0

0

手把手带你看看小程序如何优化?(实践总结)

青灯夜游

青灯夜游

发布时间:2021-12-30 10:28:40

|

6277人浏览过

|

来源于掘金社区

转载

小程序如何优化?本篇文章给大家总结一下小程序优化实践,看看小程序优化项,希望对大家有所帮助!

手把手带你看看小程序如何优化?(实践总结)

小程序运行过程

我们先来梳理一下小程序的运行原理,磨刀不误砍柴功。

一图胜千言:

1.png

建议大家认真去理解图中的内容,对于小程序开发以及优化方向都有较有力的理论支持。

优化项

1. 合理的使用分包

微信小程序的主要特点是启动快速,为了这一特性,官方因此限制了包的大小,上限为 2M。

分包是小程序优化的第一要务,能有效提高小程序启动速度,以及页面打开速度。

包分为【主包】【普通分包】【独立分包】。

【主包】应该只放置启动页或者TabBar页面。

【普通分包】放置非TabBar页面的其他页面,推荐按照页面数量或者模块划分多个分包,减少分包的大小,当用户进入对应分包页面的时候才会去下载这个包,这也实现了包的按需加载,避免了资源浪费。当小程序从普通分包中的某个页面的时候启动时,需要首先下载主包,然后在下载分包。

【独立分包】放置一些独立性较高的页面,当小程序从独立分包中的页面启动时,只会下载独立分包,从而大大提高小程序启动速度,当用户进入TabBar页面或者其他普通分包页面才回去下载对应的包。

独立分包中不能有任何全局的东西,包括组件,登录等,引入任何其他包中的资源都会出错。

作者建议梳理好页面和功能再分包,分包的界限并不是包的大小超过了 2M,而是要灵活的根据业务和功能来进行划分。在如今正常网络情况下,2M 的分包和 500KB 的分包的下载可能用户感知差距不会特别大,但是如果是在弱网环境下,这两者会造成用户白屏的时间上就有很大的差距(亲身经历,可以说是掏心掏肺了)。

比如,我会将那些可以由TabBar页面直接进入且频率较高的二级页面放入一个分包,然后其他更深层次的页面或者那些不是那么重要的页面分成一个包,又或者将整个订单业务模块的页面分成一个包。

包分好了,自然不能少了【分包预下载】。可以按照官网的规则进行配置,当用户进入某个页面时,提前下载包。

2. 按需注入

小程序下载完包之后,会将打开页面所在包的全部JS合并注入,一些未访问的页面以及未用到的自定义组件也会被注入到运行环境当中。影响注入耗时和内存占用。我们希望的是当包下载完成后,只注入我们即将打开的页面的代码就行。

这也是小程序启动或跳转进入分包页面影响白屏时间的一点。

{
    "lazyCodeLoading" : "requiredComponents"
}

3. 明确 setData 的几个调用原则

小程序是以微信客户端为宿主运行的,即wxmlwxswxss都是运行在客户端的,运行环境又分成了两个线程,一个渲染线程,一个逻辑线程。渲染层使用 WebView 进行渲染, 逻辑层使用JSCore运行JS代码。wxmlwxss工作在渲染线程,而wxs工作在逻辑线程。那两个线程之间怎么通信呢?

  • 通过客户端作为中转站进行通信

渲染层触发事件响应到客户端,逻辑层通过setData传送数据到客户端,两边的数据都会被转换成字符串之后进行传输,客户端再分别做出响应,并且响应并非实时的。意味着在逻辑层触发setData页面并不会马上更新,会有一些延迟渲染层才会更新。

模型如图:

2.png

Native即客户端。

回到问题,setData在逻辑层调用,让渲染层快速响应取决于逻辑层到客户端的数据传输效率,而这个传输效率又取决于你传输数据的大小,所以在调用setData的时候应该尽可能减少数据传输大小。

Native会将wxml转换成 js对象,然后和setData传进来的对象做差异化对比,将差异化渲染到视图上。

综上原理,我们调用setData应该遵循几个原则:

  • 尽可能减小需要 setData 数据的大小,JSON.stringify后不超过 256KB
  • 避免将不需要渲染的数据(不在wxml中绑定的数据)传入setData,减少差异对比耗时。
  • 避免过于频繁调用setData,会导致逻辑层业务繁忙,一直在处理setData的传输队列,而导致抽不开身去处理渲染层的响应,从而导致渲染阻塞,页面出现卡顿,甚至setData无效。如果可以的话,可以采用节流等方式进行优化。
  • 尽可能将多个需要更新的数据合并为一次setData,减少通信过程。
  • 避免后台页面触发setData,也会占用Js线程,有可能会造成阻塞,导致真正需要setData的数据没有响应

减小setData的数据大小通常在列表场景中,通常只更新需要更新的下标:

const needRefresh = `list[${index}]`
// 写法一
setData({
    [needRefresh]: '新值'
})

// 写法二
setData({
    [`list[${index}]`]: '新值'
})

// 写法三
setData({
    'list[0]': '新值'
})

// 写法四
const needRefresh = `list[${index}].disabled`
setData({
    [needRefresh]: '新值'
})

// 写法5 更新对象
setData({
    'personal.name':'xxx'
})

如果有变量,就需要放在[]内。

4. 控制图片大小比例

图片太大会增加下载时间和内存的消耗,并且为了用户体验,应该控制图片的高宽比例,防止图片变形或者被裁切(这个问题可以根据imagemode属性进行调整)。

一个合格的图片应该满足以下两点:

  • 图片宽高乘积 。

  • 显示的高/宽与原图的高/宽不超过 15%

由于这些图片都出自 UI,所以在这一条优化上你需要做的是:拿着这两条指标去跟 UI battle。

good lucky ~ 

EnablePPA中小学绩效考核系统2.0
EnablePPA中小学绩效考核系统2.0

无论从何种情形出发,在目前校长负责制的制度安排下,中小学校长作为学校的领导者、管理者和教育者,其管理水平对于学校发展的重要性都是不言而喻的。从这个角度看,建立科学的校长绩效评价体系以及拥有相对应的评估手段和工具,有利于教育行政机关针对校长的管理实践全过程及其结果进行测定与衡量,做出价值判断和评估,从而有利于强化学校教学管理,提升教学质量,并衍生带来校长转变管理观念,提升自身综合管理素质。

下载

以上第一条就是和设备的【dpr】相关,移动端开发一定要理解【dpr】,这里就不多赘述了

我们应该合理的采用图片资源,例如在【dpr】为 2 的设备上,一个 60x60 的元素区域显示的图片为了兼顾清晰度与资源大小,图片大小不应该超过 120x120, 同理,【dpr】为 3 设备,图片应该不超过 180x180。

我们小程序的资源都放在cdn上,可以利用cdn的图片云处理功能对资源请求进行控制,我司用的七牛云和又拍云,如下:

// 七牛云
`${_src}?imageMogr2/thumbnail/!${scaleRatio}p`

// 又拍云
`${_src}!/scale/${scaleRatio}`

更多云处理功能可以挪步官网:七牛云(https://developer.qiniu.com/dora/8255/the-zoom)  和又拍云(https://help.upyun.com/knowledge-base/image/)

我们在小程序内自定义了图片组件 cus-image , 该组件会根据【dpr】对图片进行云处理。并提供了 ratio 属性灵活调整图片大小(因为运营方上传的图片可能在不同尺寸的元素区域内引用,所以需要开发人员灵活控制)。

5. 避免短时间内发起太多请求

小程序中wx.requestwx.uploadFilewx.downloadFile的发起的网络请求短时间内最大并发限制是 10 个,超过 10 个就会导致请求阻塞。而图片请求的并发最大数量为6

短时间怎么去界定呢?

  • 【网络请求】耗时超过 300ms 的请求并发数不超过 10 个(一般不会出现这个问题,如果有这个问题那可能该考虑拆分页面、拆分业务或者合并接口了。)
  • 【图片请求】同域名耗时超过 100ms 的图片请求并发数不超过 6 个

例如:300ms内发送了12个请求,其中10个请求在300ms内就请求完成了,只有2个请求超过300ms,这样是没有问题的。

【解决方案】

  • 在接口请求上我们应该尽可能的减少请求数量。
  • 图片可以设置懒加载lazy-load
  • 图标可以使用雪碧图。
  • 将图片资源拆分在多个域名下。
  • 自定义一个分片处理函数,将请求拆分成数个阶段发出。
function interelTasks(task,wait){
    this.data.timer = setInterval(()=>{
        task()
    }, wait)
}

async function task(promiseList = []){
    const result = await promise.all(promiseList)
    // do something
}

叨扰一句:有些时候在请求数量限制范围内,我们应该对没有先后顺序的接口进行并发处理,提高接口处理效率。

6. 请求耗时优化

这一点主要体现在两个方面——【接口】和【静态资源】。

【接口】基本上不应该超过1000ms,哪怕是几百毫秒也可能需要做一些优化了,基本上正常速度在10-200ms,个别接口几百也正常,大部分都应该不超过500ms(后端大佬请消消气)。

【静态资源】首先从资源的大小考虑出发,大部分资源是图片,可以参考上面的图片大小标准。其次考虑资源缓存,对于小程序而言,静态资源基本上是存放在cdn上的,设置缓存可以有效的提高客户端表现性能。

这边给大家分享一个图片压缩网站:https://tinypng.com/

7. 避免使用过大的 WXML 节点数目

建议一个页面使用少于 1000 个 WXML 节点,节点树深度少于 30 层,子节点数不大于 60 个。一个太大的 WXML 节点树会增加内存的使用,样式重排时间也会更长,影响体验。

页面的节点数包含所有子节点数,需要注意的是子节点数,若一个子节点数大于60的时候,或许你就该考虑对组件或者页面进行重新划分了。

基本功!

8. 使用骨架屏

骨架屏相信大家都不陌生,如果我们的优化手段都用尽了,页面需要加载的资源本身就比较多,那骨架屏也是我们退而求其次的最佳方案了,也算是“曲线救国“了。

实现骨架屏的方式有多种,你可以自己写一个骨架组件,也可以用一些生成骨架屏的插件。除此之外,小程序还提供了白嫖方案,开发者工具提供了自动生成骨架屏代码的能力。

详情请访问 https://developers.weixin.qq.com/miniprogram/dev/devtools/skeleton.html

9. 合理的进行组件拆分并减小data的大小

微信小程序的更新是基于组件的,自定义组件的更新只会在组件内部,这能减少差异比较带来的耗时。

控制data的大小主要是为了减少内存消耗,比如在data中定义一些图片路径的变量,如果可以,我更推荐通过background的方式去加载一些图片。

10. 滚动区域设置惯性滚动

惯性滚动会使滚动比较顺畅,在安卓下默认有惯性滚动,而在 iOS 下需要额外设置 -webkit-overflow-scrolling: touch 的样式。

11. 扩大点击元素的可点击区域

微信规定最小可点击区域应该不小于 20x20 像素。这种样式问题不多赘述了,八仙过海,各显神通。

最后

性能优化不是一个技术债务,而是需要我们在平时的迭代版本中去不断的优化或重构,团队中的成员都应该明确这一点。

性能优化不仅仅是前端的事情,是需要团队中各个不同的职责相互配合才能做好的事情,所以,如果你发现接口慢,图片大,请勇敢的提出来,并和你的同事沟通解决。事无巨细,都很重要。

还有一些更细节的优化点可以参考官网地址:

  • https://developers.weixin.qq.com/miniprogram/dev/framework/audits/audits.html

如果有什么问题欢迎留言指正。

【相关学习推荐:小程序开发教程

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

420

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

536

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

313

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

77

2025.09.10

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

340

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1503

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

625

2023.11.24

2026赚钱平台入口大全
2026赚钱平台入口大全

2026年最新赚钱平台入口汇总,涵盖任务众包、内容创作、电商运营、技能变现等多类正规渠道,助你轻松开启副业增收之路。阅读专题下面的文章了解更多详细内容。

54

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号