首先要明确,按需加载虽然能提高首屏加载的速度,可是可能带来更多的界面重绘,影响渲染性能,所以要评估具体的业务场景再作决定。php
Lazyload,即延迟加载,这并非一个新的技术,在PC时代也是很是经常使用的一种性能优化手段。这个方案的原则是让屏幕外,或者不影响总体效果显示的图片、背景等资源,在界面就绪以后再进行网络加载。 css
滚屏加载是一种常见的无刷新动态加载数据的方案,一般用在列表形式数据展现中。一方面,数据不是经过翻页进行加载,这样就避免了再一次请求和渲染整个页面;另外一方面,数据显示的数量是受限的,例如第一次只请求了10条数据,也就只须要渲染这10条数据,下拉滚屏的时候,再去得到下面10条数据。html
响应式设计是如今网站设计的一个流行趋势,随着移动互联网的发展,这项技术也愈来愈受到重视。经过这项技术,咱们可以方便地控制资源的加载与显示,例如说在分辨率不一样的手机上,分别使用不一样的css,加载不一样大小的图片资源。 方案参考: http://www.poluoluo.com/jzxy/201206/167034.htmlandroid
第三方资源有的时候不可控,好比说页面统计、地图显示、分享组件等,这些第三方资源使用的时候要慎重选择,充分考察它们对于性能的影响,使用异步加载的方式进行,防止第三方资源的使用影响到页面自己的功能。css3
在加载时间较长的时候,务必要让用户明确感知到加载完成的提示,一般是在加载过程当中显示Loading的进度条,加载完成的时候隐藏它。从心理上,这会让用户有一种“期盼感”,而不至于太过枯燥。web
对于一些重量级的H5应用,例如游戏,开始前须要加载不少资源才能让后面的游戏过程更为流畅,一个带百分比进度显示的进度条就更加剧要。ajax
200是一个正常的response,咱们在浏览器中打开一个网页(后面会讲如何针对移动端进行调试),还会看到304,即命中浏览器缓存。这两种状态是正常的http status。正则表达式
30二、301跳转是常见的跳转,尤为前一种,在咱们进行鉴权的时候有时会用到,但这个作法要尽量地优化,一个页面访问,最多只进行一次302跳转便可,切忌频繁地跳转。chrome
40四、500,咱们对本身开发的代码比较注意,通常不会发生,可是有的时候,加载第三方库,尤为是第三方库中有本身load组件的操做,这时,404和500错误可能会在你不知不觉的时候发生。例如钉钉的第三方微应用中,就遇到过dojo的组件加载问题,加载的一些子组件失败了,可是又没有影响页面显示,这就很容易被忽略。后面也会再讲,如何去测试和发现这样的隐患。浏览器
若是咱们没有设置图标ico,则会加载默认的图标:域名目录下的favicon.ico。不少开发者没有注意到这一点,就会致使这个请求404或者500。
一般,咱们在应用内部打开网页,不会显示这个图标出来(除非放到浏览器中显示网页),咱们须要保证这个图标存在,尽量地小(通常4KB如下),而且设置一个较长的缓存过时时间。
显示效果较好的图片格式中,有webp、jpg和png24/32这几种常见的图片格式。通常来讲,webp的图片最小,但在iOS或者android4.0如下的系统中可能会有兼容性问题须要解决。
Jpg是咱们最常使用的方案,大小适中,解码速度快,兼容性问题也基本不存在,是咱们在H5的应用中使用起来性价比最高的方案。
Png24或png32,通常来讲,显示效果确定会比jpg更好,可是实际上人眼很难感知出来,因此在H5应用中要避免这种格式的大图片。
对于少许的图片,推荐用智图或者tinypng等工具来帮助本身选择合适的大小、格式。
在H5应用中,图片的像素要严格控制,通常来讲不建议宽度超过640px。
在html网页中,若是有多个小图片须要加载,不妨试试CSS Sprites方案,尤为是一些基本不变,大小差很少的操做类型图标。
在html或者css中,若是有相似width: **px这样的代码,就要注意看一看了,若是说图片显示的效果是宽度100px,而下载的图片倒是200px宽度,那这大小基本上就是所须要的4倍面积了,因此在H5应用中,使用图片的一个原则就是须要显示成多大,就下载多大的资源。
DataURL是用Base64的方式,将图片变成一串文本编码放入代码的方式。这种方式有好处,由于它能够减小一次http交互的请求,对于一些体积特别小的图片,或者是动态生成的图片能够考虑使用。但在H5应用中,通常状况下,咱们都是须要避免DataURL的,由于它的数据体积一般比二进制图片的格式大1/3,并且它不会被浏览器缓存,每次页面刷新都须要从新加载这部分数据。
CSS3和svg能够更好地使用GPU进行渲染加速,并且会避免增长图片资源致使的http请求增长。例如一些div的圆角效果,就彻底能够用用css来实现。
Iconfont,能够认为是一种矢量类型的操做字体。若是页面中有较多的操做图标,能够考虑使用iconfont来替代图片资源。
服务端要开启Gzip压缩。
合理设置资源的过时时间,尤为对一些静态的不须要改变的资源,将其缓存过时时间设置得长一些。
将动态资源和静态资源放置在不一样的域名下,例如图片,放在本身特定的域名下。这样的好处是,静态资源请求时,不会带上动态域名中所设置的cookie头信息,从而减小http请求的大小。
尽可能减小Cookie头信息的大小,由于这部分数据使用的是上行流量,上行带宽更小,因此传输速度更慢,所以要尽可能精简其大小。
部署CDN服务器,或者使用第三方的CDN加速服务,优化不一样地域接入网站的带宽速度。
尽可能将全部的js和css合并,减小资源请求的次数。
外联使用js和css,这样能够有效地利用缓存,避免html页面刷新后从新加载这部分代码。
压缩代码,尤为是js和css资源,压缩后的大小能够下降至原来的1/3如下,有效节约流量。
库js、css一般不会更新,可是咱们的业务js和css可能会有更新,若是命中浏览器缓存,可能会让一些新的特性不能及时展示,甚至可能致使逻辑上的冲突。
所以对于这些js、css的资源引入,最好用版本号或者更新时间来做为后缀,这样的话,后缀不变,命中缓存;后缀改变,浏览器自动更新最新的代码。
CSS要放到html代码的开头的head标签结束前。若是网页是动态生成的,那么在head代码完成后能够强制输出(例如php的flush()操做),这样的话,浏览器就会更快地解析出来head中的内容,开始下载css文件资源。
Js放到前,这样的话,js的加载不会影响初始页面的渲染。
图片设置为空的src地址,在某些浏览器中可能会致使增长一个无效的http请求,所以要避免。
可能会让页面屡次执行计算,形成卡顿等性能问题。
下降css渲染计算的成本
直接设置style属性,一方面在html代码中不利于缓存,另外一方面也不利于样式的复用,所以要避免,经过指定id或者class的方式,在css代码块中进行样式调整。
若是页面须要请求两部分以上的数据接口,建议将其合并,不然会增长一次http请求。
有的时候,服务端会把一些可有可无的数据返回回来,尤为是相似于更新时间、状态等信息,若是在客户端不影响内容的逻辑展现,不妨在接口返回的数据中直接去掉这些内容。
缓存接口数据,在一些数据新旧敏感性不高的场景下颇有做用,在非首次加载数据时候优先使用上次请求来的缓存数据,可让页面更加快速地渲染出来,而不用等待一个新的http请求结束以后再渲染。这一点咱们在后面还会再次说起。
前面的不少建议与普通的PC端web网页的开发是一致的,可是在移动互联网应用下,仅仅作到这些,可能只有60分,那么怎样才能获得80分甚至更高?
钉钉的审批微应用,使用的就是单页架构。在这种架构下,基本不存在页面跳转的等待时间,只须要执行js逻辑触发界面变化,最多进行一次网络请求,得到服务端数据,其余资源均不须要再次请求。
再快的网络交互,毕竟也是跨越了数个网络节点,所以一张图片、一个js,优化到了极致,也照样可能须要几百毫秒的时间来得到。所以想要打破这个极限,就要使用资源离线的策略。
在钉钉的微应用中,就使用了这样的一个“离线包”策略。一些固定的图片、js库等,被打包放入app中(或根据须要,在app启动的时候进行下载更新)。
微应用中,网页代码里面加载网络资源的需求,就变成了直接加载本地文件,速度天然获得再一次巨大的提高。
对于一些时效性没有那么高的数据,能够考虑将接口数据缓存。那么页面的渲染将变成这样的流程:
而非首次进入界面,流程以下:
能够看出,在非首次进入界面的时候,页面不须要等待网络数据返回,就能够进行界面渲染,渲染的初始数据来自于本地的缓存,页面能够“秒开”。而当服务端的数据返回以后,本地的渲染会再次更新,缓存也被更新。
采用这样的方案有利有弊,好处显而易见,首屏加载的速度简直太快了——静态资源来自本地,数据接口来自本地,这在2G、3G或者其余网络速度较慢的时候,也可让用户在极短的时间内就看到内容。可是这种方案也并不是万能。
有时,咱们可以经过用户的行为统计,预判出用户下一步可能进行的操做。假设,咱们统计出来针对某个微应用,用户首页渲染完成以后,大部分会点击列表中的第一个项目查看详情。那么在首页渲染完成以后,咱们就能够先预先加载第一个项目的部份内容,那么针对这部分用户,他们实际点击以后,当即就能看到新的页面中的内容。
固然,这个方式也并非在全部场景下都使用。一方面,须要作好充分的用户调研,掌握用户的使用习惯;另外一方面,对于小部分用户而言,预加载所带来的就是没必要要的流量消耗。
在功能测试中,咱们一般能够用chrome来测试不一样的分辨率下,或是不一样的设备上,网页的展示状况。在咱们作性能优化的时候,也能够用这种方式来进行调试,方便地观察在特定设备上,静态资源是否按照咱们想象的那样去加载了。
例如,咱们想看下百度首页在某个设备下的表现。 经过F12进入控制台,点击图中的短箭头标示出来的那个设备图标,而后就能够在Device和Network中选择不一样的设备和网络情况。
例如iphone5下,这个地图的图标,明显就能够看到是用iconfont来实现的效果。
固然,这个功能也仅仅是一种模拟,经过控制屏幕分辨率、UserAgent等来模拟设备请求,在实际的设备上,又该怎么查看呢?
仍是Chrome,咱们在地址栏中输入chrome://inspect (注意:Android版本须要是4.4+,而且应用中的WebView必须进行相应的调试声明配置)
在这里点击inspect,则可进入咱们熟悉的F12控制台界面,只不过debug的对象变成了咱们在手机应用中的网页。
输入performance.timing.domComplete - performance.timing.navigationStart,就能够打印出网页加载的时间,domComplete表示全部的处理都已完成而且全部的附属资源都已经下载完毕。navigationStart表示开始加载新页面。二者相减,就表明这个网页完成渲染所须要的时间了。
一样地,咱们能够在Elements tab中,debug网页,查看各个资源的使用,在Network中,看看加载了哪些资源,是否都作过了压缩。
然而,这种方式,仍是有必定缺陷。 1. 若是打开网页通过了跳转,那么咱们只能在这里看到最后一个url页面的加载状况。 2. 第一次打开页面的时候,在Network中,默认是不显示请求的详情的,当咱们选择了preserve log upon navigation以后才会捕获,所以首次进入页面的加载状况,咱们就很难得到了。
那么有没有一种方法,让咱们可以更方便地去查看首次访问时,各类资源的加载使用状况呢?
Charles Proxy,能够说是H5测试的一个神器。 它的做用是在PC端开启一个代理服务器,手机连到这个代理服务器上以后,全部的http请求就均可以在这里看得清清楚楚。通过配置证书选项,https的请求也能够正常查看。
从图中,咱们明显能够看到,有一些404的异常请求,这些都将对咱们H5应用的性能形成影响。 若是咱们发现有一些资源的Duration比较大,那这些多是服务端响应太慢,天然也能够做为咱们优化的依据。
在钉钉的测试中,造成了一套标准。
|指标项|遵循的原则|优先级|检查项|说明| |:-|:-|:---|:---|:--| |内存|内存无泄漏|P0|主功能页面反复打开,功能的重复调用,内存无泄漏| 可使用sysdump,也能够用咱们开发的perfeasy工具进行观察| | | |P1|主功能页面,持续操做,退出后,内存占用不超过总内存的5%|perfeasy| |CPU|减小无故的CPU使用|P1|灭屏,静置2分钟,在5分钟内CPU使用平均1%|adb链接后, 使用top命令| ||||主干功能正常操做CPU占用不超过60%, 持续5秒|perfeasy| |电量|避免无故电量消耗|P0|灭屏状态下,无线程持续运行|通常来讲, 静置cpu正常, 这一项就没有问题| ||||灭屏,window.setTimeout()方法中止|通常来讲, 静置cpu正常, 这一项就没有问题同上| ||||灭屏,window.setInterval()方法中止|同上| ||||ajax超时时间设置为5000ms之内|结合代码| ||||ajax无retry逻辑|结合代码| |资源|资源的正确使用|P0|是否存在资源的重复拉取|charles| |||P1|H5页面首屏总大小不超过200K|charles, chrome| |||P1|抓包检查(js/css/html)代码去除了空格/注释,JS文件变量名变成a/b等代替|charles, chrome| |||P1|H5引用的单张图片小于60K|charles, chrome
若是影响了显示质量, 可酌情调整| |流畅度|确保给到用户流畅的展现体验|P1|流畅的实时动画展现,avgFPS>=45|perfeasy| |时延|确保给到用户流畅的切换体验|P0|wifi网络下,首次进入页面onload时间<1000ms|Chrome| |时延|确保给到用户流畅的切换体验|P0|wifi网络下,首次进入页面onload时间<1000ms|Chrome| ||||wifi网络下,非首次进入页面onload时间<500ms|Chrome| ||||3G正常网络, 首次进入页面onload时间<2000ms|chrome, 树莓派模拟3G| ||||3G正常网络, 非首次进入页面onload时间<1000ms|chrome, 树莓派模拟3G|
经过charles能够方便地进行测试。 从请求监控的状况看,有一张图片超过了60KB,宽度640px,可是在应用中,实际显示的是一张小缩略图,是经过代码控制让它显示成小图的,所以修改方案很简单,将全部头像的图片均改成获取120px宽度的便可。
钉钉的教学页面
优化方案