【评论有奖】你想知道的小程序底层知识,你确定不想了解下?

635 阅读9分钟

本篇文章内容较长,建议”点赞收藏“ ≈ “学会了”,在查看

前言

本篇文章比较适合有点前端基础又想深入了解小程序的人看,前面的第一章主要介绍小程序的半底层,第二章主要介绍生命周期及生命周期及其作用。本文主要以了解为主,不深入探讨了解或单个知识点详细讲解;如果对某个知识特别想看,支持可以留言,并后期会出对应的文章。

1.了解小程序底层

1.1发展

小程序并非凭空出现的,它最开始就有微信的JS-SDK包,专门提供我们调用微信原生功能的能力,例如:拍照、录音、地图等微信原生功能,使我们开发H5网页更加方便快捷和调用高效。

1.2框架类型

技术类型有很多,例如:纯原生APP开发、纯web网页开发,但是微信经过权衡利弊,最终选择介于客户端原生技术与 Web 技术之间又互相结合各自特点的Hybrid 技术,Hybrid技术其实和刚开始的微信JS-SDK类似,前端界面使用web浏览器渲染,而调用微信功能则使用JS-SDK类似的嫁接桥来调用微信原生组件能力,从而达到更佳的体验效果。同时开发者开发完打包推送到腾讯云服务器,当用户点开使用时会下载整个小程序包到本地,实现了随时可更新小程序包和每个页面打开如同原生页面一样流畅。

1.3为何快

小程序为了达到渲染快、加载快,除了把小程序包下载到本地,还有一个比较重要的原因之一,那就是小程序使用了双线程模型渲染,小程序有独立的渲染层线程和逻辑层线程,它们工作互不干扰,并不会像普通web页面,运行逻辑层会停止渲染层进行;双线程也给小程序产生延时问题,这延时可能不止一个地方延时,例如:渲染层和逻辑层通信延时及调用原生功能交互延时等;所以我们平时使用this.setData就是一个延时的事件,这可能是微信提供的api基本都是采用异步返回的原因吧。其实为何快,不单单指上述的原因而快,其实还有很多方面的考量,还有很多都是微信团队背后默默的付出,上面只是粗略的列举2个比较重要的说明。

1.4运行环境

其实小程序开发和vue框架比较类似,无论是语法还是渲染驱动,例如:页面渲染都是通过数据驱动而达到界面UI改变(具体来说就是宿主环境会把wxml代码转化成js,然后通过setData,把转化的js数据从逻辑层发送到渲染层,在通过节点对比,发现不同的就更新上去);

  • 关于兼容问题:

各平台脚本执行环境以及用于渲染非原生组件的环境是各不相同的(文档原文):

  • 在 iOS、iPadOS 和 Mac OS 上,小程序逻辑层的 javascript 代码运行在 JavaScriptCore 中,视图层是由 WKWebView 来渲染的,环境有 iOS 14、iPad OS 14、Mac OS 11.4 等;
  • 在 Android 上,小程序逻辑层的 javascript 代码运行在 V8 中,视图层是由基于 Mobile Chrome 内核的自研 XWeb 引擎来渲染的;
  • 在 Windows 上,小程序逻辑层 javascript 和视图层 javascript 都是用 Chrome 内核;
  • 在 开发工具上,小程序逻辑层的 javascript 代码是运行在 NW.js 中,视图层是由 Chromium Webview 来渲染的。

尽管各运行环境是十分相似的,但是还是有些许区别(文档原文):

  • JavaScript 语法和 API 支持不一致:语法上开发者可以通过开启 ES6 转 ES5 的功能来规避(详情);此外,小程序基础库内置了必要的Polyfill,来弥补API的差异(详情)。
  • WXSS 渲染表现不一致:尽管可以通过开启样式补全来规避大部分的问题,还是建议开发者需要在 iOS 和 Android 上分别检查小程序的真实表现。

1.5运行机制

小程序分为冷启动和热启动:

  • 冷启动:如果用户首次打开,或小程序销毁后被用户再次打开,此时小程序需要重新加载启动,即冷启动。
  • 热启动:如果用户已经打开过某小程序,然后在一定时间内再次打开该小程序,此时小程序并未被销毁,只是从后台状态进入前台状态,这个过程就是热启动。 小程序没有立即销毁整个小程序这个概念的,只有上面的冷启动和热启动,只要启动之后,接下来的操作无论是点击右上角的胶囊关闭还是直接返回微信还是点击手机home键等关闭操作都是前后台切换(排除你直接把微信后台关了或安卓单独切换把小程序关了的情况,手机内存不足直接被微信或手机系统回收了,这3种情况是真的立即销毁小程序了);
  • 前后台切换是不杀程序的,一般前台切换到后台5秒后,小程序就会被挂起,挂起后不运行小程序的代码(排除一些小程序提供全局的个别接口是可以运行的,如:后台音乐播放后台地理位置等)

  • 那小程序什么情况才会被销毁呢?

  • 当小程序进入后台并被「挂起」后,如果很长时间(目前是 30 分钟)都未再次进入前台,小程序会被销毁。
  • 当小程序占用系统资源过高,可能会被系统销毁或被微信客户端主动回收。
  • 每当小程序可能被销毁之前,页面回调函数 onSaveExitState 会被调用。如果想保留页面中的状态,可以在这个回调函数中“保存”一些数据,下次启动时可以通过 exitState 获得这些已保存数据。

2.代码层面

2.1 全局构造器

我们知道小程序全局都可以拿到一个构造器那就是var app = getApp(),无论是哪个页面我们都能直接拿到getApp()返回一个对象,这是因为小程序初始化时,宿主环境提供一个App()构造器来注册一个程序App,这是全局唯一的,也只能写在app.js根目录文件中。在这个构造器app实例中,有他自己的生命周期,这些生命周期在冷启动时都会触发,并且触发时间会比页面的生命周期早,如:

App({
   // 冷启动时会触发,且触发一次
  onLaunch: function(options) {},
  
   // 每次从后台切换到前台都会触发,可以很多次
  onShow: function(options) {},
  
   // 每次从前台切换到后台都会触发,可以触发很多次
  onHide: function() {},
  
   // 当小程序发生脚本错误,或者 API 调用失败时,会触发 onError 并带上错误信息
  onError: function(msg) {},
  
  // 可以存放一些全局信息,每次冷启动都会恢复到初始化值
  globalData: {} 
})

2.2 页面构造器

宿主环境中,为什么提供了Page()构造器用来注册一个页面,所以每次使用wx.navigateTo({ url: '' })跳转一个新页面时,宿主环境都会重新生成一个Page()构造器注册页面,但是有种情况不会,如果跳转同一页面,此时就不会重新注册一个新的页面,但是page()内对象都是新的,生命周期也是正常的,但是page()外的自定义函数或参数就跟上一个相同页面共用的;为了减少页面占用内存,小程序有自己的回收机制,例如:使用wx.navigateBack()wx.redirectTowx.switchTabwx.reLaunch跳转页面,都会不同程度的去回收销毁一些页面。页面构造器也有自己的生命周期,如下:

Page({
  data: { text: "This is page data." },// 页面初始化数据
  onLoad: function(options) { }, // 监听页面加载,触发时机早于onShow和onReady,只触发一次
  onReady: function() { }, // 监听页面初次渲染完成
  onShow: function() { }, // 监听页面显示,触发事件早于onReady
  onHide: function() { }, // 监听页面隐藏-小程序是否切换到后台
  onUnload: function() { }, // 监听页面卸载
  onPullDownRefresh: function() { }, // 监听用户下拉动作,用于下拉刷新(需要在页面文件page.json中配置"enablePullDownRefresh": true,才生效)
  onReachBottom: function() { }, // 页面上拉触底事件的处理函数,用户滚到底部触发(需要在页面文件page.json中配置"onReachBottomDistance": 50,才生效)
  onShareAppMessage: function () { }, // 监听用户分享事件
  onPageScroll: function() { } // 页面滚动触发事件的处理函数,表示页面在垂直方向已滚动的距离(单位px)
})

结束

对于小程序这几年的迅速发展官方确实已经做了许多优化,从刚开始的各种小问题(例如适配问题)一直到修正更新发布,并趋向于稳定,也让其它大厂玩命跟进及各种扶持政策自家的小程序;由于时间问题我将简单说几点个人记得比较清楚的进步或改变:

  • 1.小程序总包从一开始的4M到12M到现在的20M已经是跨越的增加;
  • 2.小程序从单一微信入口到现在已经支持普通浏览器直接调起小程序,不局限于微信;
  • 3.小程序从分包到独立分包再到异步加载分包,大大加速了小程序使用体验及增加开发内容的丰富度;
  • 4.从不支持直接分享到朋友圈到现在安卓机公测支持直接分享到朋友圈及部分ios机分享朋友圈;
  • 5.从只能前端开发小程序到现在云开发,让前端一键变成全栈程序员;
  • 6.从不支持npm到现在基本稳定支持npm,增加插件的丰富度;
  • ...

创作不易,记得点赞收藏加评论,你的评论是我创作的动力,如有不对欢迎指出(如有侵权请告知马上删)。

image.png

惊喜

感谢各位大佬阅读和支持,欢迎大家就本文内容进行评论和吐槽!🙏🙏
条件:

  • 如果评论区超过 10 人评论,将会抽取 2 条优质评论分别赠送掘金徽章 1 枚
  • 截止日期为 9月10日 24时 最后感谢掘金平台对本次活动的大力支持!