前言
介绍了微信小程序开发的技术原理,包括技术挑战和解决方案。通过对Skia的裁剪,使用Web+W3C BOM+在微信小程序中运行渲染流程。字体内置和智能分包的方法解决了微信包大小限制,实现了在微信小程序中的完整运行。今天的前端晨读课文章由@,公众号:开发者授权。
正文从这里开始~~
它是一个跨平台的开发框架,可以用于小程序、H5、原生应用开发。
背景
小程序是一种新的商业模式,特别是微信小程序,结合了Web的动态特点,有丰富的设备能力支持。
在微信上,小程序不仅拥有稳定的分发渠道,还拥有完整的生命周期、数据、AI能力支撑。
微信小程序的开发一般有两种方式:
本文将介绍小程序开发背后的技术原理。
技术挑战
虽然官方已经提供了Web实现,但是Web本身就是基于运行的,微信小程序都可以运行,原则上运行Web是没有问题的。
但仍然存在以下技术挑战:
我们在1.x版本中对上述问题进行了探索,针对1.x版本的解决方案如下:
1.x 方案已经运行良好两年了,也收到了很多开发者的反馈,开发者经常抱怨插件被砍掉后与生态不兼容,同时库也无法使用,UI 需要从头写起。
在2.0版本中,我们重新思考了小程序的最佳运行方式,最终解决了以上所有问题。
技术解决方案
通过对Skia的切分,生成微信小程序的分包需求,使用Web+W3C BOM+跑通渲染流程。
技术选择
在介绍技术选型之前,我们需要介绍一下Web的两种类型。
1. HTML
其原理是通过dart:js库调用对象,并在此基础上将相应的+CSS添加各种转换到DOM树中。
该方案的优点是兼容性好,几乎不需要额外的依赖;缺点是性能较差,渲染内容的一致性难以对齐。
2、
原理就是通过 + Skia 来渲染界面,跟 一模一样。
这种方案的优点是渲染性能很好,一致性几乎一致;缺点是占用内存较大,并且需要从远程端加载字体。
3.2.0 选择
我们使用的是1.x版本的HTML,DOM模拟层存在很多问题,最让人诟病的就是数据更新后界面刷新速度慢,当然问题还不在于此,而是1.x本身在Tree的序列化和反序列化上天然的缺陷,虽然已经通过Diff等手段进行了优化。
在2.x版本中我们直接抛弃了HTML的思想,而使用了。
使用有几个主要的先决条件:
Skia 裁剪
Skia 是一个开源的 2D 渲染库,凭借良好的跨设备能力和优异的性能,被应用于包括 / / / 等在内的众多产品中。
Skia屏蔽了不同设备和平台的具体实现,以标准、开放的方式统一对外开放。
Skia 其中之一是,那就是。
但Web端默认使用的大小为6M,即使压缩之后依然不符合小程序分包的要求。

我们可以通过指定编译选项来缩减大小。以下是使用的配置:
.///.sh
从配置中我们可以看到,我们去掉了 、 、 以及内置字体等不必要的功能,我们可以使用微信小程序API来补充这些功能。
压缩后的wasm文件刚好满足2M分包要求。
加载
Skia构建完成后会得到.wasm、.js两个产物。
.js 公开了 wasm 中的各种 C++ 方法调用,还提供了加载 wasm 的脚手架。
但是.js默认的实现是基于Web的,我们需要将其替换为微信小程序对应的实现。
这里有一个使用Skia绘制红色矩形的微信小程序项目,有兴趣的同学可以下载进行本地研究。
注意:请从 2.0 文档博客下载示例项目
Web 在微信中运行
让Web在微信里跑起来,最大的难点在于如何完成Web所需要的Web API。
具体来说,这些类,我已经在开源了,有兴趣的可以一个文件一个文件去看。
以下是文档的摘录:
export class FlutterMiniProgramMockWindow {
// screens
get devicePixelRatio() {
return wxSystemInfo.pixelRatio;
}
get innerWidth() {
return wxSystemInfo.windowWidth;
}
get innerHeight() {
return wxSystemInfo.windowHeight;
}
// webs
navigator = {
appVersion: "",
platform: "",
userAgent: "",
vendor: "",
language: "zh",
};
// 还有更多。。。
}
当Web应用程序运行时,它将使用 . / . 来获取当前窗口的宽度和高度,以便它可以创建适当大小的画布以供下一步渲染。
在微信小程序中我们需要使用wx.()来获取对应的宽高并返回给。
关于BOM文件我就不细说了,都是胶水代码。
main.dart.js 还需要做一些修改才能在小程序上运行,主要修改是适配 main.dart.js 中的 main 函数,以便暴露给 Page 调用。
正在加载字体
最大的问题是字体加载,目前无法复用系统自带的字体。
我们的做法是,将字体精简到只包含常用的9000+汉字,在内置的小程序包中优先加载。
这样做的一个好处是小程序不需要强制下载字体,节省带宽和加载时间。
后续我们还将研究如何使用2D在本地加载字体。
分包
关于分包,其实是最容易做的,因为Web本身就有负载编译的能力。
开发者可以很方便的将 main.dart.js 拆分成若干个 JS 文件,我们需要做的就是在 Web 编译完成后,将这些 JS 文件智能的分配到不同的子包中。
资源分包也是一样,通过压缩也可以减少资源包体积。
总结
全部设置完成之后,已经可以在微信小程序里运行了,我们来总结一下都做了哪些事情。
我们对 Skia 进行了定制,使其能够在小程序上良好运行,通过 BOM 兼容,Web 可以在微信小程序中找到对应的实现,通过内置字体和智能打包,很好地解决了微信包大小限制的问题。
目前该解决方案已全面实施并投入使用。
有兴趣的人可以在文档站点上了解更多用法。
关于此