Hummingbird: 在Web上运行Flutter应用

简介: 今天,我们在 Flutter Live 上宣布了一个消息:我们正尝试在 Web 上运行 Flutter。 这篇文章描述了我们应对挑战的方式,以及该技术的当前状态。 在文末,我们附上了协同工作和嵌入等问题的答案。

image.png

原文作者:Yegor Jbanov

译者:UC 国际研发 Jothy


今天,我们在 Flutter Live 上宣布了一个消息:我们正尝试在 Web 上运行 Flutter。 这篇文章描述了我们应对挑战的方式,以及该技术的当前状态。 在文末,我们附上了协同工作和嵌入等问题的答案。

image.png

让我们快速回顾一下 Flutter 的架构。 Flutter 是一个多层系统,这样高的层更易用,用很少的代码就能表达很多,而较低的层能提供更多的控制,代价是必须处理一些复杂性。 当较高层不能满足开发者的需求时,它们可以降到较低层。 开发者可以访问 Flutter Engine 之上的所有层。

image.png

Flutter 的 Mobile 架构

在 Flutter 中,Flutter Engine 作为最低级别的库 dart:ui 暴露。它不关心 组件,物理实现,动画或布局(文本布局除外)。它所关心的是如何将图片组合到屏幕上,渲染变成像素。在 dart:ui 上直接编写应用是很困难的。这正是我们创建更高层的原因。

dart:ui 之上的一切是我们所谓的“框架”。它下面的一切都是“引擎”。该框架完全使用 Dart 语言编写。大多数引擎都是用 C++ 编写的,特定于 Android 的部分用 Java 编写,而 iOS 特定的部分用 Objective-C 编写。 dart:ui 中的一些基本类和函数是用 Dart 编写的,主要用作 Dart 和 C++ 之间的桥梁。

Flutter 还提供插件系统。插件使用指定语言编写,可以直接访问移动生态系统日积月累的 OEM 库和第三方库。你可以使用 Java 或 Kotlin 为 Android 创建插件。 iOS 插件开发是使用 Objective-C 或 Swift。

Hello, The Web

Web 平台已经发展了数十年,包含了许多技术和规范。 有一些涵盖性术语用于描述大量相关功能:HTML,CSS,SVG,JavaScript,WebGL。 为了在 Web 上运行 Flutter,我们需要:

  • 编译 Dart 代码:Flutter 是用 Dart 编写的,我们需要在 Web 上运行 Dart。
  • 选择要在 Web 上运行的 Flutter 子集:在 Web 上运行所有 Flutter 代码是不切实际的。 其中一些是特定于平台的,例如 Android 和 iOS。
  • 选择足够的 Web 功能子集:随着时间的推移,Web 平台会累积重复的功能。 例如,你可以使用 HTML + CSS,SVG,Canvas 和 WebGL 绘制图形。

从 Dart 诞生之初,它就一直在编译 JavaScript。 现在有许多重要的应用都从 Dart 编译为 JavaScript,并在生产环境中运行。 Flutter 的编译策略依赖于同样的基础设施。

当我们开始探索时,我们面临着 UI 渲染的几种选择。 我们很快意识到,要想支持的特定 Flutter 层,决定了我们将用什么 Web 技术。 我们构建了三个原型:

  • 仅仅是 Widgets(组件):这个原型实现了 Flutter 的 widget 框架,并提供了一组核心布局 widget 作为构建自定义 widget 的基础。 对于布局和定位,它依赖于 Web 的内置功能,例如 flexbox,grid 布局,浏览器滚动(通过 overflow:scroll 实现)等。
  • Widgets + 自定义布局:此原型包括 Flutter 的布局系统(由 RenderObject 提供),但将渲染对象直接映射到 HTML 元素。
  • Flutter Web Engine:这个原型保留了 dart:ui 之上的所有层,并提供了一个在浏览器中运行的 dart:ui 实现。

One of the most valuable features of Flutter is that it is portable across platforms. While you can (and sometimes are encouraged to) write custom platform-specific code, the code that does not need to be different across platforms can be shared. This allows writing applications targeting multiple platforms with a single codebase.

Flutter 最有价值的功能之一是它可以跨平台移植。 你完全可以(有时甚至被鼓励)编写自定义的特定平台代码,代码无需跨平台定制即可共享。 意味着使用单个代码库就可以编写面向多个平台的应用。

在尝试将几个示例应用移植到 Web 之后,我们意识到原型 #1 和 #2 不能提供 Flutter 开发者喜欢的可移植性级别。 因此,我们决定使用 Flutter Web Engine 设计的原型 #3,因为它有着平台之间最高的框架级代码重用:
image.png

Flutter的Web架构 (Hummingbird)

既然我们知道我们想要实现整个 dart:ui API,我们需要选择一组 Web 技术来构建。 Flutter 一次渲染一帧 UI。 在每个帧内,Flutter 会构建 widgets,执行布局,最后在屏幕上绘制它们。

构建 Widgets

Widget 构建机制不依赖于应用运行的环境。该过程只是实例化内存中的对象,跟踪其状态、以及状态变更何时计算系统低级别的最小更新,布局和绘制等。 将此部分移植到 Web 上非常简单。 在 Dart 团队用 dart2js 中实现了 super-mixin 支持之后,编译器将所有 widget 和 widget frame 都编译成了 JavaScript,几乎没有 issue 产生。

布局

布局系统有点棘手。 最大的挑战是文本布局。 除了 Center,Row, Column,Stack,Scrollable,Padding,Wrap 等之外的所有内容都由框架布局,因此无需修改即可编译到 Web。

在 Flutter 中,你可以创建 Paragraph 对象并调用其 layout() 方法来实现文本布局。 不幸的是,Web 缺少直接的文本布局 API。 我们用来测量文本布局属性的技巧是:先让浏览器布局,然后从 DOM 元素中读回相关属性。

布局文本段落时,Flutter 会测量段落的高度,宽度,最大内在宽度,最小内在宽度以及字母和表意基线。 这些属性如下所示。
image.png

Paragraph layout attributes

你可以在 Flutter 的 Paragraph 文档中找到更多详细信息。

要测量这些属性,我们首先在 HTML DOM 元素中放置一个段落,然后读取元素的维度。 这会引起浏览器布局。 例如,要获取元素的宽度和高度,我们调用 offsetWidth 及 offsetHeight。 为了测量基线,我们将段落放置在一个元素中,该元素配置为使用 flex 行进行布局。 在段落旁边,我们放置另一个名为 probe 的元素。 因为 probe 与文本的基线对齐,所以调用 getBoundingClientRect 就可以得到基线。 我们使用类似的技巧来测量最小和最大固有宽度。

  • Painting(绘制) *
    不得不提的是,我们得绘制 widgets。 对这个区域的探索最是麻烦,它仍然是我们的研究中最活跃的领域。 在框架最后,我们所有的 widget 都需要在屏幕上绘制成像素。 在浏览器中,这意味着它们必须归结为 HTML / CSS,Canvas,SVG 和 WebGL 的某种组合。

我们还没有看过 WebGL,主要是因为它级别较低,并且要求我们重新实现浏览器已经可以做的事情,例如文本布局和光栅化 2D 图形。另一个原因是我们还没有弄清楚非 Flutter 组件与 WebGL 如何结合才能实现可访问性,文本选择,和组合。

我们的早期原型为每个 RenderObject 生成了一个 HTML 元素。 结果符合预期,但最后事实却证明 API 的变化太大了。 我们必须用 Flutter 维持一个巨大的代码增量,所以我们搁置了这个想法。

我们目前正在同时探索两种方法:

  • HTML+CSS+Canvas
  • CSS Paint API

HTML+CSS+Canvas

基于这种方法,我们将框架生成的图片分类为使用 HTML + CSS 表达的图片以及使用 Canvas 2D 表达的图片。然后,我们输出结合了 HTML,CSS 和 2D 画布的 HTML DOM。
我们更喜欢 HTML + CSS,因为它受浏览器的显示列表支持。这意味着我们可以把图片的光栅化优化留给浏览器的渲染引擎去做。并且,我们还可以应用任意变换,尤其是旋转和缩放,而不必担心像素化。我们将此画布实现称为 DomCanvas。

如果我们无法使用 HTML + CSS 表达图片,我们会用 Canvas。 Canvas 2D 允许我们绘制几乎所有的 Flutter 绘图命令。如果将 Flutter 的 Canvas 与 Web 的 CanvasRenderingContext2D 进行比较,你会发现许多相似之处。在 Canvas 上绘画很高效,因为它不会创建需要随时间维护的可变树节点,如 HTML DOM 或 SVG。

2D Canvas 的一个挑战是浏览器将其表示为位图,即存储 Width x Height 像素的内存缓冲区。因此,缩放 canvas 会导致像素化。如果缩放导致图片大小变化,我们也需要调整 canvas 大小。我们发现分配 canvas 操作相当昂贵,因此方案改成调整它们的大小。最重要的是,当将多个 canvas 合成到同一页面上时,浏览器必须执行栅格合成,这也需要配置。合成栅格与显示列表的方式不同。你可以将多个显示列表绘制到同一个内存缓冲区中。我们调用 Canvas 2D 支持的 canvas 实现 BitmapCanvas。我们正在发掘使位图 canvas 更高效的方法。

为了表达 Flutter 的不透明度,变换,偏移,剪辑矩形和其他图层,我们使用纯 HTML 元素。例如,不透明度层变为 元素,其上具有 opacity CSS 属性,变换图层变为带有 transform CSS 属性的 元素,剪辑 rect 变为使用 overflow: hidden 的 。

完成所有操作后,框架将作为 HTML 元素树呈现在页面上,其中 DomCanvas 和 BitmapCanvas 作为叶节点。举个例子:
image.png

Sample HTML DOM structure of a frame

Flutter Engine 中的等效 Flutter layer tree(称为 flow layer)如下所示:
image.png

Sample Flutter Engine layer structure

它们的结构非常相似。 最大的区别是,在 Web 上,我们必须根据内容选择不同的图片实现。

HTML + CSS + Canvas 适用于所有现代浏览器。 但是,我们已经在展望未来:

CSS Paint API
CSS Paint 是一个新的 Web API,是 Houdini 的更大组成部分。 Houdini 是多个浏览器厂商合作的项目,旨在向开发者展示 CSS 引擎的某些部分。 特别的是,CSS Paint API 允许开发者在这些元素请求绘制时将自定义图形绘制成 HTML 元素。 例如,你可以将元素背景的绘制分配给自定义 CSS 绘制器。 它与 canvas 非常像,但有以下重要区别:

这个绘画不是由核心 JavaScript 独立完成的,而是由一个叫做 paint worklet 的东西完成的。 它有点像 web worker,因为它有自己的内存空间。 它会在 DOM 更改提交之后,在浏览器的绘制阶段执行绘制工作。

CSS paint 由显示列表支持,而不是位图。 这真是两全其美 - 2D canvas 般的绘画效率和无像素化。

目前 CSS paint 不支持绘制文本。

在撰写本文时,Chrome 和 Opera 是唯一在正式版本中支持 CSS Paint 的浏览器。 而其他浏览器正处于发布各自实现的不同阶段。

我们在 Flutter for Web 中对 CSS Paint API 进行了实验性支持,它已经展现出良好的结果,特别是在性能方面。 我们的实现只是将 paint 命令序列化为自定义 CSS 属性。 paint worklet 读取这些命令并执行它们。 我们使用像

这样普通的 HTML 元素来渲染文本。

我们当前的序列化机制不是特别有效 - 它是一个嵌套列表转换成的 JSON 树 - 但 Houdini 项目的一部分是添加对类型化数组的支持。 当它可用时,我们会将绘制命令编码为类型化数组而不是 JSON 字符串。 类型化数组是可转移的,这意味着它们可以通过引用从主 JavaScript 传递到 paint worklet,而不复制内存。

协同和嵌入

从 Flutter 调用 Dart 库

Flutter Web 应用可以访问当前在 Web 上运行的所有 Dart 库。

从 Flutter 调用 JavaScript 库

Flutter Web 应用完全支持 Dart 的 JS-interop 软件包:package:js和 dart:js。

在 Flutter Web 应用中使用 CSS

目前,Flutter 假定完全控制网页的正确性和性能。 例如,我们只使用遵循某些性能指南的一小部分 CSS,例如 https://csstriggers.com/。 在页面上随意使用 CSS 可能会导致 Flutter 出现不可预期的后果。

在 Flutter for Web 应用中避免使用 CSS 的另一个原因是,在设计时,Flutter 需要在渲染框架时知道所有布局属性。 CSS 充当黑盒。 例如,如果要显示可滚动的窗口 widget 列表,则必须实例化并为所有 widgets 生成 HTML 并应用必要的 CSS 属性(例如,flex-direction row 和 overflow:scroll)。 然后浏览器将所有内容都布局并将其渲染到屏幕上。 应用代码不参与布局过程。

最后,本着保持 Flutter 代码可跨平台移植的精神,我们尽量避免使用 CSS,因此我们可以在 Android 和 iOS 上本机运行相同的代码。

将 Flutter 嵌入现有的 Web 应用中

我们还没有为此添加适当的支持,但我们打算在将来探索。 我们正在考虑的方法是 和 shadow DOM。

在 Flutter 中嵌入非 Flutter 组件

我们还未支持在 Flutter Web 应用中嵌入非 Flutter 组件 - 自定义元素、React 组件、Angular 组件,但我们打算在将来探索。 有可能是使用平台视图将外部内容放入 Flutter Web 应用中。需要考虑的是外部内容可能对应用的性能和正确性产生影响。 因为非 Flutter 组件可能包含任意 CSS,如上所述,它可能会有问题。 需要更多的研究。

可移植性

我们的目标是尽可能多地将框架移植到 Web 上。 但是,这并不意味着任何 Flutter 应用将在 Web 上运行而不更改代码。 Flutter Web 应用仍然是一个 Web 应用; 它在浏览器中被沙箱化,只能执行 Web 浏览器允许的操作。 例如,如果你的 Flutter 应用使用 Web 未实现的本机插件(例如 ARCore),你将无法在 Web 上运行该应用。 同样,也无权限直接访问文件系统或低级网络。

当前状态

我们构建了足够的 Web 引擎来渲染大部分 Flutter Gallery。 我们还未移植 Cupertino widgets,但所有 Material widgets,Material Theming,以及 Shrine 和 Contact Profile 演示应用均已运行在 Web 上。

Flutter running in desktop Chrome 演讲视频
https://www.youtube.com/watch?v=5IrPi2Eo-xM

源代码在哪里?
我们计划很快开源这个项目,并很高兴与开源社区分享。 该项目最初是作为 Google 内部源代码树的一项探索而开始的。 待代码稳定后,我们打算将开发转移到 GitHub,我们有机会将其从内部基础架构中剥离出来。 与此同时,如果您在 github.com/flutter 组织下看到与 Web 相关的 pull 请求,请不要感到惊讶!

结论

希望这篇文章能让你了解我们正在解决的问题,以帮助 Flutter 在 Web 上更好运行。 欢迎表达您的观点和意见。

请继续关注 Google I/O 2019!

英文原文:

https://medium.com/flutter-io/hummingbird-building-flutter-for-the-web-e687c2a023a8

目录
相关文章
|
1天前
|
缓存 Java 测试技术
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
14 3
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
|
11天前
|
前端开发 安全 开发工具
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
141 90
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
14天前
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
37 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
16天前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
121 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
1月前
|
Web App开发 编解码 vr&ar
使用Web浏览器访问UE应用的最佳实践
在3D/XR应用开发中,尤其是基于UE(虚幻引擎)开发的高精度场景,传统终端因硬件局限难以流畅运行高帧率、复杂效果的三维应用。实时云渲染技术,将渲染任务转移至云端服务器,降低终端硬件要求,确保用户获得流畅体验。具备弹性扩展、优化传输协议、跨平台支持和安全性等优势,适用于多种终端和场景,特别集成像素流送技术,帮助UE开发者实现低代码上云操作,简化部署流程,保留UE引擎的强大开发能力,确保画面精美且终端轻量化。
使用Web浏览器访问UE应用的最佳实践
|
2月前
|
弹性计算 Java 关系型数据库
Web应用上云经典架构实践教学
Web应用上云经典架构实践教学
Web应用上云经典架构实践教学
|
2月前
|
弹性计算 负载均衡 安全
云端问道-Web应用上云经典架构方案教学
本文介绍了企业业务上云的经典架构设计,涵盖用户业务现状及挑战、阿里云业务托管架构设计、方案选型配置及业务初期低门槛使用等内容。通过详细分析现有架构的问题,提出了高可用、安全、可扩展的解决方案,并提供了按量付费的低成本选项,帮助企业在业务初期顺利上云。
|
2月前
|
弹性计算 Java 数据库
Web应用上云经典架构实战
本课程详细介绍了Web应用上云的经典架构实战,涵盖前期准备、配置ALB、创建服务器组和监听、验证ECS公网能力、环境配置(JDK、Maven、Node、Git)、下载并运行若依框架、操作第二台ECS以及验证高可用性。通过具体步骤和命令,帮助学员快速掌握云上部署的全流程。
|
2月前
|
Kubernetes 安全 Devops
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
97 10
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
|
3月前
|
前端开发 JavaScript UED
在数字化时代,Web 应用性能优化尤为重要。本文探讨了CSS与HTML在提升Web性能中的关键作用及未来趋势
在数字化时代,Web 应用性能优化尤为重要。本文探讨了CSS与HTML在提升Web性能中的关键作用及未来趋势,包括样式表优化、DOM操作减少、图像优化等技术,并分析了电商网站的具体案例,强调了技术演进对Web性能的深远影响。
59 5

热门文章

最新文章

  • 1
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 2
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 3
    【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
  • 4
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
  • 5
    【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
  • 6
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
  • 7
    零基础构建即时通讯开源项目OpenIM移动端-Flutter篇
  • 8
    flutter3-dart3-dymall原创仿抖音(直播+短视频+聊天)商城app系统模板
  • 9
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 10
    【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
  • 1
    打造高效的Web Scraper:Python与Selenium的完美结合
    13
  • 2
    Burp Suite Professional 2025.2 (macOS, Linux, Windows) - Web 应用安全、测试和扫描
    26
  • 3
    AppSpider Pro 7.5.015 for Windows - Web 应用程序安全测试
    20
  • 4
    【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
    54
  • 5
    部署使用 CHAT-NEXT-WEB 基于 Deepseek
    342
  • 6
    【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
    26
  • 7
    java spring 项目若依框架启动失败,启动不了服务提示端口8080占用escription: Web server failed to start. Port 8080 was already in use. Action: Identify and stop the process that’s listening on port 8080 or configure this application to listen on another port-优雅草卓伊凡解决方案
    40
  • 8
    零基础构建开源项目OpenIM桌面应用和pc web- Electron篇
    28
  • 9
    【01】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-硬件设备实时监控系统运营版发布-本产品基于企业级开源项目Zabbix深度二开-分步骤实现预计10篇合集-自营版
    22
  • 10
    FastAPI与Selenium:打造高效的Web数据抓取服务 —— 采集Pixabay中的图片及相关信息
    55