浏览器工作原理与实践
李兵
前盛大创新院高级研究员
立即订阅
6167 人已学习
课程目录
已完结 42 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 参透了浏览器的工作原理,你就能解决80%的前端难题
免费
宏观视角下的浏览器 (6讲)
01 | Chrome架构:仅仅打开了1个页面,为什么有4个进程?
02 | TCP协议:如何保证页面文件能被完整送达浏览器?
03 | HTTP请求流程:为什么很多站点第二次打开速度会很快?
04 | 导航流程:从输入URL到页面展示,这中间发生了什么?
05 | 渲染流程(上):HTML、CSS和JavaScript,是如何变成页面的?
06 | 渲染流程(下):HTML、CSS和JavaScript,是如何变成页面的?
浏览器中的JavaScript执行机制 (5讲)
07 | 变量提升:JavaScript代码是按顺序执行的吗?
08 | 调用栈:为什么JavaScript代码会出现栈溢出?
09 | 块级作用域:var缺陷以及为什么要引入let和const?
10 | 作用域链和闭包 :代码中出现相同的变量,JavaScript引擎是如何选择的?
11 | this:从JavaScript执行上下文的视角讲清楚this
V8工作原理 (3讲)
12 | 栈空间和堆空间:数据是如何存储的?
13 | 垃圾回收:垃圾数据是如何自动回收的?
14 | 编译器和解释器:V8是如何执行一段JavaScript代码的?
浏览器中的页面循环系统 (6讲)
15 | 消息队列和事件循环:页面是怎么“活”起来的?
16 | WebAPI:setTimeout是如何实现的?
17 | WebAPI:XMLHttpRequest是怎么实现的?
18 | 宏任务和微任务:不是所有任务都是一个待遇
19 | Promise:使用Promise,告别回调函数
20 | async/await:使用同步的方式去写异步代码
浏览器中的页面 (8讲)
21 | Chrome开发者工具:利用网络面板做性能分析
22 | DOM树:JavaScript是如何影响DOM树构建的?
23 | 渲染流水线:CSS如何影响首次加载时的白屏时间?
24 | 分层和合成机制:为什么CSS动画比JavaScript高效?
25 | 页面性能:如何系统地优化页面?
26 | 虚拟DOM:虚拟DOM和实际的DOM有何不同?
27 | 渐进式网页应用(PWA):它究竟解决了Web应用的哪些问题?
28 | WebComponent:像搭积木一样构建Web应用
浏览器中的网络 (3讲)
29 | HTTP/1:HTTP性能优化
30|HTTP/2:如何提升网络速度?
31|HTTP/3:甩掉TCP、TLS 的包袱,构建高效网络
浏览器安全 (5讲)
32 | 同源策略:为什么XMLHttpRequest不能跨域请求资源?
33 | 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?
34 | CSRF攻击:陌生链接不要随便点
35 | 安全沙箱:页面和系统之间的隔离墙
36 | HTTPS:让数据传输更安全
结束语 (1讲)
结束语 | 大道至简
课外加餐 (4讲)
加餐一|浏览上下文组:如何计算Chrome中渲染进程的个数?
加餐二|任务调度:有了setTimeOut,为什么还要使用rAF?
加餐三|加载阶段性能:使用Audits来优化Web性能
加餐四|页面性能工具:如何使用Performance?
浏览器工作原理与实践
登录|注册

24 | 分层和合成机制:为什么CSS动画比JavaScript高效?

李兵 2019-09-28
上一篇文章中我们分析了 CSS 和 JavaScript 是如何影响到 DOM 树生成的,今天我们继续沿着渲染流水线向下分析,来聊聊 DOM 树之后所发生的事情。
在前面《05 | 渲染流程(上):HTML、CSS 和 JavaScript 文件,是如何变成页面的?》文章中,我们介绍过 DOM 树生成之后,还要经历布局、分层、绘制、合成、显示等阶段后才能显示出漂亮的页面。
本文我们主要讲解渲染引擎的分层和合成机制,因为分层和合成机制代表了浏览器最为先进的合成技术,Chrome 团队为了做到这一点,做了大量的优化工作。了解其工作原理,有助于拓宽你的视野,而且也有助于你更加深刻地理解 CSS 动画和 JavaScript 底层工作机制。

显示器是怎么显示图像的

每个显示器都有固定的刷新频率,通常是 60HZ,也就是每秒更新 60 张图片,更新的图片都来自于显卡中一个叫前缓冲区的地方,显示器所做的任务很简单,就是每秒固定读取 60 次前缓冲区中的图像,并将读取的图像显示到显示器上。
那么这里显卡做什么呢?
显卡的职责就是合成新的图像,并将图像保存到后缓冲区中,一旦显卡把合成的图像写到后缓冲区,系统就会让后缓冲区和前缓冲区互换,这样就能保证显示器能读取到最新显卡合成的图像。通常情况下,显卡的更新频率和显示器的刷新频率是一致的。但有时候,在一些复杂的场景中,显卡处理一张图片的速度会变慢,这样就会造成视觉上的卡顿。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《浏览器工作原理与实践》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(21)

  • 宇宙全栈
    请问老师:既然css动画会跳过重绘阶段,则意味着合成阶段的绘制列表不会变化。但是最终得到的相邻两帧的位图是不一样的。那么在合成阶段,相同的绘制列表是如何绘制出不同的位图的?难道绘制列表是有状态的?还是绘制列表一次能绘制出多张位图?

    作者回复:
    记住一点,能直接在合成线程中完成的任务都不会改变图层的内容,如文字信息的改变,布局的改变,颜色的改变,统统不会涉及,涉及到这些内容的变化就要牵涉到重排或者重绘了。

    能直接在合成线程中实现的是整个图层的几何变换,透明度变换,阴影等,这些变换都不会影响到图层的内容。

    比如滚动页面的时候,整个页面内容没有变化,这时候做的其实是对图层做上下移动,这种操作直接在合成线程里面就可以完成了。

    再比如文章题目列子中的旋转操作,如果样式里面使用了will-change ,那么这些box元素都会生成单独的一层,那么在旋转操作时,只要在合成线程将这些box图层整体旋转到设置的角度,再拿旋转后的box图层和背景图层合成一张新图片,这个图片就是最终输出的一帧,整个过程都是在合成线程中实现的。

    2019-09-28
    4
    13
  • 早起不吃虫
    这篇文章信息量巨大,需要很多的知识储备,老师能不能提供一些课外阅读帮助理解呢,谢谢

    作者回复: 这块资料比较少,都是通过chromium源码还有blinkon上一些视频总结的。

    blinkon:https://www.youtube.com/channel/UCIfQb9u7ALnOE4ZmexRecDg

    Chromium源码: https://chromium.googlesource.com/chromium/src

    https://chromium.googlesource.com/chromium/src/+/master/docs/README.md

    不过源码看起来会比较吃力,里面充斥着大量的回调,梳理起来也是非常不轻松的

    2019-09-28
    1
    5
  • 宇宙全栈
    文中这段话中的“帧”应该改为“层”:
    这段代码就是提前告诉渲染引擎 box 元素将要做几何变换和透明度变换操作,这时候渲染引擎会将该元素单独实现一帧,等这些变换发生时,渲染引擎会通过合成线程直接去处理变换,这些变换并没有涉及到主线程,这样就大大提升了渲染的效率。

    作者回复: 嗯。多谢指正

    2019-09-28
    3
  • bai
    关于css动画和js动画效率的问题应该有点武断了,will-change只是优化手段,使用js改变transform也能享受这个属性带来的优化。既然css动画和js动画都能享受这个优化,那就不能说明css动画比js动画效率高

    作者回复: 嗯 标题是不算严谨,修订时我会做一些调整

    2019-11-20
    1
  • Angus
    题设的问题答案会不会很牵强?因为使用will-change渲染引擎会通过合成线程去处理元素的变化,所以CSS动画比JavaScript高效?不是应该从CSS动画的原理实现层面去解释吗,will-change只是让CSS动画更高效的一个API,就像JavaScript中的requestAnimationFrame也只是一个优化方案而已。
    2019-09-29
    3
    1
  • -_-_aaa
    translate3d 相比于 translate 合成线程渲染,不仅合成线程会渲染还会有调用GPU加速?
    2019-12-10
  • -_-_aaa
    Performance:使用‘ will-change: transform, opacity;‘后,主线程均匀分布,密集棱状性;GPU均匀稀疏,平均500ms一条棱;rasterizer thread1 持续paint;Summery中GPU占用一小点其它98%以上都是idle;FPS,CPU都很稳定。去掉‘ will-change: transform, opacity;‘后,主线程均匀分布,密集棱状性;GPU密集棱状形;rasterizer thread1 和 thread2 持续paint;Summery中rendering和paint占用约20%时间;FPS,CPU略微不稳定。结论:will-change可以减轻GPU负担(为什么?合成线程不用GPU?),可以减轻rasterizer 线程负担(是因为减少重绘和重排吗),减少重绘和重排,动画的针率更稳定,cpu计算更少(为什么?计算分配给别的核了?)。。。。Layers: :使用‘ will-change: transform, opacity;‘后,会合成新的层,不使用‘ will-change: transform, opacity;‘后,没有新的层。结论:不使用‘ will-change: transform, opacity;‘由于没有新的层生成,更改都会在一个层改变,所以会涉及到更多重绘和重排。Memory: 使用‘ will-change: transform, opacity;‘这个后System会更少,应该是占有系统内存会更少吧。那就尴尬了,will-change会有新图层,应该内存会增加。
    2019-12-10
  • 昆虫捕手
    老师,文中说的一副图片、一帧,指的就是一个图层?
    2019-11-27
  • 钓人的鱼
    希望老师就 重排、重绘、合成这一块弄个加餐,我自己测试出来感觉没什么变化,不知道为什么,也不知道怎么进行有针对性的分析

    作者回复: 加餐会提到一些,但是不是专门讲这几个的

    2019-11-19
  • Crack
    compositing layer中不会进行重绘重排这些操作吗?

    作者回复: 这里面执行的是合成操作,效率最高

    2019-11-13
  • 老余
    加will-change:开启动画后整个过程帧率在59.9。图层由60个排列的变为1个重叠的60层。load时间在80ms左右,fp时间在200ms左右。内存方面为2m左右。
    不加will-change:透明度变为0的时候帧率会变成40左右,随后增加到60。图层由60个排列。load时间在80ms左右,fp时间在100ms左右。内存方面为2m左右。
    2019-10-13
  • 渴望做梦
    老师,是每一个指令生成一个图层吗?
    2019-10-11
    1
  • Luke
    老师能讲解一下BFC和图层的区别与联系吗?总感觉它们之间有点相似。
    2019-10-09
    1
  • 晓小东
    打开Permance, 点击start按钮, 记录30秒内的性能监测, 发现如下区别: set-will-change(Main trhead, GPU, chrome_childIOThead, Compositor)/no-set-will-change(Main thread, Raster, GPU, chrome_childIOThead, Compositor) , 两者区别也很大, no-set-will-change中发现GPU运行了很长时间, 似乎很繁忙。 老师 我猜测是不是, 没有独立的层, 每次改变css, 每次都要整体进行raster(光栅)光栅的过程进行GPU进程通讯调用(chrome_childIOThead task也比较频繁)所以最为繁忙的为GPU, 主线程的任务看了下基本上没有差别。但是每一帧的时间明显差了好多。 我看了Life of a Pixel, 感觉还有一些懵懂(可能英文不太好吧), 老师有空是否可以结合一下, 把浏览器渲染流水线流程,在给剖析一下。
    2019-10-03
  • 晓小东
    chrome 无痕模式 开启more-tools -> Rendering -> FPS meter no-will-changes(fps:12, gpu-memory:15MB) set-will-change(fps:53, gpu-memory:4.5MB)
    2019-09-30
    1
  • 晓小东
    单独进程打开两个Tab, 一个tab设置set-will-change, 一个tab no-will-change, 打开浏览器任务管理器查看页面内存情况set-will-change:29M; no-will-change:21M; 有个疑问老师, 如果在一个Tab进行切换时当从no-will-change 到 set-will-change 再到no-will-change, 刷新发现内存变化21M -> 29M -> 29M降不下了 chrome canary版本
    2019-09-30
  • 伪装
    will-change有很多的局限性 而且浏览器兼容不是很好 在移动端 cpu开销很大
    2019-09-29
    1
  • Sobine
    老师请教一个问题,spa页面有外链到别人家的网站,新开页面报错如下,error 404—bad request .From RFC 2068 Hypertext Transfer protocol—HTTP/1.1:
    2019-09-29
  • Snow同學
    文中说:我们介绍过 DOM 树生成之后,还要经历布局、分层、绘制、合成,显示。
    1.那如何用代码检测页面第一次打开时,元素的合成和显示阶段的完?
    2.还有页面显示后,利用ajax请求会内容,在某个节点插入一段html,如何用代码检测新插入的html的合成和显示阶段完成时间?
    2019-09-29
    2
  • 易儿易
    大道至简!
    2019-09-28
收起评论
21
返回
顶部