likes
comments
collection
share

小程序工作原理速通

作者站长头像
站长
· 阅读数 5

最近在了解小程序的工作原理,这是一块非常有趣的领域,我根据现有资料和自己的理解整理出这篇文章。三千字无法做到面面俱到,但能对整体架构有所了解。

小程序宿主环境

小程序和前端APP的开发体验是非常类似,主要区别在于宿主环境的不同。小程序运行在微信、抖音这种超级APP中,而前端APP运行在浏览器中,这是最大的不同。

那应该如何理解这种不同呢?

回顾浏览器开发,纵使我们可以开发出非常精美且独一无二的页面,却始终无法突破浏览器自身能力的限制。比如我们没有办法在浏览器里执行nodejs运行时提供的fs库,导致我们没有办法直接读取用户本地的文件,这也是为什么很多js库无法在浏览器环境中执行的原因。所以我们需要了解小程序的宿主环境,知道有哪些能力以及能力的边界。

小程序架构

小程序工作原理速通

上面是小程序的架构图,分为逻辑层和视图层,这套架构需要客户端同学进行实现,在安卓和iOS的具体实现也不同,但对开发者来说是透明的

视图层

webview

视图层其实就是常规的浏览器环境,可以渲染html代码,也可以执行js代码。在客户端中,通过webview技术可以在native应用里加载网页。

webview和iframe有点类似,对于前端来说,第一次听到这个概念可能会觉得不就是iframe么?其实有点类似,对于我们而言,我们可以在前端APP里通过嵌入iframe加载别的前端APP。而webview就是提供给客户端同学的iframe,在native app里加载前端app的技术。

双线程架构

有没有发现一个问题,既然webview可以执行js,那为什么还要做一个js逻辑层呢?

我们常规的前端APP开发,页面渲染和JS逻辑都是放在一起的,是没有问题的。微信官方的意思是移动端设备性能比较弱,单线程架构容易造成页面卡顿。对浏览器工作原理有了解的同学都会清楚,JS执行会阻塞页面渲染。

但我觉得还有一个更重要的原因。

在国内所有互联网服务,都需要受到监管。一款没有办法自我监管的应用随时面临被下架的风险。通过双线程架构,确保没有办法通过JS直接修改webview视图,只能通过setData进行更新。而通过setData传递的数据,匹配到敏感词后有可能被平台记录。

视图层框架

开发者通过定义类似vue的语法以及css,来定义页面如何被渲染。小程序会将这个类似vue的语法最终编译成接收data的JS函数,有点类似一些AOT框架。最终在webview内,通过调用编译后的函数将dom节点插入到页面。

逻辑层

逻辑层可以理解为一个提供了官方基础库的运行环境,在iOS内通过jscore引擎执行js脚本。

通信实现

根据官方介绍,逻辑层与视图层的通信需要通过native层转发,这里涉及到JSBridge技术。

JSBridge是一种在native和js执行环境之间通信的技术。因为跨语言跨进程(注定了是异步的),所有被传输的数据都需要被序列化和反序列化。

有关JSBridge的文章很多,大致原理如下:

webview -> native:使用伪协议,将数据按照特定格式拼接成URL发起请求。例如请求microapp://message?a=1,在native对这类URL进行拦截,解析出{a:1}即可。

native -> webview:jscore引擎提供evaluateScript方法,可以在native中拼接js代码片段后,在js执行上下文中执行。有点类似于前端领域的jsonp技术。

小程序工作原理速通

当然还可以在native层启动一个websocket服务进行消息通信。

小程序能力与基础库

为了吸引开发者参与小程序开发,以及丰富小程序的功能,各家的开放平台往往会提供非常多的基础能力。有些能力是客户端同学帮忙实现的,比如获取GPS定位,获取用户本地文件,访问用户的麦克风等。还有一些能力是服务端同学进行实现的,比如访问用户账户信息,调用支付等等。

而前端同学会对客户端同学和服务端同学提供的能力统一封装成jssdk,暴露给开发者使用。这个jssdk会抹平底层的实现差异,对开发者而言实现一次开发多端运行的效果。比如在pc端开发者工具中,也会模拟出移动设备的效果。

为了提升开发者体验,小程序技术团队还会封装一些组件给用户调用,比如scroll,rich-text之类的。你可以理解为就是你平时开发前端APP沉淀下来的组件,只不过在这里你不太能修改。

小程序的基础库会在开发者编写的逻辑执行之前先执行。

小程序安全

相比起前端APP的开发,小程序往往有非常严格的限制,会让开发者体验不舒服。但这也是确保这套商业模式能够延续的代价。

因为严格,所以更安全。用户会觉得自己隐私有保障,并且对超级APP来说风险也更可控。

小程序分发与加载

我们如果是开发一个前端APP,只需要使用打包工具把产物部署到CDN即可,之后就能通过URL在浏览器访问。

但小程序的打包过程对我们来说是黑盒,他会将你的代码打包好后上传到平台的CDN中。并且记载当前产物的元数据。

当用户在超级APP中通过搜索或者其他方式启动你的小程序,超级APP首先会拉取元数据。元数据包含版本号,依赖的基础库,小程序产物的CDN地址等信息。超级APP会判断你本地缓存是否合法后决定是否拉取最新的小程序产物。

为了加速小程序的启动过程,小程序技术团队煞费苦心。为了更快的启动首屏,小程序技术团队会进行诸多优化:

  • 通过算法预判用户会启动哪些小程序,提前下载。不过预判算法也需要进行优化,否则浪费用户本地存储空间,浪费公司CDN流量。
  • 限制分包体积,并进行压缩,确保首屏所需的依赖尽量小。根据常规的压缩算法,如果主包限制在2MB以内,压缩率为30%,则用户最多需要下载600KB资源就能加载出首屏。
  • 流式加载,无需拉取完整包即可得到首屏。

前端架构与自我提升

最近阴差阳错的开始了解起小程序架构。

初步了解完,我认为这是学习前端架构与自我提升非常好的切入点。设计出这种架构的工程师,通过自己的专业实力影响了整个行业。

  • 混合应用的良好实践,性能与开发成本的完美权衡
  • 在提供自由的开发体验时,兼顾安全与合规
  • 技术点宽泛,涉及到几乎前端领域所有技术

如果想继续深入了解这小程序前端架构,有非常多内容是可以钻研:

  • 代码编译原理与前端框架
    • 小程序视图层有自己的AOT前端框架,页面渲染性能高。在AOT框架,可以研究一下svelte。
    • 研究类似Taro这类跨端框架的设计思路与实现原理。
  • 前端基建与工具链
    • 小程序技术团队将自身能力封装成jssdk给逻辑层调用,以及封装了一些组件(类web Components技术)给视图层调用。
    • 小程序开发者工具,涉及的知识也非常宽泛。IDE的开发与优化,代码提示,调试器与调试原理等等。
    • 小程序构建技术,其实给我的感觉有点类似next.js这种,你不需要手动配置webpack,他是开箱即用的。那小程序其实也有自己的构建配置,对开发者而言是透明的。
  • 性能优化
    • 作为C端产品,亿级日活,任何一点微小的优化,都将产生巨大的价值。
    • 基于架构整体视角思考存在非常多优化空间。比如开发者体验优化,优化编译构建速度。用户体验的优化,减少包构建体积,优化组件性能等。
转载自:https://juejin.cn/post/7323056643386032182
评论
请登录