浏览器页面是怎么渲染的

正如前面写的 浏览器中输入URL后会发生什么事情--超级详细版 中介绍的一样,一个 页面的渲染过程 也涉及到了 很多的东西,以及进程之间的通信

1、网络

  1. 网络进程接收到了 一个 html 文件 之后,除了会判断 content-type 之外,还会发生什么呢?
  2. 首先,要知道的是 TCP 的通讯 并不是一次性的,而是一个包一个包发过来的
  3. 网络进程也是如此,和 渲染进程建立了 通道之后,也是一个包一个包地发给渲染进程

2、渲染进程——解析

<head>
  <style>
    div{
       font-size: 20px;
    }
  </style>
</head>
<body>
  <div class="div1">div1</div>
  <script>
     document.querySelect('.div1').style.color = "red";
     document.querySelect('.div2').style.color = "red";
  </script>
  <div class="div2">div2</div>
</body>
  1. 渲染进程 在接收到 文件之后,会将页面清空,这里就会出现一个白屏的 现象
  2. 渲染进程 开始 一点一点地 解析 数据包,然后生成 dom 树
  3. 在这个过程之中,如果遇到了 内嵌的 css 或者 link 标签上的 css 外链,那么 继续 解析 dom ,并行地下载 css 以及解析 cssom
  4. 那么 是不是 css 就不会阻止  dom 的解析呢?
  5. 答案是 否定的,关键点 就在 js 上
  6. 看上面的那一段代码,可以看到,js 是可以 读取 一个  dom 的 css 的,也就是 读取到 cssom 的
  7. 而众所周知的事情是,js 执行 的时候 是会 阻止 dom 继续解析的
  8. 所以 为了 读取到 一个 dom 的css ,这个时候的 js 会等 css 加载完,cssom 也创建完毕之后,才开始执行
  9. 这里的 css 就变相的 阻止了 dom  的解析
  10. 那么问题来了,js 会完成 对 div2 的修改吗?这个时候 的 dom 还没有执行到 div2,js 自然是 读取不到 div2 的
  11. 如果遇到 js 的外链呢?
  12. 这个问题就实在是 老生常谈了
  13. 还要分情况来讨论,如 defer (告诉浏览器我完全不会操作 dom,所以会 加载文件之后,等到 DOMContentLoaded 之前 顺序执行)和 async (加载的时候 不会阻断 dom,但是 加载完成之后立即执行,这里就有可能会 阻断 dom 解析,而且 多个  async 也不是 顺序执行的) 的情况
  14. 然后 就是 将 dom 树 和 cssom 树合并,对 靠近视口的 内容 拥有较高的优先级,进行光栅化,呈现到 用户面前

3、渲染进程——渲染

这里主要讨论一下 js 动画 和 css 动画

  1. 相信有很多人 知道 css 动画是比 js 动画 要快的,那么到底 为什么快呢?
  2. 这里有很多理由,比如 js 和 dom 树之间线程的 通信,js 动画导致的 回流与重绘
  3. 讲 css 动画,要了解一个概念,那就是图层 layers
  4. 在浏览器 的一张 图片中,页面 其实是可以进行分层的
  5. 而进行了 分层的 图层 就摆脱了 全局的 回流与重绘的过程,只会 顾着自己的一亩三分地。在内容改变之后,只会 和之前的图片 一重叠,新的 页面就这样 出来了
  6. 其次,在 js 和 渲染线程之外,浏览器 又开了 一个新的 线程,那就是合成 线程,在这个线程上专门用来跑 css 动画
  7. 所以有的时候你会发现,当你的 页面卡住了,css 动画依旧能够执行下去

4、看一下 图层

下面就是百度 原本的 图层,结构还是很简单的

找到那个 bottom_layer ,可以看到 是那个 position: fixed 导致了 图层,我们可以手动的把这个 fixed 改成 absolute

可以发现,以前 箭头 指着的 bottom_layer 图层 就这样消失了

  1. 很多 css 属性 都是可以导致 图层的出现的,比如 transform,will-change 等
  2. 而且 在这个的基础上,translate3d 和 will-change 还会启动 GPU 绘制图层
  3. 这样的话,绘制的 效率自然是大大提升,比 js 动画 要强了
  4. 但是要注意的是,额外图层 的绘制 会导致 内存的 消耗,就像之前有文章 讲过的 字节码 和机器码 一样
  5. 所以 使用 图层 的方式绘制 要讲究 适当,不要什么都来一波 css 技术红利
  6. 可能会有人说 BFC 和图层之间 又是什么关系呢?
  7. position: fixed 是属于 BFC 的,但是又 属于 layers,但是 可以看到 position: absolute 是属于 BFC 的,但是 又不属于 layers ,所以 要具体情况具体分析了
  8. (不过根据我的试验,发现 好像也就 一个 fixed 会创建图层 ,有兴趣的 同学 也可以试试,并且指出我的 错误)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章