收藏
评论

代码按需注入与初始渲染缓存官方


你好,我是李艺。

上节课我们主要学习了自定义组件的优化技巧,这节课我们学习按需注入与初始渲染缓存。

在第一课关于启动流程的介绍中我们已经得知,第二阶段代码注入在冷启动中是不可或缺的,只有逻辑层和视图层代码全部注入,并且时间点对齐以后才会开始第三阶段首屏渲染的工作。如果这个小程序的这个代码它很大、代码很复杂,又或者用户的设备是低端机,性能不太好,这一阶段便会显著影响启动性能。

针对这个问题,小程序提供了懒加载机制,允许首屏渲染之前按需注入仅这个首屏运行所需要的一个代码,其他的代码可以在稍后用到的时候再加载和注入。下面看项目实践。


首先看实践一:按需注入

启动按需注入只需要在app.json配置文件里面添加一个lazyCodeLoading的配置,添加配置之前,小程序在首屏渲染之前,它页面所在的代码包以及主包的所有页面代码小程序都会加载并且注入,添加这个配置以后虽然相关的代码包仍在下载,但仅会加载和注入当前这个页面,它所需要用到的那些组件以及代码启用懒加载以后,在微信开发者工具的调试区可以看到相应的关于懒加载的提示,有一点我们需要注意,如果这个页面本身它比较复杂,用到了很多自定义的组件,这些自定义组件在开启按需注入这种模式以后仍然是会加载的,如果我们想进一步减少这个首屏需要注入的代码,可以在启用按需注入以后同时启用占位组件,关于占位组件,稍后我们会再详加讲解。

下面我们看实践一的代码演示。

在小程序里面启用按需注入,也就是俗称的懒加载,很简单,只需要在这个项目的app.json这个里边加一条配置就可以了,然后其他的这些工作全部是由微信完成的,我们只需要加一条配置就可以了。写一个叫做lazyLoading,当我们打一个lazy的时候它自动提示它应该填写的正确的内容, lazyCodeLoading等于requiredComponents,包括它这个值也会自动帮我们完成,其他的我们都不需要做,这个已经添加完了。现在我们单击编译按钮看一下它的一个表现,注意看在我们调试区现在多了一条打印信息:Lazy code loading is enabled告诉我们现在懒加载已经启动了,只是注入我们需要的一些组件,它有这样的一条提示,代码演示就到这里。


下面我们看实践二:静态初始渲染缓存。

前面我们使用过骨架屏,骨架屏是在这个页面完全加载以后,由微信开发者工具负责生成的一个色块状的页面结构,在运行时与骨架屏对应的还有一项技术,就是初始渲染缓存。初始渲染缓存是第一次页面运行的时候由微信客户端负责将这个页面在本地的某个区域缓存起来,下次真正的页面未加载之前,先展示缓存过的页面。初始渲染缓存又分为静态和动态两种,在这个页面配置里面只需要添加一个叫做initialRenderingCache这样的一个配置就可以启用静态缓存。静态初始缓存以页面初始的data数据与页面里面的wxml标签代码共同渲染成一个页面在本地缓存,在下一次用户访问页面的时候,不必等逻辑层代码初始化完毕它就会将缓存的页面内容先发给用户展示,在一定程度上,初始渲染缓存的页面相当于是一个静态化的本地化的骨架屏页面。

现在看实践二的代码演示。

启用渲染缓存很简单,也是加一条配置就可以了。我们打开商品详情页,它的json配置文件,我们只需要在这个里边加一条initialRenderingCache,它的值有两个,然后下面这个static代表的就是静态初始缓存,把这条配置加上然后就可以了。然后接下来我们再调一下我们编译设置,以商品详情页为启动页面进行一个测试,我们把警告信息打开以后可以看到这个地方会有一个提示,无效的page.json initialRenderingCache,提示我们这个地方有一个无效的页面配置,这个配置它其实只是在我们的微信开发者工具里面会有,如果是我们用手机测试的话,刚才我们提到了,它其实会有一条关于初始信息在这个页面成功加载之前就进行渲染的这样的一条提示。那个是我们的初始渲染缓存机制在起作用,对于我们开发者工具里面这样的一条提示,其实可以无视它,这个无关紧要的 没有关系。代码演示就到这里。


下面我们看实践三,动态初始渲染缓存。

动态初始渲染缓存与静态初始渲染缓存的不同在于配置节点的值不同,在这个页面配置里面我们添加一个initialRenderingCache等于dynamic这样的一个配置就可以启用动态缓存了,与静态初始缓存不同的是动态缓存可以指定缓存的内容。例如我们举个例子:在页面加载完成以后,通过调用setInitialRenderingCache的一个方法设置需要动态缓存的数据,这个方法的一个参数是一个dymamicData,也就是动态数据,它将与页面初始的data一起混合,然后与这个页面的wxml源码共同生成一个缓存的页面,以便下一次用户访问的时候直接去使用,并不是在本次这个页面展示的时候使用的。设置动态缓存的代码我们一定要放在 onReady周期函数里面,不能比这个时间点要早,早的话其实会影响这个页面的整体的一个渲染效率的。在微信开发者工具的模拟器里面,初始渲染缓存的一个缓存功能,刚才我们提到了会有一条黄色的无效的initialRenderingCache这样的一个配置警告信息,这个信息它不单在静态缓存里面有,在动态缓存里面其实它也有,但对于这条信息其实我们没有必要在意,我们在手机上进行测试的时候其实是没有这样一条提示的,我们可以在手机上预览商品详情页,然后关掉小程序,怎么关掉,就是在微信顶部下拉这个屏幕,在最近使用过的小程序列表里面将测试版本的小程序下拉到下方的红色区域内进行删除,当我们下一次在手机中再次预览的话就能看到这个缓存页面,但是如果你这个页面足够简单,由于它加载太快的话,这个缓存页面可能还是看不到。当然我们在调试区会看到一条提示就是Update view with init data,这个提示它其实就是我们的初始渲染缓存机制在发挥作用,并且这条提示它会在我们这个页面的onLoad事件之前就会显示出来。现在我们在屏幕上看到的这个截图就是我们手机上测试的一个截图效果。

下面我们进行实践三的代码演示。

启用动态初始渲染缓存也很简单,主要也是改配置,在我们商品详情页的json配置文件里面将它的initialRenderingCache这个节点,它的值由static改成dynamic,如果这个我们记不清的话,其实还可以借助它的自动提示功能,然后回车就可以了,这是第一步。第二步就是我们如果想加一点动态的数据作为缓存的一部分的话,可以在这个里面有一个关于swipers数据的加载,加载完成以后,在最后这个地方可以再调用它的一个叫做setInitial,这个地方没有提示对吧,第一个方法可以查文档,第二个方法可以看最终源码,我们就看一下最终源码。

这个源码里面序号跟我们实践是对应的,比如说我们第三讲的实践三对应的源码就是3.3 setInitialRenderingCache这个代码,这个地方我们可以看到 这个名字它用的其实是我们data对象里面默认的有的这个名字,然后这个数据是我们新加载到的数据,但是我们设置跟setData不一样,setData是我们设置这个页面里面,给这个页面用的,这个是给我们动态渲染缓存机制去使用的,代码设置完以后我们可以再测试一下。在调试区刚才我们提到了,仍然会看到无效的page.json initialRenderingCache这样的一个黄色的配置提示,这个没有关系 其实可以无视它。在手机上测试它这个提示其实是没有的,这个代码演示就到这里。


最后我们总结一下,按需注入是小程序的一项优化机制,只需要开发者在app.json配置文件里面加一条配置,不需要再做其他的任何事情就可以显著提升小程序的启动性能了,这条配置可以作为项目的一个默认配置进行保留,初始渲染缓存它相当于之前PC Web 2.0时代在后台自动为动态页面生成的HTML静态页面,当用户访问的时候,它发给用户的是静态页面,动态内容有更新的时候,静态页面在后台它会重新再生成一次,这是一种以空间换时间的一种优化策略,多占用一点点的内存和硬盘以争取启动时间上的一个减少。

下面我们再说一下初始渲染缓存的它的一个工作原理,在小程序启动页面的时候,尤其是小程序冷启动进入第一个页面的时候,由于逻辑层初始化的时间比较长,等到逻辑层与这个视图层全面初始化完毕再渲染出这个页面可能会看到白屏现象,这是我们不想给用户看到的,启用初始渲染缓存可以使视图层不需要等待逻辑层初始化完毕,也就是这个时候我们可以跳过逻辑层与视图层初始化完成时间点的这样的一个对齐的限制,直接提前将一个缓存的页面渲染结果展示给用户,具体的实现的流程它是这样的,在小程序页面的第一次被打开的时候,微信就将这个页面的初始渲染的结果记录下来,然后写入到一个临时的缓存区域里面,在这个页面第二次打开的时候,微信它查看缓存里面有没有这个页面,如果是有 直接就把这个页面展示给用户,但是我们要知道缓存的页面它是无法响应用户的交互事件的,需要等到这个页面真实渲染完成以后这个页面才可以正常访问,现在我们在屏幕上看到的这两个链接是我们本节课涉及到的文档链接。这节课我们就讲到这里。


这节课我们主要学习了代码的按需注入,俗称懒加载,开启方式是在app.json配置文件里面添加一个值等于requiredComponents一个lazyCodeLoading的配置节点,关于初始静态缓存,这是一种空间换时间的优化策略,它可以减少用户等待页面加载的时间,但这个缓存的页面是不能进行事件交互的,并且并不是所有的组件都支持静态缓存的,基本上我们在文档上看到所有的原生组件它都不在这个缓存之列,不在缓存之列也不会给我们带来一些错误,它只是这些组件它无法在缓存以后呈现给用户,所以初始渲染缓存只适合这个页面节点数量比较少、比较简单、内容不经常变化、用户又经常访问同时wxml节点的结构又非常简单的这样的一些入口页面去使用。

初始渲染缓存与骨架屏是同一种优化策略,本质上它们都是以空间换时间,只不过是两个不同方向的一个优化,一般而言我们用了骨架屏以后就不要再使用初始渲染缓存了。反之也是一样的,用于提供导航功能的一个首页或者是二级页面,一般适合使用初始渲染缓存,而这个页面经常变化的时候,它时效性较高的动态详情页面,这种页面它适合使用骨架屏。当然了如果这个页面想让用户尽早看到内容的话,下节课我们学习如何使用分包,独立分包以及分包预下载。

这里有一个问题请你思考一下,在多地图游戏开发里面,当用户从一个地图跳入到另外一个地图的时候,我们总是能看到一个资源加载进度条,这是游戏对地图资源加载的一种优化,这类游戏它并没有在启动的时候就开始加载所有的地图资源,而仅是在加载当前这个游戏运行所需要的一个最小的资源包,在小程序开发里面有没有这样的一种机制可以实现相似的资源加载优化效果?下节课我们就一起来探讨一下这个问题。


点击查看开放文档:

最后一次编辑于  2022-07-14
赞 15
收藏

17 个评论

  • 苏勒
    苏勒
    2023-09-26

    怎么不对比一下开启和不开启的性能状况,到底提升了多少?

    2023-09-26
    赞同 4
    回复
  • 夏虫不可语冰
    夏虫不可语冰
    2022-07-24

    企业微信小程序不支持

    2022-07-24
    赞同 4
    回复
  • Mars
    Mars
    2022-06-13

    使用了第三方组件,开启之后一大堆问题。

    2022-06-13
    赞同 3
    回复 3
  • 覆盆子
    覆盆子
    2022-07-21

    小游戏能使吗

    2022-07-21
    赞同 2
    回复 2
  • 小斌
    小斌
    发表于移动端
    2022-07-02
    不错。
    2022-07-02
    赞同 2
    回复
  • Frank
    Frank
    2022-06-29

    哇,uniapp写的项目,相关配置还没有更新,蓝瘦

    2022-06-29
    赞同 2
    回复
  • 帆小小
    帆小小
    2023-11-30

    小程序的初衷不就是为了区别H5, 把资源全部加载并缓存到本地来优化打开体验吗? 现在又是分包, 又是按需注入的, 和H5又有什么分别了呢?

    哦, 还是有分别的, 小程序搞了2个线程, 一个逻辑线程, 一个视图线程, 然后为了解决2个线程通信导致的渲染效率的问题, 又出了一个WXS脚本, 为了进一步提升视图线程的渲染效率, 又出了个Skyline渲染, 可是这玩意又把WSX脚本从视图线程给移除了, 然后解决这个问题, 又出了个Worklet.

    腾讯的大神们, 有种就把 webview 重写一下, 不要为了复用别人的东西, 又想封闭, 然后打一堆补丁

    2023-11-30
    赞同 1
    回复 1
    • Donkeyman
      Donkeyman
      06-20
      确实,不过skyline+js引擎已经可以认为是一个浏览器了
      06-20
      回复
  • l
    l
    2022-07-25
    加了"lazyCodeLoading": "requiredComponents" 页面打开空白。。
    


    2022-07-25
    赞同 1
    回复 3
    • 海斌
      海斌
      2022-07-26
      也遇到空白页问题,扫码进入首页,跳转到注册页面,再次扫码进入首页,跳转到注册页面,点击下一步进入主页时主页空白;测试了多次,应该是跳转第三个页面,第三个页面没有自动注入,但是真机调试日志上显示第三个页面的onload/onshow执行了,但onload中的打印日志并没有执行
      2022-07-26
      1
      回复
    • LIYI
      LIYI
      2022-07-30
      清一下编译缓存?
      2022-07-30
      回复
    • l
      l
      2022-10-14回复LIYI
      是小程序打开就会空白,去掉那个配置后就正常了
      2022-10-14
      1
      回复
  • J.A.R.V.I.S.
    J.A.R.V.I.S.
    2022-06-16

    开启用时注入的组件是相关代码都没加载过来,还是说代码已经加载了,只是没执行注册逻辑呢?

    2022-06-16
    赞同 1
    回复 1
    • LIYI
      LIYI
      2022-06-27
      根据官文文档描述,“在打开上述「按需注入」特性的前提下,可以通过「用时注入」特性使一部分自定义组件不在启动时注入,而是在真正被渲染时才进行注入,进一步降低小程序的启动和首屏时间。”

      应该是没有注入,但已经加载了。

      「用时注入」节省的是WXSS等代码编译、注入的时间。但如果把用时注入的组件载分批次另外加载,反而麻烦了。加载遵守的应该是代码包、分包相关的规则。
      2022-06-27
      1
      回复
  • 泉水
    泉水
    2023-10-24

    启用lazyCodeLoading之后,引入kbone页面后,小程序在pc端会空白

    2023-10-24
    赞同
    回复

正在加载...

登录 后发表内容

小程序性能优化实践

课程标签