【转载】DevTools性能分析文档
https://gist.github.com/the1sky/7887088#file-devtools
DevTools性能分析文档
本文只谈性能,其它请参见devTool官方文档
Timeline解读
可以理解为接收webkit渲染过程中产生的事件,并可进行分析的平台,请按Ctrl + Shift + I,选择timeline
每一个事件在timeline中被称为一个record
查看模式
分为三个模式:事件、帧和内存,其中帧模式是最常用也是最有效的模式。
事件模式
直观查看页面在渲染过程中的事件流
一目了然的发现耗时长的事件
发现有超过16.7ms的事件,开始兴奋吧,少年!
为什么是16.7ms? 请仔细阅读帧模式

帧模式
无以伦比的强大,多个事件的组合
直观获取页面性能概况
30fps & 60fps线很有爱

什么是帧?
可以理解为一次完整的呈现,包括硬件帧和软件帧
硬件帧
想想屏幕的刷新频率,60hz/s, 其实就是1s时间内产生了60个屏幕画面
软件帧
想象下经常玩的游戏,遇到过15fps的情况?
15fps就是指在1s时间内产生了15个游戏画面
见下图:

为什么是16.7ms?
理想情况下:1000ms / 60 = 16.7ms
正常情况下:1000ms / 24 = 41.7ms
目标-------------------------------->16.7ms
超过41.7ms的帧肯定是无法容忍的
[google devtools大会上的演示]
timeline帧的组成?
在一帧内,浏览器必需要把帧的内容渲染到屏幕上,包含如下操作:
运行JS
事件处理
更新DOM
更改样式
布局(layout)
绘制(paint)
webkit内核中的帧的组合逻辑?
跟踪源代码中...
内存模式
能直观的看到性能的拐点,就是内存空间大起大落的地方
下部有对应的recording
由于内存优化暂时不是重点方向,没有进行深入的思考

timeline record
一个record对应一个事件,按类型划分包括loading、scripting、rendering和painting
loading
加载相关的事件,主要包括:
Send Request
Receieve Response
Receieve Data
Finish Loading
Parse HTML
scripting
js相关的事件,主要包括:
Evaluate Script
Function Call
Event
Timer Fired
Install Timer
Remove TImer
DOMContentLoaded
Request Anination Frame
Animation Frame Fired
Cancel Anination Frame
rendering
布局相关的事件,主要包含:
Invalidate layout
Layout
REcalculate style
scroll
painting
绘制相关的事件,主要包含:
paint
快捷键
开始记录
Ctrl + E
重新加载页面
Ctrl + R
停止记录
Ctrl + E
辅助工具
show paint rectangles
显示绘制区域
show composited layer border
显示组合层中每个层的边框
什么是composited layer会下文中详谈
Enable continuous page repainting
对调试很有帮助
show FPS meter
帧率显示,粗略看动态性能
Show potential scroll bottlenecks
[在演示性能瓶颈问题时会用到这些辅助工具]
页面渲染过程
总体是这个样子的
Html -> Dom Tree
Dom Tree -> RenderObject Tree
RenderObject Tree -> RenderLayout Tree
分支出现:
software path
hardware path

software path
传统的渲染流程
RenderLayout进行层控制
RenderObject.paint(),直接把自己绘制到一个Bitmap
这个Bitmap是在在内容中开辟的一块空间,通过Webkit/Skia的GraphicsContext
这个Bitmap就是将要用来进行呈现的屏幕内容
so, 你看到了你想看的

harewar path
也就是所谓的硬件加速
会进行 RednerLayout Tree -> GraphicsLayer Tree
引入Compositor的概念,产生能供GPU使用的指令,调用GPU的GL/D3D,传递指令及相关的Bitmap及顶点信息
不像software path只有个一个GraphicsCotext, 这里是每个GaphicsLayout对应一个GraphicsContext
因为每个假如每个RenderLayout都需要要给GraphicsLayout会造成内存的大量浪费,故只有符合特定条件的renderLayout才能有自己的GraphicsLayout, 否则只能使用其父级对象的GraphicsLayout,所谓的特定条件如下(copy自官方):
1、Layer has 3D or perspective transform CSS properties
2、Layer is used by video element using accelerated video decoding
3、Layer is used by a canvas element with a 3D context or accelerated 2D context
4、Layer is used for a composited plugin
5、Layer uses a CSS animation for its opacity or uses an animated webkit transform
6、Layer uses accelerated CSS filters
7、Layer with a composited descendant has information that needs to be in the composited layer tree, such as a clip or reflection
8、Layer has a sibling with a lower z-index which has a compositing layer (in other words the layer is rendered on top of a composited layer)
符合上述条件的RednerLay,会被称作Composited layer
Compositor所做的工作就是组合Composited layer,对应DevTools Timeline中出现的Composite Layout记录
之后,Composited layer及顶点信息和处理指令会被传递到GPU
so, 你看到了你想看的,只是相较于software_path,内部流程变了

layers
如上述渲染流程
页面渲染分层渲染的
包括普通的layout和composited layout
普通的layout直接通过browser process,并最终展示在屏幕上
composited layout通过GPU Process,直接显示在屏幕上
使用compostied的优势是很明显的,在进行repaint的时候,只需要重绘独立的一个composited layout并提交给GPU处理
其实绘制过程(即格栅化过程)都是由Skia完成,这个是有必要而且是正在进行的改进,引入了Accelerated Painting的概念,用到了Ganesh技术
Ganesh,简单讲就是能够根据render layer,记录SKPicture指令,后续通过回放这些SkPicture命令就可以来格栅化图层,这些SkPicture可以通过Ganesh产生对应的GL指令
paint和composite
这两个概念容易混淆,通过以上的内容,应该有一定的区分了
paint
就是renderLayer绘制到Bitmap
composite
当使用GPU加速时的概念
分层处理,并最终通过GPU合成处理
格栅化(插播)
上文略有提到,刚提到paint,在这里插播下
paint干的活就是格栅化的过程
矢量 ---------> 位图(Bitmap)

reflow和repaint
先看下正常的渲染绘制图:

reflow指元素style的变更引起的render tree的重构,这里的style指代的是引起元素几何属性变更的样式
width、height、margin、border和left/top等
repaint一般由reflow引起,但不一定
比如更改一个div的background-color,由于元素的几何属性没发生变化,不会发生reflow,但会repaint
切记:reflow和repaint的代价很昂贵!
聪明的浏览器
假如针对每次style的变更都进行reflow和repaint,可以想象下将会发生什么。
浏览器会进行所谓的‘批处理’
创建一个队列
保存样式变更的请求
批量执行队列内容,统一进行reflow和repaint
达到一定的时间或一定的样式变更请求次数
但是呢?
总有一些样式的请求需要立马知道元素当前的最新样式
这样就会打断浏览器处理的节奏
浏览器就这么很不情愿的进行强制reflow和repaint,这也是下面将要谈的‘强制同步布局’,绝对的性能瓶颈
什么拖慢了你的页面
强制同步布局
forced
耗时的CSS
耗时的onscroll()
耗时的event handlers
Image resize/decode
settimeout/requestAnimationFrame()
银弹
timeline指标说明
参考:
1、http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/
2、