我从小程序学到了什么(一)
前言
最近在看小程序相关,从技术角度来看小程序在Hybrid的优化过程有很多值得我们学习的地方,所以我想在学习的同时也能有所输出,在这个系列我不会讲怎么去申请一个小程序,怎么去开发一个程序,而是讲从小程序我们能学到什么,尽管它现在还存在很多问题,但大范围的使用会推动小程序将微信技术生态做到极致,使用到Hybrid技术的公司非常多,希望我的系列文章能对大家有所帮助。
在微信下的页面技术演变
从技术的角度来看,其实微信的页面技术是小程序的前身,如下图。
在微信里面的网页,可以通过JS-SDK来调用微信native,让开发者使用到微信的原生能力,当JS-SDK公布后受到很多开发者的欢迎,但随着广泛的使用,开发者们又遇到了很多问题。
- 白屏
用户在手机访问微信的一个h5,由于移动设备的限制和网络速度,都会有一个明显的白屏。
微信团队用了很多精力来解决这个问题,就出现了后面的JS-SDK增强版,这里面有个比较重要的功能就是:离线存储。 离线存储简单的理解就是从本地加载web资源而不再从服务端拉取,从而避免网络速度的瓶颈。
离线存储降低了网络延时大大提高了h5的用户体验,但在一些复杂的页面依然会有白屏的问题,这里主要是js和css的复杂性会占用大量的UI线程而影响WebView的渲染。
其实目前大部分公司使用的是类似JS-SDK方案:灵活的网页开发+ 丰富的原生功能 + 离线存储。
- 没有native流畅的操作
有些团队使用SPA框架来模拟native的原生页面切换,但SPA也有自己的弊端,随着业务的复杂,很有可能让WebView的负担越来越大,而且做到这一点需要开发者有足够的时间和精力。
- 安全
对攻击防不胜防,浏览器下的js是非常灵活,可以对Dom和Bom随意操作,可以随意跳转,可以动态执行等等。
所以,微信能否解决之上的问题呢,微信的页面是否能做到以下:
- 快速的加载
- 强大的能力
- 流畅的体验
- 安全
- 开发成本低
这就是小程序。
小程序的技术选型
小程序如果想解决之前纯网页技术的一些问题,必须要做一些新的尝试
- 可否使用Native技术
要达到快速的加载和流畅的体验,是不是直接基于微信的客户端开发就Ok了呢?但这有个问题,这么做意味着小程序的代码需要和微信客户端代码一起发布,这种节奏肯定无法满足的。
- 可否使用ReactNative
RN虽然用javascript解释执行,但渲染方面还是Native渲染,其实RN能解决加载和渲染的问题,但它也仍然有些不足,这里引用微信官方给的原因
- 对css的支持问题无法满足web开发者日渐增长的需求,如果改造也要花很大精力和风险。
- 到目前还是有些性能的坑以及bug,对于复杂一些的页面比较难以胜任。
- 不可预期的因素,比如之前闹的沸沸扬扬的许可证。
纯h5有很多弊端,纯Native又不可能满足发版的需求,RN又不是很成熟,所以最终微信在面对自己的技术生态下对小程序的选型还是Hybrid,界面由成熟的Web技术渲染,逻辑由成熟的Js解析和执行,再加上微信Native提供的原生能力。但要实现之上所说的需求,小程序还是需要基于Hybrid做突破。
双线程模型
双线程:小程序的逻辑层与渲染层是分开两个线程, 逻辑层的js用到Native自身的JSCore来解析和执行,而界面还是通过WebView来渲染。通信过程如下图(图片来自微信官方文档,侵删):
一般的Hybrid技术,WebView既做js解析和执行,还要渲染html和css,当页面比较复杂时,很有可能出现界面的渲染等待JS的执行从而造成白屏现象,我们用双线程可以降低Webview的负担,在复杂的页面交互里可以并行js执行与界面渲染。 另外Native的Jscore仅仅只是实现了ECMAScript标准,它不像浏览器还需要实现DOM与BOM,所以在小程序里通过js无法操作dom,无法使用BOM,这也在一定程度上解决了安全和管控的问题。
小程序的javascript
如上所说,小程序的javascript是由JSCore来实现ECMAScript,除了这个之外小程序还提供了一个框架和一系列api,这些底层的升级是与微信客户端的升级同步的。
(图片来自微信官方文档,侵删):
总结
微信页面以及小程序的技术体系其实与大多数公司一致,但微信做为一个平台会将安全与性能做到极致,虽然大部分公司不需要做到微信这种平台体量,但它的技术演进还是能给我们很多借鉴,比如我们可以也用多个WebView吗?我们也可以用双线程吗?我们也可以做WebView预加载吗?我们也能做微信开发者工具吗?接下来我们也会渐渐结合我们自身的业务场景继续和大家分享。
由于第一篇为了给后面的知识内容做些准备,所以用到了微信官网的一些内容和图片,特此说明,侵删。
参考文献:小程序开发指南
如想阅读更多文章,可以关注我们的微信公众号:大前端工程师