标签:row 逻辑 ios平台 开发效率 timer 多个 平台 目的 res
引子:
一个指标引发的血案
https://www.cnblogs.com/Sherlock09/p/11726885.html
进入移动互联网时代,传统Web开发技术(HTML,CSS,JavaScript)风光不再,客户端技术(iOS以及Android)依靠良好的体验重新崛起。但是客户端技术的开发效率始终无法与Web技术抗衡,同时会受到诸多平台层面的限制。在这一大背景下,小程序独特的架构诞生了,它将Web前端技术与传统的客户端技术结合在一起,其目的是在开发效率上超过传统的客户端技术,在使用体验上超越传统的Web前端技术。由于小程序的架构区别于传统的Web前端技术,开发者在开发过程可能会遇到一些性能上的问题。本文旨在介绍百度小程序一些实现原理和优化手段,帮助开发者优化自己的小程序。
在传统的Web前端项目中,所有代码全部运行在浏览器中。而小程序提供的运行环境有两种,分为逻辑层和视图层。假设现在开发者的小程序项目中有两个页面pages/index和pages/home
,那么逻辑层代码指的是app.js
与pages/index/index.js
还有pages/home/home.js
,视图层代码指的是pages/index/index.swan
和pages/home/home.swan
。在小程序中想要改变视图需要逻辑层与视图层之间进行通信,这部分通信是需要客户端参与,会消耗一定的系统资源。
存在问题:setData 调用随意、频繁,有很多不必要的数据没有必要存放在data中
setData方法是开发者通过逻辑层向视图层发送数据的方法。每一次 setData 的调用,都会触发一次通信,而每一次的通信都会消耗一定的系统资源,因此,开发者在使用 setData 需要注意以下几点:
不建议在更新数据结构当中的某一子项的时候将整个数据结构放到setData方法中,可以通过优化setData的key值来实现。
错误写法:
let person = this.getData(‘person‘);
|
正确写法:
this.setData(‘person.age‘, 30);
|
在更新列表中某一项内部的值时,推荐的用法为:
this.setData(‘list[0].person.name‘, ‘Harry‘);
|
在处理无限滚动页面加载的时候,我们发现很多开发者将新的一页上的数据添加整体的数据里面再调用setData。这样做造成每次页面加载传输的数据越来越大。
未优化情况下的做法:
let pages = this.data.pages.push(pageData)
|
优化后的做法:
Page({
|
使用trackBy来优化列表更新时的渲染性能
当使用下拉刷新功能时,新的数据会被添加到当前列表的头部,这种情况下,页面中列表内所有的项都会被重新渲染一次。
// 下拉刷新更新方式举例
|
如果使用trackBy,那么原先的列表内的项位置会移动,新添加的项会被渲染。这样可以省去一部分重新渲染带来的消耗。
// 使用trackBy举例
|
优化:
1. 由于代码中的setData 会增加逻辑层与渲染层间的线程通信,所以要避免频繁的调用setData,将相应的调用合并
2. 对于页面中不涉及渲染的变量,从data中拆分出来(待),scene这些公用的数据可以放在初始化的app.js中
3. 小程序版本和api 更新迭代快,废弃掉原来旧的影响性能的api,例如getData这个api,在之前的版本都是可以用的,在新的版本中虽然也可以用,但是由于对性能有一定影响,所以
遵循优化的原则,改掉这些对性能有影响的api
减小包的体积可以减少包的下载时间。根据已经上线的小程序包的统计分析结果,小程序官方将主包的体积控制在 1M 左右,包内的文件个数限制在 200 以内。除了体积之外,小程序包内的文件个数也直接影响到小程序包的解压速度。因此,需要减少小程序包内非必须的图片、字体、音频等资源的文件个数。同时,逻辑层与视图层的代码都需要加载到 webview 实例当中去,减小这部分的体积也会加快小程序的启动速度。
存在问题:包体积过大,目前主包大小在1.44M
优化方案:
分包加载是智能小程序用来解决包体积过大而给出的一个技术解决方案(点击查看分包加载相关文档)。为了最大程度的减少主包的大小,提高小程序的加载速度,开发者使用分包加载策略时,建议将必须的和经常访问的页面放入主包当中,例如将声明在 app.json 当中的 tabBar 配置项下的页面放入主包当中。另外,根据小程序的投放场景不同,开发者需要仔细思考自己的小程序中哪些页面是经常被访问的。举个例子,在Feed和搜索分发的小程序非首页页面我们建议放到主包中,避免首次打开投放页面处于分包内时需要先下载主包再下载分包而导致的性能退化。
{
|
3. 图片组件懒加载
JSON描述文件可以通过jsonminify工具对JSON文件进行压缩。
绝大多数小程序都需要请求服务端来获取渲染页面的数据,对于请求数据的优化,总结起来就是一句话,关键的早请求,不关键的晚请求。
涉及到关键数据的异步请求可以尽早的发出,不需要等待页面的 onReady 生命周期之后才去发送请求。这样可以让页面所需的数据尽可能早的处于 Ready 状态。除了在现有的生命周期发送数据请求以外,我们还提供了prefetch机制(prefetch机制需要在app.json之中进行配置)能够在小程序框架启动阶段就去请求数据,而不用等待页面生命周期触发。
根据小程序被打开的场景,可以对异步请求进行优先级排序,不重要的请求放在页面的 onReady 生命周期去请求。例如,贴吧小程序最经常被访问的页面是帖子内容页,因此除了当前帖子内容以外的数据请求都是非关键请求,可以将触发的时机延后,保证帖子内容尽可能早的被加载出来。
当使用swan.navigateTo
进行页面跳转的时候,旧页面是没有被销毁的。旧页面当中定义的定时器仍旧会运行。因此在页面跳转的时候,一定要记住清理没有用的定时器:
Page({
|
自定义组件与模板内的import与include功能都可以达到代码复用的效果。需要注意的是,如果自定义组件内没有逻辑层的功能的话,这时候使用自定义组件就是非必须的了。我们可以用下面的方式实现代码的复用:
<import src="./person.swan" />
|
// Person相关函数
|
// 复用person.js中的函数
|
提前加载页面的骨架,可以减少用户的白屏等待时长,百度智能小程序提供了渐进式加载机制,使用这一机制,可以给用户带来更好的用户体验。下面将介绍如何使用这一机制为开发者自己的小程序提供渐进式加载的能力。
这里插一句额外的,在其他webpack的项目中,也可以使用page-skeleton-webpack-plugin,这个插件来生成骨架屏,具体可参考
https://github.com/ElemeFE/page-skeleton-webpack-plugin
第一步:在工程项目根目录新建skeleton文件夹(除了config.jso以外的文件目录可自定义名称),目录如下所示
skeleton
|
第二步:使用标准HTML与CSS,编写骨架屏模板文件,如index.tpl骨架屏代码如下图
<style>
|
第三步:配置config.json文件,pages和骨架屏是多对一的映射关系,可配置多个页面对应同一个骨架屏模板
{
|
说明
1. 需要目前最新的开发者工具rc版本与百度App 11.10及其以上版本 2. 骨架屏移除的时机由开发者自己掌控。开发者可以在Page内通过调用this.removeSkeleton()移除。
当前首页白屏率
小程序白屏数据出现异常上涨时,可以从以下三个方面着手排查分析:
有些小程序的页面数据展示可能存在前置条件,例如需要登录、定位等。在条件不满足时,可能存在兼容处理问题。这里给出常见的几种case:
小程序框架自身也在不断更新,所支持的能力也在不断更新和扩充。同样,开发者也会对小程序自身也会进行版本更新。这里就涉及到了兼容性问题。小程序框架版本修复Bug记录和版本兼容性,请参考以下连接了解和主动规避:
已有启动性能数据,平均数据和80分位数据较快不一定能保证白屏率就低,白屏case大概率发生在性能的长尾数据中。
从平台跟进的多个小程序白屏数据分析结果来看,小程序白屏率高的主要因素是页面数据加载和渲染较慢。如果小程序上线后白屏数据就处于高位,或者版本更新后白屏数据上涨,可以通过以下方面进行分析和优化:
页面数据加载方式:
针对一次请求返回的数据过多的情况,可以从两个角度来优化:1 、非关键数据延迟请求,2、非关键数据延迟渲染
非关键数据延迟请求:
swan.request({
|
非关键数据延迟渲染
this.setData({keyData}, () => {
|
增加过渡态提示:
页面加载时,可以使用Loading组件等形式进行提示,给用户一个提示,提升用户体验。
使用骨架屏:
骨架屏形式类似下图,可以很好的提升用户使用小程序时的体验。
上线四五天后,整体效果有了一定的提升,由于用户收敛和老用户更新版本的影响,最终的效果还需再观察一段时间
通过这次性能优化的调整,体会到了小程序这种运行在端内的代码对于性能的苛刻要求,你的每一部分代码的简洁程度,代码组织的调整,静态资源大小、部署、加载的策略
都深深影响到小程序加载的整体指标。
同时,日常生活中的代码,也有同样的问题
1. 对于新的代码,是否做到了合理的书写?拆分?便于维护?
2. 对于冗余的代码,实际上严重影响着代码整体加载效率,是否有目的的清理和调整?
3. 对于静态资源,一些图片、字体,图片有没有压缩合并?冗余的一张图片有可能比冗余的一个jquery更大?
4. 对于旧的api,拿vue2.0举例,在v-for的时候,如果把key添加上,将大大提升Vnode diff的效率,这块是否有意识的去优化
5. 很多东西,实际上我们都知道应该去做,是否去主动的做一些,哪怕做一点,哪怕这次去一个 没用 || 已经 改版了的图片、js、css(主要)
注:由于内部安全红线,相关业务信息已隐藏,转载请著名出处(https://www.cnblogs.com/Sherlock09/p/11726885.html)
标签:row 逻辑 ios平台 开发效率 timer 多个 平台 目的 res
原文地址:https://www.cnblogs.com/Sherlock09/p/11726885.html