Chrome 性能调优简介

前端产品直接影响用户的体验,而用户体验上,操作的流畅性对其有着至关重要的影响。也许在PC上我们还感觉不出来强烈的卡顿,但是随着前端移动端的发展,Web 性能问题在移动端得到了急剧放大。什么才是真正的流畅呢?目前来说,与设备刷新频率保持一致,即 60fps 才可以说是真正的操作很流畅。这也是为什么大部分移动端 App 产品会选择使用原生的开发语言而非 H5 开发的一个重要原因。要知道,相对于 H5 开发,原生开发的代价高、开发效率低,而且很难做到App出了问题立马就能更新到用户端。所以,我们需要对我们的前端产品进行优化,尽量达到 60fps 的帧率,也就是说每一帧的运行时间最好不要超过 16ms。

前端性能优化是一个很大的话题,雅虎前端优化军规从宏观上告诉我们有哪些点是可以优化的,本文主要从其中的一个点,即浏览器端渲染这个微观角度上来介绍,更具体点来说,本文将结合 Chrome 调试工具来介绍常见的可优化点。

浏览器渲染基本流程

先大致地了解浏览器端渲染一个页面的基本流程。

当浏览器接收到服务器端的页面内容之后,它需要对整个 HTML 结构进行解析,形成 DOM 树;与此同时,它还需要对相应的 CSS 文件进行解析,形成 CSS 树(CSSOM)。接下来,需要结合 DOM + CSSOM,形成一个绘制树(Render Tree)。Render 树与 DOM 很像,区别在于,它不会包含 DOM 中的 head 等与渲染内容无关的结点,也不会包含 CSS 中定义为不可见的结点(对于 CSS 中定义的伪元素,如果可见,也会出现在绘制树中)。

得到绘制树之后,需要计算每个结点在页面中的位置,这一个过程称为layout(也有的称为reflow)。值得注意的是,layout 是一个计算代价相对很大的过程,它需要从根节点进行遍历,对每个可出现在页面中的节点进行位置的计算。

由于layout的过程中,我们是在一个连续的二维平面上进行的,接下来,需要将这些结果栅格化,映射到屏幕的离散二维平面上,这一过程称为 paint。paint实际上包含了两个任务:绘制(调用底层类似于Canvas的绘制API) + 栅格化(由composite线程控制,将绘制结果上传到GPU用于组合拼装页面)。Chrome调试窗口中,实心绿色框表示绘制,空心绿色框表示的是栅格化。现代浏览器为提升性能,将页面划分多个 layer,各自进行 paint 然后组合成一个页面(composite layers),可以与 PhotoShop 中的图层概念进行类比。这样做有什么好处呢?这样我们可以充分地利用 GPU 的并行处理能力,将某些 layer 传送到 GPU中进行绘制,即一系列的像素集合,并将结果传送到 CPU 中组装成一个页面。

这样我们得到的就是首次页面绘制的过程了。接下来,每一帧的过程中,又会发生什么事情呢?如下:

JavaScript => Style => Layout => Paint => Composite

每一帧中,如果 JS 动态地修改了 DOM 或 CSSOM,就会引起样式的更新,从而引起页面的 re-Layout,然后重新绘制结果并重新组装 layer。需要说明的是,并不是所有的修改都会引起上述所有的更新。如我们修改背景颜色的时候,就不会引起 Layout 的更新;但我们如果修改 width 等布局属性,则会引起上面的变化;而如果修改 transform: translate3d 这种硬件加速属性,Layout和Paint都不会更新,这会大大加速页面的性能。关于什么属性引起哪些更新,可以参考 CSS TRIGGERS

这也说明,在使用JavaScript进行动画的过程中,我们应该尽早在每一帧的开始执行 JS,这也是为什么推荐使用 requestAnimationFrame 的原因,因为它在每一帧刷新的时候都会调用,而且确保是每一帧最开始执行。

从另一个角度来看,页面生存周期内的状态及其用户可接受时间可以大致分为:加载数据(<1000ms)、响应(<100ms)、空闲期(50ms)、动画期(<16ms)。显然,我们的优化重点应该是在动画期,对于加载响应数据的优化,可以参考雅虎优化准则。接下来,我们就把我们的重点放在动画期的性能优化上,利用Chrome调试工具找出那些引起页面卡顿(Jank)的罪魁祸首。

性能优化

使用 Timeline 视图,我们可以清晰地看到每一帧执行的时间,具体发生了哪些事情,有哪些引起单帧时间过长。关于具体如何使用Timeline,这里不做介绍,毕竟它是一个实践性的东西。这里列举一下一些常见的性能问题:

  1. JavaScript 代码中出现的计算密集型任务,引起单帧时间太长。例如图像处理、对万级别的数据进行冒泡排序,显然它会导致页面直接卡顿,体验很差。这种情况下,一方面我们需要优化算法,另一方面,可以考虑使用 WebWorker 在另一个线程中进行计算。可以参考:http://www.html5rocks.com/en/tutorials/workers/basics/
  2. CSS样式的改变(不管是JS代码中改变的还是通过CSS3动画改变的):
  • CSS选择器:大量使用伪类的选择器性能会有所下降(示例:http://jsbin.com/gozula/1/quiet),这种情况下考虑选择器直接作用在子元素上,而非通过伪类来选择,推荐使用BEM形式的选择器。另外,直接设 className 性能不如 classList 设置。classList.remove(‘XXX’); classList.add(‘XXX’);
  • 某些CSS属性的更新会引起大量的 reflow,从而引起单帧时间太长。这种情况下,我们应该尽量减少或避免在动画过程中引起reflow。频繁地读取 offsetWidth, getComputedBoundingRect 等方法很容易引起 reflow 的情况。
  • 对引起reflow的CSS属性进行读写分离,避免反复的JS->style->layout->JS对页面进行多次reflow。经常看到Timeline中提示Forced Synchronous Layout就属于这种情况,这些属性可以参考 CSS TRIGGERS 网站。http://output.jsbin.com/cahapijazu/1 VS. http://output.jsbin.com/cahapijazu/2
  • CSS引起页面的大量 repaint ,这种情况很大程度上页面上大量的不必要内容被重新绘制了。当页面全堆积到了一个层(Layer)上,就会出现这种情况,will-change可用于提醒浏览器示例:http://www.html5rocks.com/static/demos/parallax/demo-1a/demo.html (优化后的结果:https://dl.dropboxusercontent.com/u/2272348/codez/parallax/demo-promo/index.html,可以把#background设置will-change属性以避免滚动时整个#background的大量repaint)和 http://output.jsbin.com/raruwi/1/quiet。另外,大量的图片 resize 操作也会引起 repaint。
     // 反复读写的例子,这种情况下我们应该先把读操作缓存起来
     for (var i = 0; i < paras.length; i++) {
        var width = block.offsetWidth;
        paras[i].style.width = width + ‘px’;
    }

推荐课程:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容