小程序启动速度优化实践


帮企商城 2021-09-16 13:25:49


图怪兽_f09fbf0090e57ae49f6d1f9b9c22b3b8_98680.jpg


前端应用的启动速度一向是移动终端的优化重点,因为这是面向用户进入的大门。良好的启动速度无异于会带来良好的用户体验。

 本篇文章主要介绍商城小程序的启动速度优化方法。

 启动时间消耗概览

 小程序的启动时间主要分为以下几个阶段:

 微信客户端比对版本差异,下载并加载代码。

小程序本身的初始设置,业务逻辑请求处理。

页面的渲染。

所以,小程序从点击启动到渲染完成主要会经历以上几个过程,接下来我们针对以上部分进行优化说明。

 

代码下载加载阶段

众所周知,小程序本身使用的是JS,HTML,CSS等语言进行开发。所以在代码发布时,微信会对这些文本文件进行必要的体积压缩。除此之外还有应用所需的图片资源文件。

 所以发布后的小程序主要包括:

 压缩后的JS,HTML,CSS等文本文件。

应用中所需的图片资源文件。

这些文件的总体积便会影响到小程序第一阶段的加载速度。而在这些文件中,图片资源文件占了总体积将近80%的比例。

 所以,针对这一阶段的主要优化方式为:

 将不必要的图片资源存储于服务器,通过url加载。 不必要的图片资源包括但不限于:营销活动的背景图、活动的规则说明图、活动BannerGIF图等。在优化时,按照文件大小从大到小排序,分情况处理。

 将必要的Icon图做压缩,如果不需要Aphla通道的图可转换为JPEG格式。

推荐在线图片压缩处理网站:https://tinypng.com/

 对于按钮背景图等可使用CSS达到同样效果的使用CSS绘制。

 避免冗余代码,及时移除废弃代码。


 代码初始化,业务逻辑请求处理

这一部分主要与业务本身联系紧密,需要根据业务需要来进行优化处理。以下主要针对主商城的业务模式进行优化说明:

 小程序优化之前的启动过程如下:

 登录 -> 获取上次下单地址 -> 请求货架信息 -> 通过购物车信息 -> 渲染

第二次启动过程如下(与首次相同):

 登录 -> 获取上次下单地址 -> 请求货架信息 -> 通过购物车信息 -> 渲染

小程序优化之后的首次启动过程如下:

 登录 -> 获取上次下单地址 -> 请求货架信息 -> 分页渲染 -> 同步购物车信息

第二次启动过程如下(没有登录过程):

 获取用户上次下单地址 -> 请求货架信息 -> 分页渲染 -> 同步购物车信息

可以看到,这里主要针对登录做了优化,并将页面渲染前置。

 在优化过程中,发现小程序每次都会重新登录,显然不需要这么做。如果将登录状态存储在本地,可以减少登录一系列过程的开销。但是为了保证登录状态的过期问题,所以专门对网络框架层做了处理:如果后端返回statusCode401或者403,或者statusCode200但是内部的code102,则会重新走登录过程。登录完毕之后会再次请求原有的接口,好处在于业务层并不需要关心也不会感知到token过期的问题。

 

渲染

在优化之前,小程序会显示一个Loading图,直到购物车信息同步完毕。我们为了尽快的将信息展示给用户,将这个Loading图前置到了货架信息开始渲染时,也就是说,在渲染货架信息的时候,便不再显示Loading。这个过程很重要,对启动速度影响很大。

 除此之外,在初次渲染时只渲染少量的数据,但足满一屏。通过测试发现,渲染全部数据与渲染一屏的数据时间差异较大,我们在用户需要查看更多数据的时候,再对剩下的数据同样进行分页渲染:货架数据一次10条。

 页面渲染的同时,我们也在同步购物车信息,做到了并行进行。在同步完成之后,再将购物车的信息更新到货架上。


 总结

经过以上大幅优化手段,小程序启动速度明显加快。在开发者工具上的运行结果为:之前首次是4秒,优化之后首次是2秒。第二次进入之前还是4秒,优化之后为1.5秒。可以算是”秒开“了。

 这里我们并没有涉及网络优化方面,但这并不意味着网络部分不需要优化。如果在实际开发中,网络部分不再合理的范围内,则需要考虑服务器相关的优化:代码优化、DNS优化、服务器地理位置优化、网络环境优化、网络包压缩以及适时不采用HTTPS等加密传输等方向。另外由于小程序是运行在微信内置的相关引擎上,所以在我们不可控的范围内也有一定的开销,这一部分需要及时关注微信方面的更新。

 

工具

优化应用需要一个得力的工具,这里为大家共享一个执行时间统计工具,这款工具可以统计两个点之间所花费的时间,使用方便简单。以下是JS语言,其它语言可参考实现方式:

 

let index = 0;

 

function logTime(arg) {

  index++;

 

  const app = getApp();

  let current_date = new Date();

 

  let offsetTime = 0;

  if (app && app.globalData.lastTimeLogFunctionCallTime !== 0) {

    if (app.globalData.startTotalTime == 0) {

      app.globalData.startTotalTime = current_date.getTime();

    }

    offsetTime = current_date.getTime() - app.globalData.lastTimeLogFunctionCallTime;

  }

 

  let desc = current_date.getMinutes() + "" + current_date.getSeconds() + '' + current_date.getMilliseconds() + "毫秒";

 

  if (app && app.globalData.startTotalTime != 0) {

    let totalStartTime = new Date(current_date.getTime() - app.globalData.startTotalTime);

    desc += ", 启动总耗时: " + totalStartTime.getMinutes() + "" + totalStartTime.getSeconds() + "" + totalStartTime.getMilliseconds() + "毫秒";

  }

  if (offsetTime != 0) {

    let time = new Date(offsetTime);

    desc += ", 与上一次调用的差值为: " + time.getSeconds() + "" + time.getMilliseconds() + "毫秒";

    if (DEBUG_STACK_MODE) {

      let currentCallStack = (new Error).stack;

      desc += ", 当前的调用栈为: " + currentCallStack;

    }

  }

 

  logi('TIME_TAG ==> ' + index + (arg ? " " + arg : "") + ' 当前方法的调用时间为: ' + desc);

 

  if (app) {

    app.globalData.lastTimeLogFunctionCallTime = current_date.getTime();

  }

}

 

function logi(infoMsg) {

  if (DEBUG_MODE) {

    console.info(infoMsg);

  }

}


相关阅读:

春哥团队获得1000万元投资将用于开发各种商业源码系统

春哥技术团队在京发布春哥数字人系统CGDigitalPersonSystem

春哥团队8周年:帮助更多的人实现在家创业赚钱

帮企商城国庆狂欢盛宴 放“价”到底!

脱单盲盒项目,日入过万不是梦!2021年最大风口项目!

如何给我们春哥团队付款?

微信小程序日常开发中常遇到的错误代码

小程序前端直传阿里云oss

微信小程序之image组件

解决微信小程序switchTab不能带参方法