加载失败,
在微信小程序里运行完整的 Flutter,怎么做到的?
在微信小程序里运行完整的 Flutter,怎么做到的?
1月26日修改
背景
小程序是一种全新的业务形态,特别是微信小程序,既结合了 Web 动态化特性,又拥有 Native 丰富的设备能力支持。
在微信这个宿主上,小程序不仅有稳定的分发渠道,更拥有完善的生命周期、数据、AI 能力支持。
在该微信上开发小程序,一般使用以下两种方法:
•
JavaScript + WXML + WCSS
•
Taro + React + JavaScript
本文要介绍的是使用 Flutter Framework 开发小程序的方法,以及该方法背后的技术原理。
技术挑战
尽管 Flutter 官方已经提供 Flutter Web 实现,Flutter Web 本身就是基于 dart2js 运行的,微信小程序可以运行 JavaScript,在原理上跑起 Flutter Web 是没有问题的。
但仍然存在以下技术挑战:
•
微信小程序没有 W3C 标准的 JavaScript 对象,Flutter Web 不能直接运行。
•
微信小程序也没有 DOM 实现,Flutter Web HTML Renderer 不能直接渲染。
•
微信小程序对包大小的限制十分严格,主包不能超过 2M,而 Flutter Web 所编译的 main.dart.js 初始体积就有 1.3 M,必须有合理的分包机制才能上传。
我们在 MPFlutter 1.x 版本中,针对上述问题已有一定的探索,1.x 版本的解决方法如下:
•
使用微信开源的 kbone 库,模拟 W3C 实现,并通过模拟的 DOM 对象渲染出符合 WXML 要求的视图树。
•
通过 Shadow Element Tree 的方式,使用 JSON 在 Dart 与 JavaScript 上下文同步视图树。
•
Fork Flutter Framework,并对其进行外科手术式的裁剪,使 main.dart.js 初始体积降低到 600K。
MPFlutter 1.x 方案已经良好的运行了两年,也收到了开发者非常多的反馈,开发者常诟病于裁剪后的 Flutter Framework 不兼容 Flutter 生态上的插件,同时 material 库也无法使用,需要从头开始编写 UI。
在 MPFlutter 2.0 版本,我们重新思考在小程序上运行 Flutter 的最佳方式,并在最终使用 CanvasKit Renderer 解决以上全部问题。
技术方案
Summary
通过裁剪 Skia 生成符合微信小程序分包要求的 CanvasKit,使用 Flutter Web + W3C BOM + WebGL Canvas 跑通渲染流程。
技术选型
在介绍技术选型前,需要先介绍 Flutter Web 的两种 Renderer。
HTML Renderer
原理是 Flutter Framework 通过 dart:js 库调用 Document 对象,并基于此将各种 RenderObject 转换为对应的 Element + CSS 添加到 DOM 树中。
该方案优点在于兼容性很好,几乎没有额外的依赖;缺点是性能不佳,并且渲染内容一致性难以与 Native Flutter 对齐。
CanvasKit Renderer