小程序工作原理速通

最近在了解小程序的工作原理,我认为是非常有趣的领域,所以根据现有资料和自己的理解整理出此篇文章。这篇文章可能无法做到面面俱到,只求对整体架构有所了解。

小程序宿主环境

小程序和前端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限制,直接使用JS进行DOM更新,导致内容管控出现风险。

而通过setData,所有的数据都是有办法被监管的。

视图层框架

开发者通过定义类似vue的语法以及css,来定义页面如何被渲染。小程序会将这个类似vue的语法最终编译成一串JS代码,有点类似一些AOT框架。最终在webview中,根据data计算成html将页面渲染出来。

逻辑层

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

通信实现

逻辑层与视图层的通信根据官方介绍是通过native层进行转发的,这里会用到JSBridge技术。

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

相关的文章也比较多,大致原理就是:

webview发送信息给native,可以通过伪协议,按照规定拼接好URL发起请求即可。比如请求microapp://message?a=1。native对这串请求进行拦截,解析出{a:1}即可。

native发送信息给webview,可以通过类似jsonp的方式。回顾一下jsonp,可以通过执行一段js脚本,在浏览器的js上下文内定义数据。native也具备类似的能力,可以拼接好一串JavaScript代码,然后直接在在webview内执行。比如在jscore中使用evaluateScript这个方法,执行自己拼接好的代码。

当然还可以通过websocket进行传输,在native层启动一个服务端口。

小程序能力与基础库

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

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

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

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

小程序安全

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

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

小程序分发与加载

我们如果要访问一个前端APP,直接在浏览器内输入URL即可,然后浏览器会帮我们做后续的事情。

在超级APP里,我们拉起一个小程序,背后其实也有一些复杂的逻辑。当我们点击一个小程序的icon,超级APP比如抖音,会去服务器拉取这个小程序的元数据,比如版本号,依赖的基础库版本号,分包的CDN地址等等。经过比对后判断直接通过本地缓存或去CDN拉取最新版本的小程序进行加载。

为了加速小程序的启动过程,小程序技术团队也煞费苦心了。最基础的方法是对分包进行压缩,并且限制分包的体积,比如分包最大为2MB,如果压缩率为30%,那用户只需要花费600KB流量就能完成首屏加载。以及预测用户的开启行为,提前预热等。

但最近又听说有流式加载这个技术,不需要将整个分包都下载完成,可以边下载边加载,感觉和unbundle的打包理念有点类似,按需加载(但是对网络性能要求可能更高)。

前端架构与自我提升

最近阴差阳错的开始了解起小程序架构,我感叹,第一个设计出这种架构的是天才级专家工程师。令我感叹的地方,具体如下:

  • 混合应用的良好实践,性能与开发成本的完美权衡
  • 开发的架构,但兼顾安全与合规
  • 技术点宽泛还深入,涉及到前端的方方面面

如果想深入了解这小程序前端架构,其实有非常多内容是可以自我提升的:

  • 代码编译原理,将模板代码通过AOT技术编译成JS脚本
  • 前端工具链,IDE开发技术
  • 性能优化实战,亿级用户高频访问,每一处优化都能带来巨大的收益,彰显前端价值
相关推荐
Myli_ing42 分钟前
HTML的自动定义倒计时,这个配色存一下
前端·javascript·html
dr李四维1 小时前
iOS构建版本以及Hbuilder打iOS的ipa包全流程
前端·笔记·ios·产品运营·产品经理·xcode
雯0609~1 小时前
网页F12:缓存的使用(设值、取值、删除)
前端·缓存
℘团子এ1 小时前
vue3中如何上传文件到腾讯云的桶(cosbrowser)
前端·javascript·腾讯云
学习前端的小z1 小时前
【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制
开发语言·前端·javascript
彭世瑜2 小时前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript
FØund4042 小时前
antd form.setFieldsValue问题总结
前端·react.js·typescript·html
Backstroke fish2 小时前
Token刷新机制
前端·javascript·vue.js·typescript·vue
小五Five2 小时前
TypeScript项目中Axios的封装
开发语言·前端·javascript
小曲程序2 小时前
vue3 封装request请求
java·前端·typescript·vue