前端移动篇--页面性能优化的三两事
近几年,随着移动互联网强势崛起,越来越多的网民开始在手机上“冲浪”。各大移动厂商为了吸引用户的浏览,开始制作布局越来越复杂,效果越来越炫的移动应用产品。然而随之而来,也带来了越来越多的问题,比如:文件越来越大、下载和运行速度越来越慢等等。这些问题的影响,直接导致用户的流失率越来越高。据统计:
image.png从图中可以得知71%的用户期望移动页面跟pc页面一样快,74%的用户能容忍的响应时间为5秒,所以我们必须保证移动端页面有足够的速度。
移动页面的速度跟三个因素有关,分别是:移动网络带宽速度,设备性能(CPU,GPU,浏览器),页面本身。
作为一个开发者,用户所处的移动网络带宽环境,以及所拥有的设备是我们不能控制的。但是页面本身的大小,是我们可以通过自己的手段,去完善和提升的。
接下来我们来聊聊具体如何去优化移动端页面。
首先我们得关注一下一个页面从开始到呈现完毕需要经历什么阶段,主要有四个阶段:
(一)从图中可以明显得知,在页面加载这一环节,占据了大部分的时间。因而从加载这一环节去考虑如何去优化页面。
常规的手段有这几种 1. 预加载 2.按需加载
(1) 预加载
这种加载方式可以提升用户的体验感,让用户在等待页面加载的过程中,不会觉得那么枯燥。
(2)按需加载
image.png这种加载方式是尽量让首屏的资源记载完成,首屏以外的资源在首屏加载结束后进行记载,这样也能就节省加载的时间,提升用户体验。
(二)接下来从图片资源进行考虑。
一个移动端的页面,图片的大小还是占据一定比例的。因而我们需要对图片资源进行压缩。常用的图片压缩网站可以使用 https://tinypng.com/
然而针对不同的图片文件格式,jpg:建议使用大尺寸大有损压缩比的jpg,png:建议多彩图片使用png24、低彩图片使用png8。
(三)从点击事件的角度考虑
在移动端使用click点击事件,会存大约 300 毫秒的等待时间。为什么这么设计呢? 因为它想看看你是不是要进行双击(double tap)操作。为了让这300毫秒的等待时间消失,我们可以引入fastclick.js这个库。
(四)接下来我们从渲染的角度进行思考"重绘和重排"
浏览器下载完页面中的所有组件——HTML标记、JavaScript、CSS、图片之后会解析生成两个内部数据结构——DOM树和渲染树。
DOM树表示页面结构,渲染树表示DOM节点如何显示。DOM树中的每一个需要显示的节点在渲染树种至少存在一个对应的节点(隐藏的DOM元素disply值为none 在渲染树中没有对应的节点)。渲染树中的节点被称为“帧”或“盒",符合CSS模型的定义,理解页面元素为一个具有填充,边距,边框和位置的盒子。一旦DOM和渲染树构建完成,浏览器就开始显示(绘制)页面元素。
当DOM的变化影响了元素的几何属性(宽或高),浏览器需要重新计算元素的几何属性,同样其他元素的几何属性和位置也会因此受到影响。浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。这个过程称为重排。完成重排后,浏览器会重新绘制受影响的部分到屏幕,该过程称为重绘。由于浏览器的流布局,对渲染树的计算通常只需要遍历一次就可以完成。但table及其内部元素除外,它可能需要多次计算才能确定好其在渲染树中节点的属性,通常要花3倍于同等元素的时间。这也是为什么我们要避免使用table做布局的一个原因。
并不是所有的DOM变化都会影响几何属性,比如改变一个元素的背景色并不会影响元素的宽和高,这种情况下只会发生重绘。
提高网页性能,就是要降低"重排"和"重绘"的频率和成本,尽量少触发重新渲染。
DOM变动和样式变动,都会触发重新渲染。但是,浏览器已经很智能了,会尽量把所有的变动集中在一起,排成一个队列,然后一次性执行,尽量避免多次重新渲染。
div.style.color = 'blue';
div.style.marginTop = '30px';
上面代码中,div元素有两个样式变动,但是浏览器只会触发一次重排和重绘。
如果写得不好,就会触发两次重排和重绘。
div.style.color = 'blue';
var margin = parseInt(div.style.marginTop);
div.style.marginTop = (margin + 10) + 'px';
上面代码对div元素设置背景色以后,第二行要求浏览器给出该元素的位置,所以浏览器不得不立即重排。
重排和重绘是DOM编程中耗能的主要原因之一,平时涉及DOM编程时可以参考以下几点:
1.尽量不要在布局信息改变时做查询(会导致渲染队列强制刷新)
2.同一个DOM的多个属性改变可以写在一起(减少DOM访问,同时把强制渲染队列刷新的风险降为0)
3.将需要多次重排的元素,position属性设为absolute或fixed,这样此元素就脱离了文档流,它的变化不会影响到其他元素。例如有动画效果的元素就最好设置为绝对定位。
渲染的另一个角度,移动端的动画我们尽量使用css3进行处理,少用js。这样可以减少脚本的加载,可利用硬件进行加速,可规避渲染树的计算渲染更快。
最后总结如下:
image.png其实从任何角度的优化都是具有两面性的,比如图片压缩,在减少资源体积的同时,可能会带来图片失真的影响。按需加载提升了速度,但可能导致大量的重绘等等各方面的影响。类似的矛盾在优化过程也许碰到很多。需要根据自己业务的实际情况进行权衡考量。
谢谢以下文章进行的赞助:
http://www.cnblogs.com/zichi/p/4720000.html
http://www.jianshu.com/p/f69b476a7200