Created
December 10, 2013 07:54
-
-
Save the1sky/7887088 to your computer and use it in GitHub Desktop.
devTools性能分析
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DevTools性能分析文档 | |
=============================== | |
本文只谈性能,其它请参见[devTool][1]官方文档 | |
[email protected] | |
---------------- | |
###Timeline解读 | |
可以理解为接收webkit渲染过程中产生的事件,并可进行分析的平台,请按Ctrl + Shift + I,选择timeline | |
每一个事件在timeline中被称为一个record | |
####查看模式 | |
分为三个模式:事件、帧和内存,其中帧模式是最常用也是最有效的模式。 | |
#####事件模式 | |
>直观查看页面在渲染过程中的事件流 | |
> | |
>一目了然的发现耗时长的事件 | |
> | |
>发现有超过16.7ms的事件,开始兴奋吧,少年! | |
>为什么是16.7ms? 请仔细阅读帧模式 | |
> | |
![enter image description here][2] | |
#####帧模式 | |
>无以伦比的强大,多个事件的组合 | |
> | |
>直观获取页面性能概况 | |
> | |
>30fps & 60fps线很有爱 | |
![enter image description here][3] | |
######什么是帧? | |
可以理解为一次完整的呈现,包括硬件帧和软件帧 | |
>硬件帧 | |
> | |
>>想想屏幕的刷新频率,60hz/s, 其实就是1s时间内产生了60个屏幕画面 | |
> | |
>软件帧 | |
>>想象下经常玩的游戏,遇到过15fps的情况? | |
> | |
>>15fps就是指在1s时间内产生了15个游戏画面 | |
见下图: | |
![enter image description here][4] | |
######为什么是16.7ms? | |
>理想情况下:1000ms / 60 = 16.7ms | |
> | |
>正常情况下:1000ms / 24 = 41.7ms | |
> | |
>目标-------------------------------->16.7ms | |
> | |
>超过41.7ms的帧肯定是无法容忍的 | |
[google devtools大会上的演示] | |
######timeline帧的组成? | |
>在一帧内,浏览器必需要把帧的内容渲染到屏幕上,包含如下操作: | |
>>运行JS | |
> | |
>>事件处理 | |
> | |
>>更新DOM | |
> | |
>>更改样式 | |
> | |
>>布局(layout) | |
> | |
>>绘制(paint) | |
> | |
>webkit内核中的帧的组合逻辑? | |
>>跟踪源代码中... | |
#####内存模式 | |
>能直观的看到性能的拐点,就是内存空间大起大落的地方 | |
> | |
>下部有对应的recording | |
> | |
>由于内存优化暂时不是重点方向,没有进行深入的思考 | |
![enter image description here][5] | |
####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 | |
![enter image description here][6] | |
#####software path | |
>传统的渲染流程 | |
> | |
>RenderLayout进行层控制 | |
> | |
>RenderObject.paint(),直接把自己绘制到一个Bitmap | |
> | |
>这个Bitmap是在在内容中开辟的一块空间,通过Webkit/Skia的GraphicsContext | |
> | |
>这个Bitmap就是将要用来进行呈现的屏幕内容 | |
> | |
>so, 你看到了你想看的 | |
![enter image description here][7] | |
#####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,内部流程变了 | |
![enter image description here][8] | |
####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) | |
![enter image description here][9] | |
####reflow和repaint | |
先看下正常的渲染绘制图: | |
![enter image description here][10] | |
>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、 | |
[1]: https://developers.google.com/chrome-developer-tools/ | |
[2]: http://dayhub.me/webkit/images/event.png | |
[3]: http://dayhub.me/webkit/images/frame.png | |
[4]: http://dayhub.me/webkit/images/frame_diff.png | |
[5]: http://dayhub.me/webkit/images/memory.png | |
[6]: http://dayhub.me/webkit/images/treeConvert.png | |
[7]: http://dayhub.me/webkit/images/software_path.png | |
[8]: http://dayhub.me/webkit/images/hardware_path.png | |
[9]: http://dayhub.me/webkit/images/rasterizer.png | |
[10]: http://dayhub.me/webkit/images/render.png |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment