当前可视化的页面优先加载完成,即在可见的屏幕范围内,内容应该毫秒时间段内完全展现。
Lazyload,即延迟加载
滚屏加载是一种常见的无刷新动态加载数据的方案,通常用在列表形式数据展示中。预先加载10条数据,也就只需要渲染这10条数据,下拉滚屏的时候,再去获得下面的10条数据。
Media Query(响应式加载)
响应式设计是现在网站设计的一个流行趋势,随着移动互联网的发展,这项技术也越来越受到重视。通过这项技术,我们能够方便地控制资源的加载与显示,例如说在分辨率不同的手机上,分别使用不同的css,加载不同大小的图片资源。
异步加载,防止第三方资源的使用影响到页面本身的功能。
第三方资源有的时候不可控,比如说页面统计、地图显示、分享组件等,这些第三方资源使用的时候要慎重选择,充分考察它们对于性能的影响,使用异步加载的方式进行,防止第三方资源的使用影响到页面本身的功能。
一个页面访问,切忌频繁地跳转。
图片的使用
显示效果较好的图片格式中,有webp、jpg和png24/32这几种常见的图片格式。一般来说,webp的图片最小,但在iOS或者android4.0以下的系统中可能会有兼容性问题需要解决。
Jpg是我们最常使用的方案,大小适中,解码速度快,兼容性问题也基本不存在,是我们在H5的应用中使用起来性价比最高的方案。
Png24或png32,一般来说,显示效果肯定会比jpg更好,但是实际上人眼很难感知出来,所以在H5应用中要避免这种格式的大图片。
对于少量的图片,推荐用智图或者tinypng等工具来帮助自己选择合适的大小、格式。
像素控制
在H5应用中,图片的像素要严格控制,一般来说不建议宽度超过640px。
小图片合并
在html网页中,如果有多个小图片需要加载,不妨试试CSS Sprites方案,尤其是一些基本不变,大小差不多的操作类型图标。
避免DataURL
DataURL是用Base64的方式,将图片变成一串文本编码放入代码的方式。这种方式有好处,因为它可以减少一次http交互的请求,对于一些体积特别小的图片,或者是动态生成的图片可以考虑使用。但在H5应用中,一般情况下,我们都是需要避免DataURL的,因为它的数据体积通常比二进制图片的格式大1/3,而且它不会被浏览器缓存,每次页面刷新都需要重新加载这部分数据。
使用图片的替代(css3, svg, iconfont)
CSS3和svg可以更好地使用GPU进行渲染加速,而且会避免增加图片资源导致的http请求增加。例如一些div的圆角效果,就完全可以用用css来实现。
Iconfont,可以认为是一种矢量类型的操作字体。如果页面中有较多的操作图标,可以考虑使用iconfont来替代图片资源。
域名/服务端部署
Gzip
服务端要开启Gzip压缩。
资源缓存,长cache
合理设置资源的过期时间,尤其对一些静态的不需要改变的资源,将其缓存过期时间设置得长一些。
分域名部署(静态资源域名)
将动态资源和静态资源放置在不同的域名下,例如图片,放在自己特定的域名下。这样的好处是,静态资源请求时,不会带上动态域名中所设置的cookie头信息,从而减少http请求的大小。
减少Cookie
尽量减少Cookie头信息的大小,因为这部分数据使用的是上行流量,上行带宽更小,所以传输速度更慢,因此要尽量精简其大小。
CDN加速
部署CDN服务器,或者使用第三方的CDN加速服务,优化不同地域接入网站的带宽速度。
代码资源
Javascript, CSS合并
尽量将所有的js和css合并,减少资源请求的次数。
外联使用js, css
外联使用js和css,这样可以有效地利用缓存,避免html页面刷新后重新加载这部分代码。
压缩html, js, css
压缩代码,尤其是js和css资源,压缩后的大小可以降低至原来的1/3以下,有效节约流量。
资源的版本更新
库js、css通常不会更新,但是我们的业务js和css可能会有更新,如果命中浏览器缓存,可能会让一些新的特性不能及时展现,甚至可能导致逻辑上的冲突。
因此对于这些js、css的资源引入,最好用版本号或者更新时间来作为后缀,这样的话,后缀不变,命中缓存;后缀改变,浏览器自动更新最新的代码。
Css位置
CSS要放到html代码的开头的head标签结束前。如果网页是动态生成的,那么在head代码完成后可以强制输出(例如php的flush()操作),这样的话,浏览器就会更快地解析出来head中的内容,开始下载css文件资源。
Js位置
Js放到前,这样的话,js的加载不会影响初始页面的渲染。
代码规范
避免空src
图片设置为空的src地址,在某些浏览器中可能会导致增加一个无效的http请求,因此要避免。
避免css表达式
可能会让页面多次执行计算,造成卡顿等性能问题。
避免空css规则
降低css渲染计算的成本
避免直接设置元素style
直接设置style属性,一方面在html代码中不利于缓存,另一方面也不利于样式的复用,因此要避免,通过指定id或者class的方式,在css代码块中进行样式调整。
服务端接口
接口合并
如果页面需要请求两部分以上的数据接口,建议将其合并,否则会增加一次http请求。
减少接口数据量
有的时候,服务端会把一些无关紧要的数据返回回来,尤其是类似于更新时间、状态等信息,如果在客户端不影响内容的逻辑展示,不妨在接口返回的数据中直接去掉这些内容。
缓存
缓存接口数据,在一些数据新旧敏感性不高的场景下很有作用,在非首次加载数据时候优先使用上次请求来的缓存数据,可以让页面更加快速地渲染出来,而不用等待一个新的http请求结束之后再渲染。这一点我们在后面还会再次提及。
★其他一些建议
合理使用css
正确使用Display属性 Display属性会影响页面的渲染,因此请合理使用
display:inline后不应该再使用width、height、margin、padding以及float
display:inline-block后不应该再使用float
display:block后不应该再使用vertical-align
display:table-*后不应该再使用margin或者float
不滥用float
不声明过多的font-size
值为0时不需要单位
标准化各种浏览器前缀
无前缀应放在最后
CSS动画只用 (-webkit- 无前缀)两种即可
其它前缀为 -webkit- -moz- -ms- 无前缀 四种,(-o-Opera浏览器改用blink内核,所以淘汰)
选择器
避免让选择符看起来像是正则表达式。高级选择器不容易读懂,执行耗时也长
尽量使用ID选择器
尽量使用css3动画
资源加载
使用srcset
首次加载不超过1024KB(或者可以说是越小越好)
html和js
减少重绘和回流
缓存dom选择和计算
缓存列表.length
尽量使用事件代理,避免批量绑定事件
使用touchstart,touchend代替click
Html使用viewport
减少dom节点
合理使用requestAnimationFrame动画代替setTimeOut
适当使用Canvas动画
TouchMove, Scroll事件会导致多次渲染
单页应用
钉钉的审批微应用,使用的就是单页架构。在这种架构下,基本不存在页面跳转的等待时间,只需要执行js逻辑触发界面变化,最多进行一次网络请求,获得服务端数据,其他资源均不需要再次请求。
资源离线
再快的网络交互,毕竟也是跨越了数个网络节点,因此一张图片、一个js,优化到了极致,也照样可能需要几百毫秒的时间来获得。因此想要打破这个极限,就要使用资源离线的策略。
在钉钉的微应用中,就使用了这样的一个“离线包”策略。一些固定的图片、js库等,被打包放入app中(或根据需要,在app启动的时候进行下载更新)。
微应用中,网页代码里面加载网络资源的需求,就变成了直接加载本地文件,速度自然得到再一次巨大的提升。