关于这个话题其实聊过很多次,在 2023 年初的时候,谷歌就提出了调整 Flutter Web 路线的方向,而今年年初的时候,Flutter 官方也正式官宣弃用 HTML renderer 的计划,而近日,在 #145954 的 Final update 里提到,大概在今年 12 月该功能将正式合并到 beta 版本,届时 --web-renderer
选项将不再可用, Flutter Web 将只支持默认的 CanvasKit 和全新的 SkWasm。
关于这个点,这里需要再再再强调一下,弃用 HTML renderer 并不是说 Flutter 觉得传统 Web 路线有什么不好,只是 CanvasKit 和 Wasm 更贴合 Flutter 框架的技术路线,因为在 2023 年确定 Flutter Web 技术路线时官方就明确过:
“Flutter Web 的定位不是设计为通用 Web 的框架,Flutter Web 是一个围绕 CanvasKit 和 WebAssembly 等新兴 Web 技术进行架构设计的框架。”
由于 Flutter 一直以来都是以 Canvas 为基准通过 Engine 来实现跨平台,并且保证不同平台上的控件得到一致的渲染效果,而 Html renderer 的渲染方式明显违背了“初衷”,在兼容适配的过程中产生了许多额多的开发成本和兼容问题。
本次合并调整之后,Flutter Web 只提供了两个渲染器支持,分别是 default 和 WebAssembly,对应 CanvasKit 和 SkWasm。
对于默认构建,Flutter 在运行时选择
canvaskit
渲染器;对于 WebAssembly 构建,Flutter 在运行时选择skwasm
渲染器,如果浏览器不支持skwasm
,则回退到canvaskit
。
不管是 CanvasKit 还是 SkWasm ,都是基于 canvas 模式绘制,渲染器会将 UI 基元(存储为 Scene
对象)转换为像素,只是 SkWasm 需要 WasmGC 支持,所以目前并非所有浏览器都支持 WasmGC 。
不过 WebKit 也合并了 Wasm GC 默认开启的支持,也就是未来 Webkit 默认能够支持 Wasm GC 和 Wasm Native 的场景会越来越多:
从目前来看,CanvasKit 会附带一个额外的 1.5MB wasm 文件,SkWasm 附带一个 1.1MB 的额外 wasm 文件,并且后续将继续推进 size 的减小。
而从效果上看,与 CanvasKit 相比,SkWasm 的启动时间和帧性能明显更好,在多线程模式对比更明显,特别是服务器开启了 SharedArrayBuffer 的情况:
当使用
skwasm
时,Dart 代码被直接编译成 WebAssembly,此时如果托管服务器满足 SharedArrayBuffer ,Flutter 将使用专用的 Web Worker 将部分渲染工作负载卸载到单独的线程,从而利用多个 CPU 内核。
总的来说,SkWasm 主要改善了两件事:性能和启动时间:
- 启动时间:注意这里并不是说**下载时间 **,对比 JS ,Wasm 很难有压缩优势,这里的启动时间更多是浏览器解析、编译和启动代码所花费的时间,特别缓存启动受益最大
- 性能:SkWasm 模式下 Dart 可以运行得更快,共享内存多线程(通过线性内存访问、ffi 和一些 C++ 支持,让 SkWasm 能够通过将工作卸载给 Web Worker 来加速 Flutter 中的渲染)
具体效果其实可以简单通过以下例子进行对比:
- https://vsm-wonderous-js-canvaskit.web.app/#/welcome (linear wasm)
- https://vsm-wonderous-wasm-skwasm.web.app/#/welcome (optimized wasmgc)
当然,从目前国内的情况下,确实很少人会在为了开发 Web 程序而直接选择 Flutter,更多还是在使用 Flutter 之后,因为它支持 Web,所以就顺带把业务能力支持到 Web 场景。
特别是在 3.24 开始 Flutter Web 增加了对 Multi-view 嵌入支持,可以同时将内容渲染到多个 HTML 元素中,核心是 Flutter Web 不再只是 Full-screen 模式,这个功能可以称为 “embedded mode” 或者 “multi-view”,支持灵活地将 Flutter 视图集成到现有 Web 应用里。
所以,从目前效果来看,Flutter Web 官方定位本身就不适用于具有文本丰富或者基于 flow 的内容的静态网站,Flutter Web 更多的支持场景是:
- Single Page Apps
- 现有的 Flutter 应用 to web
典型的例子可以看 wonderous 的 https://wonderous.app/web/#/welcome ,它的 Web Demo 可以算是 Flutter Web 的较好展示之一:
另外一个话题就是 SEO,在今年早些时候,Flutter 添加了对应的 roadmap 更新,在其中就有一段测试 link,虽然后续被移除了:
通过 https://alien-hawaii-2024.web.app/ 可以看到,Web 下页面其实可以做到复制和检索,但是不能被翻译插件识别,另外在 SEO 搜索上也可以匹配到:
源码在 : https://github.com/yjbanov/alien-hawaii
其实 SEO 一直算是 Flutter Web 的一个问题,官方也在探索如何去解决,只是暂时还没有一个特别合适的公式方案,不过确实有不少第三方支持存在:
-
https://pub.dev/packages/seo
-
https://pub.dev/packages/meta_seo
-
https://pub.dev/packages/seo_renderer
例如 seo_renderer ,其实根据 Google 的说法,只要内容相似(完整来源),就不被视为 SEO 伪装,理论上,seo_renderer 这种使用 regex 和 navigator userAgent 自动检测爬虫,并对应添加 HtmlElement 添加到 DOM 的行为,也算是一种规避的方式:
不过还是回归到 Flutter 路线上,它本身就不是为了传统 Web 场景存在,前面我们也说过 Flutter Web 的一些适用场景,另外在 2022 和 2023 年的 Google I/O 上,Flutter 也曾通过 Flutter Game 发布过两个 Flutter Web 小游戏,这也算是 Flutter Web 的场景之一:
甚至还有人通过 MPFlutter 在微信小游戏上发布了一个款五子棋游戏的:https://mpflutter.feishu.cn/wiki/BGMNwe6dAiOr6Rkn2oycF9y5nab
最后,在 Flutter CTO 2024 的报告显示,目前 Flutter 用户除了 Android 和 iOS 外,排第三的是 Web ,所以整体上 Flutter 对于 Web 还是比较上心的,而 HTML 的正式移除,明确了 Web 后续的路:坚定不移的 Wasm 。
参考资料
-
https://github.com/flutter/flutter/issues/145954
-
https://github.com/flutter/flutter/issues/153974
-
https://github.com/flutter/flutter/issues/153678
-
https://github.com/flutter/flutter/issues/93404