浏览器工作原理与实践
李兵
前盛大创新院高级研究员
立即订阅
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?
浏览器工作原理与实践
登录|注册

23 | 渲染流水线:CSS如何影响首次加载时的白屏时间?

李兵 2019-09-26
上一篇文章中我们详细介绍了 DOM 的生成过程,并结合具体例子分析了 JavaScript 是如何阻塞 DOM 生成的。那本文我们就继续深入聊聊渲染流水线中的 CSS。因为 CSS 是页面中非常重要的资源,它决定了页面最终显示出来的效果,并影响着用户对整个网站的第一体验。所以,搞清楚浏览器中的 CSS 是怎么工作的很有必要,只有理解了 CSS 是如何工作的,你才能更加深刻地理解如何去优化页面。
本文我们先站在渲染流水线的视角来介绍 CSS 是如何工作的,然后通过 CSS 的工作流程来分析性能瓶颈,最后再来讨论如何减少首次加载时的白屏时间。

渲染流水线视角下的 CSS

我们先结合下面代码来看看最简单的渲染流程:
//theme.css
div{
color : coral;
background-color:black
}
<html>
<head>
<link href="theme.css" rel="stylesheet">
</head>
<body>
<div>geekbang com</div>
</body>
</html>
这两段代码分别由 CSS 文件和 HTML 文件构成,我们来分析下打开这段 HTML 文件时的渲染流水线,你可以先参考下面这张渲染流水线示意图:
含有 CSS 的页面渲染流水线
下面我们结合上图来分析这个页面文件的渲染流水线。
首先是发起主页面的请求,这个发起请求方可能是渲染进程,也有可能是浏览器进程,发起的请求被送到网络进程中去执行。网络进程接收到返回的 HTML 数据之后,将其发送给渲染进程,渲染进程会解析 HTML 数据并构建 DOM。这里你需要特别注意下,请求 HTML 数据和构建 DOM 中间有一段空闲时间,这个空闲时间有可能成为页面渲染的瓶颈。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《浏览器工作原理与实践》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(16)

  • Angus
    第1条:下载JavaScript文件并执行同步代码,会阻塞页面渲染
    第2条:defer异步下载JavaScript文件,会在HTML解析完成之后执行,不会阻塞页面渲染
    第3条:sync异步下载JavaScript文件,下载完成之后会立即执行,有可能会阻塞页面渲染
    第4条:下载CSS文件,可能阻塞页面渲染
    第5条:media属性用于区分设备,screen表示用于有屏幕的设备,无法用于打印机、3D眼镜、盲文阅读机等,在题设手机条件下,会加载,与第4条一致,可能阻塞页面渲染
    第6条:print用于打印预览模式或打印页面,这里不会加载,不会阻塞页面渲染
    第7条:orientation:landscape表示横屏,与题设条件一致,会加载,与第4条一致,可能阻塞页面渲染
    第8天:orientation:portrait表示竖屏,这里不会加载,不会阻塞页面渲染

    会阻塞页面的有1、3、4、5、7。我这里的问题在于是否加载CSS文件和JavaScript文件时,CSS文件一定会阻塞JavaScript代码的执行,还是说在JavaScript脚本需要使用到CSSOM能力的时候才会有这个前置依赖。
    2019-09-26
    1
    19
  • SeaYang
    老师,浏览器是不是有一个尽量快速渲染页面的机制呢?比如说,有时候打开一个网页很慢,后面慢慢地显示了样式错乱的页面,这明显是css没有加载构建完成,但是还是看到有页面出来了,只是样式有点乱。老师,能解释一下浏览器在这个过程中的一些优化措施吗?
    2019-09-27
    5
  • 老余
    script异步的属性是async,不是sync
    2019-10-13
    2
  • HB
    有个疑问,DOM tree 和 render tree 构建是同时进行的还是DOM tree和 cssom都构建完成后才构建render tree呢?看how browser works 有些没看清楚
    2019-09-26
    1
  • 极客时间
    另外styleSheets和cssom是一回事儿吗 感觉有点懵
    2019-12-10
  • 极客时间
    老师我重读文章发现一个问题 生成styleSheets是在dom解析完成之后进行的吗?还是在解析dom过程中有另外一个线程来生成styleSheets。
    2019-12-10
  • -_-_aaa
    “还可以将一些不需要在解析 HTML 阶段使用的 JavaScript 标记上 sync 或者 defer。”,这里应该是async ,我记得async和defer的作用是资源空闲时下载和自动放入body后下载,倒是不知道这两属性运用在不解析html的js上,难道是不操作dom 的js吗?
    2019-12-09
  • -_-_aaa
    “中我们提到过,当渲染进程接收 HTML 文件字节流时,会先开启一个预解析线程,如果遇到 JavaScript 文件或者 CSS 文件,那么预解析线程会提前下载这些数据。”这个预解析不是async 或defer才触发吗?
    2019-12-09
  • 🍐 🍾 🔆
    老师我想问下 如果script放在</body> 还有优化的意义么 这样就不会阻塞渲染了么

    作者回复: 依然会阻塞啊,只不过DOM会提前生成,但是渲染之前还需要等待该JS的执行完成!

    2019-12-03
    2
  • vianem
    老师求解答:


    <html>
    <head>
        <link href="theme.css" rel="stylesheet">
    </head>
    <body>
        <div>geekbang com</div>
        <script>
            while (1) {}
        </script>
        <div>geekbang com</div>
    </body>
    </html>
    按照文章中所说,dom解析应该一直被while循环阻塞,更生成不了布局树和绘制位图。但是我们还是能看到页面能显示出script标签前的内容呀。

    作者回复: 你确定能显示?

    2019-12-02
  • 昆虫捕手
    老师这里有个疑问,是所有阻塞都是会影响白屏?假如我的页面大部分是用js动态生成的,那么我先解析js操作已用的dom, 不是会比先解析html生成dom后再修改dom省力?
    2019-11-27
  • 一步
    在不考虑与解析线程的存在,CSS 资源的加载会阻塞DOM的构建吗? 构建CSSOM树会阻塞DOM树的构建吗?
    2019-10-16
  • 一步
    在渲染流水线中 构建 DOM 树和 构建 CSSOM 树是同时进行的吗? 还是CSSOM 的构建会阻塞DOM的构建,交替执行的? (这里前提是 css 的资源下载非常快,在DOM树构建完成之前就下载完成了)
    2019-10-16
  • Marvin
    因为cssom构造优先,所以先考虑css加载:没有media配置和配置了screen、landscape,3个css文件会命中,也就是4、5、7。js文件分加载和执行两部分,其中defer和async两种属性配置之后都会与dom树构造无关,也就是与渲染无关,其他的情况都会阻塞渲染,也就是1、3。总结:1、3、4、5、7会阻塞渲染。我查阅了h5规范,没有sync属性显式配置的定义,所以sync是无效属性,和1效果一致。网上有文章称,sync和defer同为异步加载和执行,区别在于,多个defer是顺序执行,多个sync是先加载完成先执行,但这个无从考证。
    2019-09-27
  • 柒月
    1 4吧 一样的资源应该只加载一次吧
    2019-09-26
  • mfist
    首先说下几个属性的含义:defer:异步下载js文件,等待domcontendloaded事件后解析执行,sync猜应该是async,异步下载js文件,下载完成后立即解析执行,media='screen' 电脑屏幕场景,media='print' 打印场景,orientation:landscope输出设备可见区域高度小于宽度;portrait 剩余场景。
    阻塞页面渲染的有1 4 5 8。
    2019-09-26
    2
收起评论
16
返回
顶部