本篇文章,我将简单聊聊前端性能优化的一些点。
我认为各种优化最好都基于实际场景来研究和设计,所以这里我不会谈一些通用的优化点,而是以微信小程序优化为例,来简单说明一下。希望,能给你一些启发。
接下来,我将从小程序启动流程开始,来一一说明一下。
资源准备 #
微信后台需要确定微信小程序的版本、配置等信息,同时准备好小程序环境。这个阶段,开发者无法干预,所以无法对其进行优化。
代码包加载 #
冷启动时,基于小程序的版本,将会加载对应的代码包。代码包的大小会影响加载的耗时,所以我们需要通过某些方式来降低包体积。
因为一开始加载的为主包,所以我们主要优化主包的体积:
- 移除未使用的代码和资源。
- 压缩代码和资源。
- 合并代码和资源。
- 一些非首屏的代码,可以拆入到分包中
- 一些静态资源,如图片、字体等,可以放到 CDN 上
- 某些场景下的代码,如弹框组件,也可以放到分包中,并通过分包异步化来加载
- 一些不太重要的功能,可以跟产品和业务沟通,并进行下线
- 因为我们基于跨端框架,所以默认可能会引入一些非小程序的逻辑,对于这类代码,我们一方面通过条件编译来进行剥离,另一方面通过编译配置来剔除掉。
代码注入 #
代码包加载后会进行代码注入,代码注入分为两块,逻辑层注入和视图层注入,分别对应小程序的 js 文件和 wxml、wxss 文件,分别通过两块引擎基于两个线程来承接。
注入阶段的耗时优化,微信官方提供了两个优化策略:
- 按需注入:通过配置
lazyCodeLoading为requireComponents,可以实现按需注入。它仅注入当前访问页面所需的自定义组件和页面代码。未访问的页面、当前页面未声明的自定义组件不会被加载和初始化。 - 用时注入:在按需注入的基础上,可以指定一部分自定义组件不在小程序启动时注入,而是在真正渲染的时候才进行注入。具体操作为,给相关自定义组件设置占位组件,一开始会先渲染占位组件,渲染流程完成后,才会开始注入相关的自定义组件代码,注入结束,再替换占位组件。通过这种方式,我们可以将一些弹框这种不用及时透出的组件先不注入,提高首屏的渲染耗时。
除此之外,我们也要避免一些如 getSystemInfoSync 等同步调用的 API,因为它们会阻塞流程。
首次渲染 #
在微信小程序的生命周期中,微信官方定义了一个首次渲染的指标,即从小程序启动到onLoad、onShow、onReady这三个生命周期函数的执行完成截止。
代码注入后的这个阶段,渲染的是非业务数据的视图。一般来说,为保证体验,我们这里会渲染一些loading视图,比如loading图标、loading文字,或者骨架屏等。
这块的耗时,主要是视图的耗时,我们可以从整体页面结构来优化:
- 减少视图层级:避免嵌套过深的视图结构,因为视图层级越深,渲染耗时就越长。
- 视图dom数量:尽量精简视图结构。
- 合理使用动画:动画会增加渲染的耗时,所以我们需要合理使用动画,避免在首屏渲染时使用过多的动画。
除此之外,微信官方提供了一个配置项initialRenderingCache,通过配置其为static,可以开启初始渲染缓存。这样,第二次启动小程序时,导航栏、骨架屏等视图将快速展示。
请求业务接口 #
微信小程序存在并发请求数量限制,如果我们的核心接口放到后面请求,可能就需要等待。
所以,为了提高用户体验,我们需要将核心接口放到前面请求,其他接口放到后面请求。这样,就不会阻塞首屏的渲染。
渲染业务数据 #
这块主要是渲染,所以可以沿用首屏渲染中从页面结构优化的方向。
页面交互 #
页面渲染完之后,基于用户的交互,会触发一些状态的变更,并导致视图的变更。为了优化交互体验,我们需要:
- 避免频繁、大规模的调用 setData ,这也是官方建议的,毕竟这会频繁触发视图的渲染、增加内存占用,以及增大线程间通信耗时。
- 页面卸载时,需要把一些eventBus、定时器进行销毁,避免内存泄漏,以及后续持续的监听调用,占用多余资源。
页面切换 #
除了页面交互,用户也可能切换页面。在切换页面时,页面会可能会触发分包的加载等操作,这段时间我们可以好好利用下,通过一些优化策略来提高用户体验。
- 分包预加载:预加载下一个页面的代码包,这样切换到下一个页面时,就可以直接从内存中加载,而不需要等待网络请求。
- 数据预拉取:在切换到下一个页面时,我们可以预拉取下一个页面需要的数据,这样切换到下一个页面时,就可以直接使用预拉取到的数据,而不需要等待网络请求。
总结 #
以上就是我对微信小程序性能优化的一些思考和总结。其他场景也是类似,即梳理整个生命周期,并基于周期内的每一个节点进行优化。