专栏首页腾讯NEXT学位小程序的底层框架

小程序的底层框架

| 导语  前端的框架太多让人眼花缭乱,很多相似的地方,优秀的地方大家都会借鉴,同时又会有各自的一些特点。小程序也好,其他框架也好,理解他们的设计缘由、实现原理,还是能学到很多很多东西的。

技术选型

目前来说,页面渲染的方式主要有三种:

一、Web 渲染。

二、Native 原生渲染。

三、Web 与 Native 两者掺杂,也即我们常说的 Hybrid 渲染。

前面也说过,小程序最终的呈现形式,是 WebView + 原生组件,Hybrid 方式。我们结合之前对小程序的期望来看:

开发门槛:Web 门槛低,不过 Native 也有像 RN 这样的框架支持

体验:Native 体验比 Web 不要好太多,Hybrid 在一定程度上比 Web 接近原生体验

版本更新:Web 支持在线更新,Native 则需要打包到微信一起审核发布

管控和安全:Web 可跳转或是改变页面内容,存在一些不可控因素和安全风险

由于小程序的宿主是微信,如果用纯客户端原生技术来编写小程序 ,那小程序代码需要与微信代码一起编包,跟随微信发版本,这种方式跟开发节奏必然都是不对的。 所以方向应该是需要像 Web 技术那样,有一份随时可更新的资源包放在云端,通过下载到本地,动态执行后即可渲染出界面。

如果用纯 Web 技术来渲染小程序,在一些有复杂交互的页面上可能会面临一些性能问题。 这是因为在 Web 技术中,UI渲染跟 JavaScript 的脚本执行都在一个单线程中执行,这就容易导致一些逻辑任务抢占UI渲染的资源。

总地看来,小程序选择了 Hybrid 的渲染方式,可以用一种近似 Web 的方式来开发,并且还可以实现在线更新代码。同时,引入原生组件有以下好处:

一、扩展 Web 的能力。比如像输入框组件(input, textarea)有更好地控制键盘的能力

二、体验更好,同时也减轻 WebView 的渲染工作

三、绕过 setData、数据通信和重渲染流程,使渲染性能更好

现在,我们还剩下一个很重要的问题:管控性和安全性。于是,双线程的设计被提出来了。

双线程的小程序

也不知道是哪位大佬,能想出双线程这样的模型,反正我是佩服得666的。

双线程是什么?我们先来看个官方的图:

小程序的渲染层和逻辑层分别由 2 个线程管理:渲染层的界面使用了 WebView 进行渲染,逻辑层采用 JsCore 线程运行 JS 脚本。

为什么要这么设计呢?前面提到的管控和安全,为了解决这些问题,我们需要阻止开发者使用一些浏览器提供的,诸如跳转页面、操作 DOM、动态执行脚本的开放性接口。

我们可以使用客户端系统的 JavaScript 引擎,iOS下的 JavaScriptCore 框架,安卓下腾讯 x5 内核提供的 JsCore 环境。通过提供一个沙箱环境来运行开发者的 JavaScript 代码来解决。这个沙箱环境只提供纯 JavaScript 的解释执行环境,没有任何浏览器相关接口。

这就是小程序双线程模型的由来:

逻辑层:创建一个单独的线程去执行 JavaScript,在这个环境下执行的都是有关小程序业务逻辑的代码

渲染层:界面渲染相关的任务全都在 WebView 线程里执行,通过逻辑层代码去控制渲染哪些界面。一个小程序存在多个界面,所以渲染层存在多个 WebView 线程。

双线程通信

把开发者的 JS 逻辑代码放到单独的线程去运行,但在 Webview 线程里,开发者就没法直接操作 DOM。那要怎么去实现动态更改界面呢?

前面我们知道,逻辑层和渲染层的通信会由 Native (微信客户端)做中转,逻辑层发送网络请求也经由 Native 转发。这是不是意味着,我们可以把 DOM 的更新通过简单的数据通信来实现呢?

Virtual DOM 相信大家都已有了解,大概是这么个过程:用JS对象模拟DOM树 -> 比较两棵虚拟DOM树的差异 -> 把差异应用到真正的DOM树上。

在这里我们可以用上,如图:

在渲染层把 WXML 转化成对应的 JS 对象。

在逻辑层发生数据变更的时候,通过宿主环境提供的 setData 方法把数据从逻辑层传递到 Native,再转发到渲染层。

经过对比前后差异,把差异应用在原来的 DOM 树上,更新界面。

我们通过把 WXML 转化为数据,通过 Native 进行转发,来实现逻辑层和渲染层的交互和通信。而这样完整的一套框架,基本上都是通过小程序的基础库来完成的。

小程序的基础库

小程序的基础库是 JavaScript 编写的,它可以被注入到渲染层和逻辑层运行。主要用于:

在渲染层,提供各类组件来组建界面的元素

在逻辑层,提供各类 API 来处理各种逻辑

处理数据绑定、组件系统、事件系统、通信系统等一系列框架逻辑

由于小程序的渲染层和逻辑层是两个线程管理,两个线程各自注入了基础库。小程序的基础库不会被打包在某个小程序的代码包里边,它会被提前内置在微信客户端。这样可以降低业务小程序的代码包大小,单独修复基础库中的 Bug,无需修改到业务小程序的代码包。

Exparser 框架

Exparser 是微信小程序的组件组织框架,内置在小程序基础库中,为小程序的各种组件提供基础的支持。小程序内的所有组件,包括内置组件和自定义组件,都由 Exparser 组织管理。Exparser 特点包括:

基于 Shadow DOM 模型:模型上与 WebComponents 的 ShadowDOM 高度相似,但不依赖浏览器的原生支持,也没有其他依赖库;实现时,还针对性地增加了其他API以支持小程序组件编程。

可在纯JS环境中运行:这意味着逻辑层也具有一定的组件树组织能力。

高效轻量:性能表现好,在组件实例极多的环境下表现尤其优异,同时代码尺寸也较小。

结束语

这节里大概讲了小程序设计中比较重要的一个模型——双线程,关于双线程的出现、设计、数据通信,到基础库、Exparser 框架,都是一个个相关而又相互影响的选择。

关于小程序的底层框架设计,其实还涉及更多更多我们未能一时半会掌握完的内容,自定义组件、原生组件,还有他们做了很多的性能优化工作,都不是只言片语能讲完的。我们能做的,就是多去思考。

原文作者:腾讯工程师王贝珊

  来源:腾讯内部KM论坛

前端NEXT学位课程第九期火热招生中!

上腾讯课堂官网搜索NEXT学院还有小游戏、小程序课程等你哟~

更多课程问题,请添加NEXT学院官方小助手微信:TencentNext

腾讯NEXT学院

求职干货 | 前辈blog  | 前端课程

↓↓↓点击阅读原文,抢购限时优惠

本文分享自微信公众号 - 腾讯NEXT学院(Next_Academy)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-12-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 学员故事 | 0基础的我们,是这样做出小程序的(下)

    ? 嗨咯~ 我是N妹,这期给我们做分享的是“人人都会微信小程序”的优秀学员——“小亭同学”,快来看看她是如何从0到1做出小程序的吧~ 学员说 大家好,我是小亭...

    腾讯NEXT学位
  • 超实用的小程序官方能力,你知道吗?

    小程序官方平台和工具里,其实有很多很好用的能力,你都了解吗? 小程序管理后台 微信公众平台里,其实藏着一些好用的能力,一起来看看吧。 问题定位辅助 -...

    腾讯NEXT学位
  • 【干货】加强 web 静态资源安全方法之SRI

    我们通常会用CSP加强站点JS资源的执行限制,有效降低XSS攻击;我们通过HTTPS链接加密资源,减少站点资源劫持风险等等大量的前端安全方案。但你可能还没听说...

    腾讯NEXT学位
  • 小程序的底层框架

    原文链接:https://godbasin.github.io/2018/09/02/wxapp-technology-architecture/

    李成熙heyli
  • 【小程序】359- 小程序运行机制

    前端的框架太多让人眼花缭乱,很多相似的地方,优秀的地方大家都会借鉴,同时又会有各自的一些特点。小程序也好,其他框架也好,理解他们的设计缘由、实现原理,还是能学到...

    pingan8787
  • 腾讯冲击下一个迪士尼,竟要靠这些关键点!

    ? 5G背景下,数字文化产业迈入新时代。腾讯用IP串起数字文化产业链、以科技推动数字文化创新、通过海外市场拓展塑造文化自信等一系列动作奠定了其数字文化的龙头地...

    腾讯文旅
  • gps实时位置的展示

    很多时候,我们有这样的使用场景:外业人员在外作业,我们需要知道人员的当前的实时位置和人员信息,如何实现呢?本文将为大家简单的说明该场景下我们应该实现。

    lzugis
  • NCVerilog+SimVision+Vivado仿真环境搭建

    INCISIVE又叫做IES,以前老版本叫做IUS,是Cadence的一款可以用于数字IC设计仿真的套件工具,它就是我们所熟知的NC-Verilog,内置有图形...

    网络交换FPGA
  • Meteor1.3七日谈 — Mantra核心简介

    时见疏星
  • 啥,还有PowerMock搞不定的?

    测试中有遇到一个测试超时的场景。在系统中配置了一个timeout,默认譬如300S,程序在未达到timeout之前将持续进行。

    Criss@陈磊

扫码关注云+社区

领取腾讯云代金券