webkit浏览器渲染影响因素分析

前言:浏览器的渲染对性能影响非常大,特别是在移动端页面,在宏观上,我们可以参考雅虎那20几条军规来操作,但在微观渲染层面,实际还没有一套相对成型的理论做为依据。

本文只是抛砖引玉,带大家进入微观的优化领域,实际在渲染优化这块上,还有很多技巧及方法需要大家去挖掘。本文写的也比较凌乱,望包涵!!

先来看个chrome timeline 工具上的一个图:

rendering1

在timeline上,我们看到有6种颜色的柱子,这6个类型的柱子构建了整个webkit浏览器的渲染过程。

简单的分类一下:蓝色表示加载,黄色表示脚本执行,紫色表示计算样式及布局,绿色表示绘制合成,白色表示空闲时间,灰色表示其他时间。这里主要看的是前面三个。

如下图:

rendering2

蓝色loading包含各种资源加载,在页面初始化加载阶段可以看到蓝色部分是耗时最长的,因为正在加载资源(加载html、css、js、img、flash、mp3等。)

Chrome上各个渲染部分的实际含义:

Parse Html:

发送一个http请求,获取请求的内容,然后解析html的过程。

Recalculate Style:

重新计算样式,它计算的是Style,和Layout做的事情完全不同。Layout计算的一个元素绝对的位置和尺寸,或者说是“Compute Layout”。

Recalculate被触发的时候做的事情就是处理JavaScript给元素设置的样式而已。Recalculate Style会计算出Render 树(渲染树),然后从根节点开始进行页面渲染,将CSS附加到DOM上的过程。

任何企图改变元素样式的操作都会触发Recalculate 。同Layout一样,它也是在JavaScript执行完成后才触发的。

Layout:

计算页面上的布局,即元素在文档中的位置及大小。如上面所说,Layout计算的是布局位置信息。任何有可能改变元素位置或大小的样式都会触发这个Layout事件,如width、height

Rasterizer:

光栅化,一般的安卓手机都会进行光栅化,光栅主要是针对图形的一个栅格化过程。低端手机在这部分耗时还蛮多的。

Paint:

页面上显示东西有任何变动都会触发Paint 。包括拖动滚动条、鼠标选中文字,等这些完全不改变样式,只改变显示结果的动作都会触发Paint。

Paint的工作就是把文档中用户可见的那一部分展现给用户。Paint是把Layout和Recalculate的计算的结果直接在浏览器窗体上绘制出来,它并不实现具体的元素计算。

Image Decode:

图片解码,将图片解析到浏览器上显示的过程。

Image Resize:

图片的大小设置,图片加载解析后,若发现图片大小并不是实际的大小(CSS改变了宽高),则需要Resize。Resize越大,耗时越久,所以尽量以图片的原始大小输出。

Composite Layers:

最后合并图层,输出页面到屏幕。浏览器在渲染过程中会将一些含义特殊样式的DOM结构绘制于其他图层,有点类似于Photoshop的图层概念。一张图片在Photoshop是由多个图层组合而成,而浏览器最终显示的页面实际也是有多个图层构成的。

有哪些因素会导致新建图层:

1、进行3D或者透视变换的CSS属性

2、使用硬件加速视频解码的<video>元素

3、具有3D(WebGL)上下文或者硬件加速的2D上下文的<canvas>元素

4、组合型插件(即Flash)

5、具有有CSS透明度动画或者使用动画式Webkit变换的元素

6、具有硬件加速的CSS滤镜的元素

在CSS里面,不同的属性会触发不同的layout或者paint,所以通过JS改变css的属性时,应该考虑到这些方面。如下图:

2

再引用另外一张图来看看CSS不同属性所触发的情况:

3

关于CSS属性的一个渲染问题,可以看下表,需翻墙查看: https://docs.google.com/spreadsheet/pub?key=0ArK1Uipy0SbDdHVLc1ozTFlja1dhb25QNGhJMXN5MXc&single=true&gid=0&output=html

如何优化渲染时间

1、为了确保页面的流程,必须保证60fps内不发生2次渲染树更新。 如下图,16ms内只发生如下几个操作则是正常及正确的 :

QQ截图20140817214845

2、页面滚动时,需要避免不必要的渲染及长时间渲染。

不必要的渲染包括:

1)position:fixed

fixed定位在滚动时会不停的进行渲染,特别是如果是页面顶部有个fiexd,页面底部有个类似返回顶部的fixed,则在滚动时会整个页面进行渲染,效率非常低。可以加 transform :  translateZ(0) ; 解决。

7

2) overflow:scroll

3) hover effects

有些:hover伪类在页面滚动时会不小心就触发到,如hover效果有阴影、圆角等比较耗时的属性时,建议页面滚动时,先取消hover效果,滚动停止后再加上hover效果。这个可以通过在外层加类名进行控制。

4) touch listeners

6

长时间渲染包括:

1)复杂的CSS

2)Image Decodes

这里特别是图片的Image Decodes及 Images Resize 这2个过程在移动端是非常耗时的,如下图:

4

3)Large empty layers(大的空图层,DIV)

5

参考: https://speakerdeck.com/addyosmani/velocityconf-rendering-performance-case-studies

Chrome渲染分析之Timeline工具的使用

页面的绘制时间(paint time)是每一个前端开发都需要关注的的重要指标,它决定了你的页面流畅程度。而如何去观察页面的绘制时间,找到性能瓶颈,可以借助Chrome的开发者工具。

本文主要介绍Chrome渲染分析工具 Rendering。

/

如上图,按F12调出开发者工具,然后按“ESC”调出Rendering界面。

以上5个选项的意思如下:

  • 1、Show paint rectangles 显示绘制矩形
  • 2、Show composited layer borders 显示层的组合边界(注:蓝色的栅格表示的是分块)
  • 3、Show FPS meter 显示FPS帧频
  • 4、Enable continuous page repainting 开启持续绘制模式 并 检测页面绘制时间
  • 5、Show potential scroll bottlenecks 显示潜在的滚动瓶颈。

1、Show paint rectangles

开启 显示绘制矩形 这个选项,可以看到绿色的框(之前的版本都是红色的框,现在改绿色了,呵呵),这个绿色的框,表示页面正在绘制的区域,即是页面正在渲染,发生绘制操作的区域。 这是用来了解滚动时页面表现的第一个指示器。

鼠标移到图片上,可以发现css3动画的位移,而css3动画的位移导致页面重绘,重绘的区域即是绿色框住的部分。细心的朋友可能会发现,这个绿色框住的部分,并不仅仅就是刚好那个div所在的区域,而涉及到周边的位置。发生这种情况的原因,是页面的重绘是个连带反应,会影响周边元素。

/

开启这个选项之后,可以做一些常规的页面交互操作,如Slider切换,拍拍网左侧导航mouse over时效果,可以看到页面效果所影响的范围。

再比如滚动页面,拍拍首页会出现一个返回顶部的按钮,滚动的时候,会发现返回顶部这个区域在不停的进行重绘,而返回顶部是position:fixed定位的。这也解释了为什么fixed定位是最耗性能的属性之一

/

如果这个时候,我们给头部的再加个position:fixed,然后滚动页面时,会发现整个页面都几乎是绿色框住了,这主要是所有具有fixed定位的元素,在页面绘制时会处于同一个渲染层级上,一头一尾的fixed无疑会导致整个页面进行重绘,性能非常差。

/

这里提到一个渲染层级的概念,webkit内核的浏览器在进行页面绘制、渲染并最终展示在浏览器窗口上,实际上就像是Photoshop上的图层,不同的图层进行叠加最后生成一个图片的过程。

这个层的详细介绍,我下一篇文章会详细介绍,这里先卖个关子。

回到之前的话题,既然绿色框住的部分表示页面重绘,那哪些操作会导致重绘呢?

影响页面重绘的因素

主要有2大类:

  • 1、页面滚动
  • 2、互动操作
  • 1).Dom节点被Javascript改变,导致Chrome重新计算页面的layout。
  • 2).动画不定期更新。
  • 3).用户交互,如hover导致页面某些元素页面样式的变化。
  • 4).调整窗口大小 和 改变字体
  • 5).内容变化,比如用户在input框中输入文字
  • 6).激活 CSS 伪类,比如 :hover
  • 7).计算 offsetWidth 和 offsetHeight 属性
  • 8).增加或者移除样式表

影响重绘的因素很多,这里列举了部分在前端开发的过程中常见的操作:

1、应该尽量避免重绘,并且尽可能的使绘制区域最小,以提升页面性能。

就上面拍拍网的例子,一头一尾加上fixed定位导致整个页面重绘,是不可取的。也许你分析完后以后都不敢用fixed,但是可能在实际工作中这种情况无法避免(设计师或产品经理要求)。何东西都有它适用的地方,重要的是作为前端人员,你应该能够测量并知道你写的代码所带来的性能损耗及所造成的影响。

2、同时避免组合触发,如滚动的时候同时执行hover效果操作,一个例子(Expensive Scrolls),
在滚动的时候同时也有可能触发页面模块的hover效果,而hover效果用了box-shadow 、border-radius等耗性能大的样式。从而可能导致丢帧现象。

如何去优化:技巧在于滚动时,关闭模块的hover效果,然后设定一个计时器,时间到了再把hover打开。意思是我们保证在滚动时不去执行昂贵的互动事件重绘。当你停止动作一段时间后,我们再将动画开启。

2.show composited layer borders

/

中文可翻译为:显示层的组合边界。

我们知道,在页面最终是由多个“图层”渲染而成。勾上这个选项,页面上的“layer(层)”会加上一个黄色的边框显示出来,如下图的天猫首页头部所示:

/

其中:

  • 黄色边框:用于显示页面上的layer
  • 蓝色栅格线:表示的是分块,这些分块可以看作是比层更低一级的单位
    当然,还有其他颜色的边框线,比如图片如果单独有个layer的话,边框线是蓝色的。

使用这个工具,可以查看当前页面的layer情况,更好的发现页面不需要的layer将之清除。

layer存在的意义

在弄明白这个问题之前,我们需要先了解一个dom元素最终是如何转变为我们屏幕上可视的图像。在概念上讲,可简单的分为四个步骤:

  • 获取 DOM 并将其分割为多个层
  • 将每个层独立的绘制进位图中
  • 将层作为纹理上传至 GPU
  • 复合多个层来生成最终的屏幕图像。

可以将这个过程理解为设计师的Photoshop文件。在ps源文件里,一个图像是由若干个图层相互叠加而展示出来的。分成多个图层的好处就是每个图层相对独立,修改方便,对单个图层的修改不会影响到页面上的其他图层。

基于photoshop的图层理念来理解web端的层,那么就很容易理解了。layer存在的意义在于:用最小的代价来改变某个页面元素。

我们可以将某个css动画或某个js交互效果把它抽离到一个单独的渲染层,这样可以加快渲染的效率。

如何创建layer

  • 3D 或透视变换(perspective transform) CSS 属性
  • 使用加速视频解码的 <video> 元素
  • 拥有 3D (WebGL) 上下文或加速的 2D 上下文的 <canvas> 元素
  • 混合插件(如 Flash)
  • 对自己的 opacity 做 CSS 动画或使用一个动画 webkit 变换的元素
  • 拥有加速 CSS 过滤器的元素
  • 元素有一个包含复合层的后代节点(换句话说,就是一个元素拥有一个子元素,该子元素在自己的层里)
  • 元素有一个 z-index 较低且包含一个复合层的兄弟元素(换句话说就是该元素在复合层上面渲染)
  • 在webkit内核的浏览器中,如果有上述情况,则会创建一个独立的layer。

在webkit内核的浏览器中,如果有上述情况,则会创建一个独立的layer。

其中第一点是最常用的手段,比如我们有时候给一个css效果加上transform: translateZ(0);,目的就是为了创建一个独立的layer。

另外还有另外一个css属性:will-change也能实现同样的效果。

layer 过多带来的问题

还是拿photoshop来做比喻,一个ps文件如果有非常多的图层,那么这个文件肯定是非常大的。那对于web端也是一样,创建一个新的渲染层,它得消耗额外的内存和管理资源。当在内存资源有限的设备,比如手机上,由于过多的渲染层来带的开销而对页面渲染性能产生的影响,甚至远远超过了它在性能改善上带来的好处。

举个栗子,我们在天猫首页上加入css:* {-webkit-transform: translateZ(0);}。 然后使用timeline可以看到,天猫的渲染耗时非常严重。

/

其影响的是页面渲染的最后一个环节:Composite Layers

那么,一个合理的策略是:当且仅当需要的时候才为元素创建渲染层。

更直观的查看页面layer

除了rendering 里提供的show composited layer borders选项外,还有一个更为直观的3d图像展示:

先选中timeline的某一帧,然后选择下面的layer标签tab,在右侧的区域就可以看到整个页面的3d图层了。

/

在这个视图中,你可以对这一帧中的所有渲染层进行扫描、缩放等操作,同时还能看到每个渲染层被创建的原因。

3.show FPS meter

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/

https://developers.google.com/web/fundamentals/performance/rendering/stick-to-compositor-only-properties-and-manage-layer-count

http://www.html5rocks.com/en/tutorials/speed/layers/

https://developer.chrome.com/devtools/docs/rendering-settings

Chrome渲染分析之Rendering工具使用(1)

页面的绘制时间(paint time)是每一个前端开发都需要关注的的重要指标,它决定了你的页面流畅程度。而如何去观察页面的绘制时间,找到性能瓶颈,可以借助Chrome的开发者工具。

本文主要介绍Chrome渲染分析工具 Rendering。

如上图,按F12调出开发者工具,然后按“ESC”调出Rendering界面。

以上5个选项的意思如下:

1、Show paint rectangles 显示绘制矩形

2、Show composited layer borders 显示层的组合边界(注:蓝色的栅格表示的是分块)

3、Show FPS meter 显示FPS帧频

4、Enable continuous page repainting 开启持续绘制模式 并 检测页面绘制时间

5、Show potential scroll bottlenecks 显示潜在的滚动瓶颈。

OK,简单的翻译了下,估计这样看也不清楚是啥意思。下面以这个网站http://css3exp.com/moon/ 和 我负责的拍拍网站:http://www.paipai.com 作为基础 逐个讲解:

由于时间及篇幅关系,本文分为几篇文章进行讲解。

1、Show paint rectangles

开启 显示绘制矩形 这个选项,可以看到绿色的框(之前的版本都是红色的框,现在改绿色了,呵呵),这个绿色的框,表示页面正在绘制的区域,即是页面正在渲染,发生绘制操作的区域。 这是用来了解滚动时页面表现的第一个指示器。

鼠标移到图片上,可以发现css3动画的位移,而css3动画的位移导致页面重绘,重绘的区域即是绿色框住的部分。细心的朋友可能会发现,这个绿色框住的部分,并不仅仅就是刚好那个div所在的区域,而涉及到周边的位置。发生这种情况的原因,是页面的重绘是个连带反应,会影响周边元素。

开启这个选项之后,可以做一些常规的页面交互操作,如Slider切换,拍拍网左侧导航mouse over时效果,可以看到页面效果所影响的范围。

再比如滚动页面,拍拍首页会出现一个返回顶部的按钮,滚动的时候,会发现返回顶部这个区域在不停的进行重绘,而返回顶部是position:fixed定位的。这也解释了为什么fixed定位是最耗性能的属性之一

如果这个时候,我们给头部的再加个position:fixed,然后滚动页面时,会发现整个页面都几乎是绿色框住了,这主要是所有具有fixed定位的元素,在页面绘制时会处于同一个渲染层级上,一头一尾的fixed无疑会导致整个页面进行重绘,性能非常差。

这里提到一个渲染层级的概念,webkit内核的浏览器在进行页面绘制、渲染并最终展示在浏览器窗口上,实际上就像是Photoshop上的图层,不同的图层进行叠加最后生成一个图片的过程。

这个层的详细介绍,我下一篇文章会详细介绍,这里先卖个关子。

回到之前的话题,既然绿色框住的部分表示页面重绘,那哪些操作会导致重绘呢?

影响页面重绘的因素
主要有2大类:

1、页面滚动

2、互动操作
1).Dom节点被Javascript改变,导致Chrome重新计算页面的layout。

2).动画不定期更新。

3).用户交互,如hover导致页面某些元素页面样式的变化。

4).调整窗口大小 和 改变字体

5).内容变化,比如用户在input框中输入文字

6).激活 CSS 伪类,比如 :hover

7).计算 offsetWidth 和 offsetHeight 属性

8).增加或者移除样式表

总结
影响重绘的因素很多,这里列举了部分常见的操作,在前端开发的过程中,1、应该尽量避免重绘,并且尽可能的使绘制区域最小,以提升页面性能。

就上面拍拍网的例子,一头一尾加上fixed定位导致整个页面重绘,是不可取的。也许你分析完后以后都不敢用fixed,但是可能在实际工作中这种情况无法避免(设计师或产品经理要求)。何东西都有它适用的地方,重要的是作为前端人员,你应该能够测量并知道你写的代码所带来的性能损耗及所造成的影响。

2、同时避免组合触发,如滚动的时候同时执行hover效果操作,一个例子(Expensive Scrolls),
在滚动的时候同时也有可能触发页面模块的hover效果,而hover效果用了box-shadow 、border-radius等耗性能大的样式。从而可能导致丢帧现象。

如何去优化:技巧在于滚动时,关闭模块的hover效果,然后设定一个计时器,时间到了再把hover打开。意思是我们保证在滚动时不去执行昂贵的互动事件重绘。当你停止动作一段时间后,我们再将动画开启。

具体可参看这篇文章《Avoiding Unnecessary Paints

web移动端性能调优及16ms优化

本文只是一个索引,收集了网络上大部分关于调试及优化方面的文章,从中挑选了一些比较好的文章分享给大家。

移动端性能不及桌面浏览器性能的10分之1,特别是在android设备良莠不齐的情况下,性能显得尤为重要。感觉做移动端页面,重回了解放前电脑还是386的年代,呵呵。

国内,16ms优化,60fps指标等相关的文章非常少,大部分还是翻译国外的一些优秀文章,非常感谢这些翻译者对web前端的贡献,让我等英文盲能及时了解前沿技术哈。

在进行毫秒级的优化时,了解浏览器的工作原理非常重要,这是晋级优秀程序员的关键。就像写win客户端软件的,总会去了解一下计算机组成原理、操作系统原理等。而我们做web页面的,了解浏览器工作原理也是一样的道理

浏览器的工作原理

浏览器的工作原理:新式网络浏览器幕后揭秘

页面渲染的GPU加速技术 – 基础:WebKit软件渲染模式

Chrome 渲染优化 – 层模型

理解WebKit和Chromium: WebKit渲染基础

理解WebKit和Chromium: Chromium的GPU硬件加速

掌握调试方法

掌握调试方法比记住别人总结的结论更重要,所谓授人以鱼如授人以渔。根据实际业务发现其页面的瓶颈,才能制定对应的优化方案。

调试方法主要是使用chrome的开发者工具进行调试,学会如何使用timeline并结合Rendering选项里的内容发现性能瓶颈

【译】Android上的远程调试

【推荐】使用Chrome DevTools的Timeline和Profiles提高Web应用程序的性能

使用Chrome工具来分析页面的绘制状态

Chrome DevTools

Profiling Mobile HTML5 Apps With Chrome DevTools

浏览器自带开发工具的秘密
里面有写到本地电脑如何连接手机,通过chrome查看网页。(安装ADB插件)

Navigation Timing API

Explore and Master Chrome DevTools
几个简单的视频介绍 了解chrome devtools的相关知识

浏览器开发工具的秘密

移动端性能优化

web性能优化,其实不分PC端、移动端,优化思路及手法都是相通的,只是目前PC端,性能问题并不明显,很多时候被忽视了。
这里主要强调的是渲染优化及滚动优化,是微观层面上的毫秒级优化。

【推荐】16毫秒的优化
16毫秒的优化Web前端性能优化的微观分析

优化移动体验的HTML5技巧

开发基于web技术的高性能动画

复杂应用的 CSS 性能分析和优化建议

requestAnimationFrame for Smart Animating

前端性能优化:高频执行事件/方法的防抖
在移动端可使用requestanimationframe做优化

高性能移动端开发

rendering-without-lumps:

Gone In 60 Frames Per Second: A Pinterest Paint Performance Case Study

Web滚动性能优化实战

用HTML5实现iPad应用无限平滑滚动

滚动事件防抖和Reflow-重绘循环

改善HTML5网页性能-译

减少javascript垃圾回收

Images Slowing Down Your Site? Try This One Weird Trick!

如果以上的文章链接打不开,那估计是别人博客down掉了,你可以尝试google一下文章标题,也许会找到别人转载的文章。

我接触移动端其实并不久,很多优化知识还仅仅停留在在理论层面,并未真正实施体验过。移动端的优化路上,还有很长的路要走。

最后,丢一个我和荔枝同学一起写的PPT
若无法查看可点击链接查看