页面的绘制时间(paint time)是每个前端开发都须要关注的的重要指标,它决定了你的页面流畅程度。而如何去观察页面的绘制时间,找到性能瓶颈,能够借助Chrome的开发者工具。css
本文主要介绍Chrome渲染分析工具 Rendering。html
如上图,按F12调出开发者工具,而后按 “ESC” 调出 Rendering 界面。前端
以上5个选项的意思以下:html5
一、Show paint rectangles 显示绘制矩形ios
二、Show composited layer borders 显示层的组合边界(注:蓝色的栅格表示的是分块)css3
三、Show FPS meter 显示 FPS 帧频web
四、Enable continuous page repainting 开启持续绘制模式 并 检测页面绘制时间chrome
五、Show potential scroll bottlenecks 显示潜在的滚动瓶颈。canvas
开启 显示绘制矩形 这个选项,能够看到绿色的框(以前的版本都是红色的框,如今改绿色了,呵呵),这个绿色的框,表示页面正在绘制的区域,便是页面正在渲染,发生绘制操做的区域。 这是用来了解滚动时页面表现的第一个指示器。浏览器
鼠标移到图片上,能够发现 css3 动画的位移,而 css3 动画的位移致使页面重绘,重绘的区域便是绿色框住的部分。细心的朋友可能会发现,这个绿色框住的部分,并不只仅就是恰好那个 div 所在的区域,而涉及到周边的位置。发生这种状况的缘由,是页面的重绘是个连带反应,会影响周边元素。
开启这个选项以后,能够作一些常规的页面交互操做,如 Slider 切换,拍拍网左侧导航 mouse over 时效果,能够看到页面效果所影响的范围。
再好比滚动页面,拍拍首页会出现一个返回顶部的按钮,滚动的时候,会发现返回顶部这个区域在不停的进行重绘,而返回顶部是 position:fixed
定位的。这也解释了为何fixed定位是最耗性能的属性之一
若是这个时候,咱们给头部的再加个 position:fixed
,而后滚动页面时,会发现整个页面都几乎是绿色框住了,这主要是全部具备 fixed 定位的元素,在页面绘制时会处于同一个渲染层级上,一头一尾的 fixed 无疑会致使整个页面进行重绘,性能很是差。
这里提到一个渲染层级的概念,webkit 内核的浏览器在进行页面绘制、渲染并最终展现在浏览器窗口上,实际上就像是 Photoshop 上的图层,不一样的图层进行叠加最后生成一个图片的过程。
这个层的详细介绍,我下一篇文章会详细介绍,这里先卖个关子。
回到以前的话题,既然绿色框住的部分表示页面重绘,那哪些操做会致使重绘呢?
主要有2大类:
一、页面滚动
二、互动操做
1).Dom 节点被 Javascript 改变,致使 Chrome 从新计算页面的 layout。
2).动画不按期更新。
3).用户交互,如 hover 致使页面某些元素页面样式的变化。
4).调整窗口大小 和 改变字体
5).内容变化,好比用户在 input 框中输入文字
6).激活 CSS 伪类,好比 :hover
7).计算 offsetWidth
和 offsetHeight
属性
8).增长或者移除样式表
影响重绘的因素不少,这里列举了部分在前端开发的过程当中常见的操做:
一、应该尽可能避免重绘,而且尽量的使绘制区域最小,以提高页面性能。
就上面拍拍网的例子,一头一尾加上fixed定位致使整个页面重绘,是不可取的。也许你分析完后之后都不敢用fixed,可是可能在实际工做中这种状况没法避免(设计师或产品经理要求)。何东西都有它适用的地方,重要的是做为前端人员,你应该可以测量并知道你写的代码所带来的性能损耗及所形成的影响。
二、同时避免组合触发。
如滚动的时候同时执行 hover 效果操做,一个例子(Expensive Scrolls),在滚动的时候同时也有可能触发页面模块的 hover 效果,而 hover 效果用了 box-shadow
、border-radius
等耗性能大的样式。从而可能致使丢帧现象。
如何去优化:技巧在于滚动时,关闭模块的 hover 效果,而后设定一个计时器,时间到了再把 hover 打开。意思是咱们保证在滚动时不去执行昂贵的互动事件重绘。当你中止动做一段时间后,咱们再将动画开启。
中文可翻译为:显示层的组合边界。
咱们知道,在页面最终是由多个“图层”渲染而成。勾上这个选项,页面上的“layer(层)”会加上一个黄色的边框显示出来,以下图的天猫首页头部所示:
其中:
使用这个工具,能够查看当前页面的layer状况,更好的发现页面不须要的 layer 将之清除。
在弄明白这个问题以前,咱们须要先了解一个 dom 元素最终是如何转变为咱们屏幕上可视的图像。在概念上讲,可简单的分为四个步骤:
能够将这个过程理解为设计师的 Photoshop 文件。在 ps 源文件里,一个图像是由若干个图层相互叠加而展现出来的。分红多个图层的好处就是每一个图层相对独立,修改方便,对单个图层的修改不会影响到页面上的其余图层。
基于 photoshop 的图层理念来理解web端的层,那么就很容易理解了。layer 存在的意义在于:用最小的代价来改变某个页面元素。
咱们能够将某个 css 动画或某个js交互效果把它抽离到一个单独的渲染层,这样能够加快渲染的效率。
<video>
元素 <canvas>
元素opacity
作 CSS 动画或使用一个动画 webkit 变换的元素在 webkit 内核的浏览器中,若是有上述状况,则会建立一个独立的 layer。
其中第一点是最经常使用的手段,好比咱们有时候给一个css效果加上 transform: translateZ(0);
,目的就是为了建立一个独立的 layer。
另外还有另一个css属性:will-change
也能实现一样的效果。
仍是拿photoshop来作比喻,一个ps文件若是有很是多的图层,那么这个文件确定是很是大的。那对于web端也是同样,建立一个新的渲染层,它得消耗额外的内存和管理资源。当在内存资源有限的设备,好比手机上,因为过多的渲染层来带的开销而对页面渲染性能产生的影响,甚至远远超过了它在性能改善上带来的好处。
举个栗子,咱们在天猫首页上加入css:* {-webkit-transform: translateZ(0);}
。 而后使用timeline能够看到,天猫的渲染耗时很是严重。
其影响的是页面渲染的最后一个环节:Composite Layers。
那么,一个合理的策略是:当且仅当须要的时候才为元素建立渲染层。
除了 rendering 里提供的 show composited layer borders 选项外,还有一个更为直观的3d图像展现:
先选中 timeline 的某一帧,而后选择下面的 layer 标签 tab,在右侧的区域就能够看到整个页面的3d图层了。
在这个视图中,你能够对这一帧中的全部渲染层进行扫描、缩放等操做,同时还能看到每一个渲染层被建立的缘由。
show fps meter能够理解为显示FPS帧频/帧数。开启这个选项后,右上角会实时显示当前页面的FPS。
先简单科普一下啥是FPS。FPS全称叫 Frames Per Second (每秒帧数)。帧数越高,动画显示的越流畅。通常的液晶显示器的刷新频率也就是 60HZ。也就是说,要想页面上的交互效果及动画流畅。那么FPS稳定在60左右,是最佳的体验。。据悉 ios上的交互效果都是60FPS呢。
记得之前作Flash游戏的时候,FPS帧数是游戏流畅度的一个重要指标。在web端,道理也是同样。
科普完毕,回到正题。chrome提供的show FPS meter选项,在咱们制做测试页面交互及动画性能时很是有用。同时它也提供了当前页面的GPU占有率给咱们。
参考:
http://www.html5rocks.com/en/tutorials/speed/unnecessary-paints/
http://www.html5rocks.com/en/tutorials/speed/layers/
https://developer.chrome.com/devtools/docs/rendering-settings