微信小程序怎样提高应用速度小技巧
作者:vicyao, 腾讯web前端开发 高级工程师
商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处。
原文链接:http://wetest.qq.com/lab/view/294.html
WeTest 导读
小程序科普类的文章已经很多了,今天这里讲的是针对小程序的优化方法,可以有效提高小程序的响应速度和用户体验。当然,开发体验也提高不少。
1、提高页面加载速度
在小程序这个环境下,怎样提高页面加载速度呢? 这个问题很大,我把问题具体一下,如何缩短从用户点击某个链接,到打开新页面的这段时间? 这里抛一个核心关键点:
从页面响应用户点击行为,开始跳转,到新页面onload事件触发,存在一个延迟,这个延迟大概在100-300ms之间(安卓响应比ios慢些)。
这个延迟说短不短,我们可以利用这段时间,预先发起新页面所需要的网络请求。这样一来,就节省了100-300ms(或者一个网络请求的时间)。
知道有这个gap后,代码如何实现呢?
说白了,就是实现一个在A页面预加载B页面数据的功能。但而这种跨页面的调用,很容易把逻辑搞复杂,将不同页面的逻辑耦合在一起。所以,我们希望将预加载的逻辑隐藏于无形中,不增加任何的页面间耦合,以及开发复杂度。
下面以腾讯视频小程序为例,讲解下技术实现。
小程序首页:

当用户点击海报图后,会执行以下代码(就一行):

接下来程序会加载播放页:

播放页主要代码:

可以看到,不管是外部页面的调用还是实际逻辑的实现都非常简洁。在第二个页面中,我们扩展了Page的生命周期函数,增加了onNavigate方法。该方法在页面即将被创建但还没开始创建的时候执行。
老司机也许会发现这里有点蹊跷。在首页点击的时候,播放页根本就没有创建,对象都不存在,怎么访问到里面的方法呢?
这里就要说下微信的页面机制。
在小程序启动时,会把所有调用Page()方法的object存在一个队列里(如下图)。每次页面访问的时候,微信会重新创建一个新的对象实例(实际上就是深拷贝)。
也就是说,在A页面在执行点击响应事件的时候,B页面的实例还没创建,这时候调用的onNavigate方法,实际上是Page对象的原型(小程序启动时候创建的那个)。
而接下来马上要被创建的B页面,又是另外一个object。所以,在onNavigate和onLoad方法中,this指针指的不是同一个对象,不能把临时数据存储在当前object身上。因此我们封装了一对全局的缓存方法,$put()和$take()。

为了通用性,Page上用到的公共的方法,比如$route、$put、$take都定义在了一个Page的基类里面。基类还同时保存了所有页面的list,这样就可以做到根据页面名调用具体页面的onNavigate方法。 当然,并不是每个页面都需要实现onNavigate方法,对于没有定义onNavigate方法的,$route函数会跳过预加载环节,直接跳转页面。所以对于开发者来说,不需要关心别的页面实现了什么,对外看来完全透明。
2、用户行为预测
在上面的例子中,我们实现了用户主动点击页面,提前加载下一页面数据的方法。而在某些场景下,用户的行为可以预测,我们可以在用户还没点击的时候就预加载下个页面的数据。让下个页面秒开,进一步提升体验的流畅性。
继续以腾讯视频小程序为例,主界面分为3个页卡(大部分小程序都会这么设计),通过简单的数据分析,发现进入首页的用户有50%会访问第二个页卡。所以预加载第二个页卡的数据可以很大程度提高用户下个点击页面的打开速度。
同样,先看看代码实现。 首页预加载频道页的姿势:

频道页的实现方法:

跟第一个例子类似,这里定义了一个$preLoad()方法,同时给Page扩展了一个onPreload事件。页面调用$preLoad()后,基类会自动找到该页面对应的onPreload函数,通知页面执行预加载操作。 跟第一个例子不同,这里预加载的数据会保存在storage内,因为用户不一定会马上访问页面,而把数据存在全局变量会增加小程序占用的内存。微信会毫不犹豫的把内存占用过大的小程序给杀掉。
也许对于大部分有app开发经验的同学来说,更普遍的做法是先让页面展示上次缓存的数据,再实时拉取新数据,然后刷新页面。这个方法在小程序上也许体验并不太好,原因是小程序的性能以及页面渲染速度都不如原生app。将一个大的data传输给UI层,是一个很重的操作。因此不建议采用这种方法。
3、减少默认data的大小
刚刚说到,页面打开一个新页面时微信会深拷贝一个page对象,因此,应该尽量减少默认data的大小,以及减少对象内的自定义属性。有图有真相:

以一个100个属性的data对象为测试用例,在iphone6上,页面的创建时间会因此增加150ms。
4、组件化方案
微信没有提供小程序的组件化方案(相信一定在实现中)。但开谈不说组件化,写再多代码也枉然。这里演示一个简单的组件化实现。
以腾讯视频播放页为例,页面定义如下:

其中,P()函数是自定义的基类。这是一个非常有用的东西,可以把所有通用的逻辑都写在基类里面,包括pv统计,来源统计,扩展生命周期函数,实现组件化等。
函数第一个参数是页面名称,作为页面的key。第二个是page对象,其中扩展了一个comps数组,里面就是所有要加载的组件。
以播放器组件/comps/player/index.js为例:

组件的定义跟一个普通Page对象一模一样,有data属性,onLoad、onShow等事件,也有页面响应的回调方法。wxml模板里定义的事件和js事件一一对应。
基类做的事情,就是把这些组件对象的属性和方法复制到Page对象上(浅拷贝)。其中data属性会merge到一起。而微信预定义的生命周期函数(包括自己扩展的),则封装成队列按序执行。比如当系统调用onLoad方法时,实际上是执行了所有组件的onLoad方法,最后再执行Page的onLoad。
以上是代码部分,至于wxml模板和wxss部分,就要手工import过去了。
wxml:

wxss:

5、其他
虽然小程序已经足够小巧,但启动速度还是有那么2-3秒,无法做到秒开。楼主尝试对小程序的启动时间做优化,但没有找到多少有价值的优化点。单个页面的初始化只需要1-2ms。也许大部分时间消耗在了微信跟服务器端通信的过程中。
所幸,腾讯提供了一个可以自主进行服务器性能测试的环境,用户只需要填写域名和简单的几个参数就可以获知自己的服务器性能情况,目前在腾讯WeTest平台可以免费使用。
腾讯WeTest服务器性能测试运用了沉淀十多年的内部实践经验总结,通过基于真实业务场景和用户行为进行压力测试,帮助游戏开发者发现服务器端的性能瓶颈,进行针对性的性能调优,降低服务器采购和维护成本,提高用户留存和转化率。
功能目前免费对外开放中,欢迎大家进入原文链接,点击下方链接体验!
微信小程序怎样提高应用速度小技巧的更多相关文章
- 微信小程序之提高应用速度小技巧
作者:vicyao, 腾讯web前端开发 高级工程师商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处. 原文链接:http://wetest.qq.com/lab/view/294.htm ...
- 微信小程序开发教程 #043 - 在小程序开发中使用 npm
本文介绍了如何在微信小程序开发中使用 npm 中包的功能,大大提高微信小程序的开发效率,同时也是微信小程序系列教程的视频版更新. 微信小程序在发布之初没有对 npm 的支持功能,这也是目前很多前端开发 ...
- 微信小程序开发公测,小程序账号申请办法攻略
11月3号晚上 10 点,微信公众平台发布公告,宣布微信小程序正式开放公测.此次小程序公测允许开发者将产品提交至微信公众平台审核,但是暂时不支持发布,也就是说普通消费者若想体验小程序,还需要等待一段时 ...
- 微信小程序开发——前端如何区分小程序运行环境
前言: 之前用vue做h5项目,对于接口请求,都是根据前端访问域名来判断运行环境,然后自动适配对应的服务器地址的.这样的好处就是在开发.测试及发布上线全程都不需要手动去改接口请求地址,只要提前配置好就 ...
- 微信小程序开发——打开另一个小程序
微信小程序打开另一个小程序,有两种方法:1.超链接:2.点击按钮. 全局配置: 跳转到其他小程序,需要在当前小程序全局配置中配置需要跳转的小程序列表,代码如下: App.json { ... &quo ...
- 微信小程序唤起其他微信小程序 / 移动应用App唤起小程序
微信小程序唤起其他微信小程序 / 移动应用App唤起小程序 1. 微信小程序唤起微信小程序 小程序唤起其他小程序很简单 先上链接 小程序跳转小程序 Navigator组件 推荐使用 小程序跳转小程序 ...
- 微信小程序——【百景游戏小攻略】
微信小程序--[百景游戏小攻略] 本次课程小项目中的图片以及文章还未获得授权!请勿商用!未经授权,请勿转载! 博客班级 https://edu.cnblogs.com/campus/zjcsxy/SE ...
- 微信小程序--简约风博客小程序(基于云开发 - 全开源)
微信小程序--简约风博客小程序(基于云开发 - 全开源) 项目启动纯属突发奇想,想看看博客小程序,例如wehalo博客小程序,但是感觉自建平台还要浪费自己的服务器算力,还没有访问量,省省吧. 本着白嫖 ...
- 微信小程序--关于加快小程序开发的几个小建议
加快小程序开发的几个小建议 1.使用 app.json创建页面 按照我们平常的开发习惯,创建一个新的页面,一般都会先创建文件夹,再创建对应page的形式,创建完成后,app.json中会自动注册该 ...
随机推荐
- Struts2的一个入门实例----登录功能
一.搭建环境与测试 1.web.xml文件,配置核心Filter 1: <?xml version="1.0" encoding="UTF-8"?> ...
- 编译安装mysql-server5.6.32手记
起因: CentOS内置源里面默认安装的Mysql-server太老旧,不支持一些新方法的调用,需要重新安装一个新版本 老版本里面有数据,不想卸载,想保留库和软件本身 机器上没有运行Docker,而且 ...
- Word常用实用知识1
Word常用实用知识1 纯手打,可能有错别字,使用的版本是office Word 2013 转载请注明出处,谢谢. 快速输入日期(含格式) [插入]--[日期] 快速输入日期和时间(快捷键) 快速 ...
- MyBatis浅尝笔记
MyBatis应属于一种轻量级的java持久层技术,它通过简单的SQL xml或注解,将数据库数据映射到接口与POJO.最近项目要用到mybatis,所以学习之后在这里做个总结,文中的示例以xml配置 ...
- Nancy简单实战之NancyMusicStore(一):准备工作和搭建项目
开发环境 OS : Windows 10 10.0.14393 IDE : Visual Studio 2015 Community With Update 3 Database : PostgreS ...
- java文件上传(单文件 多文件)与删除
/** * 文件上传--单文件 * * @param request * @param response * @param path * 文件存放路径(path为WebApp\后面的内容) * @re ...
- 【初码干货】关于.NET玩爬虫这些事
这几天在微信群里又聊到.NET可以救中国但是案例太少不深的问题,我说.NET玩爬虫简直就是宇宙第一,于是大神朱永光说,你为何不来写一篇总结一下? 那么今天就全面的来总结一下,在.NET生态下,如何玩爬 ...
- [CSS3] 学习笔记-HTML与CSS简单页面效果实例
一个简单的首页的设计: html文件: <!doctype html> <html> <head> <meta charset="UTF-8&quo ...
- web开发的性能准则(减少页面加载时间方面)
准则(概述) 减少 HTTP 请求 使用CDN加速 避免空的src或href属性值 增加过期头 启GZIP压缩 把css文件放到头部 把javascript放到尾部 避免使用css表达式 删除不使用的 ...
- We Chall-Training: Encodings I -Writeup
MarkdownPad Document html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,ab ...