浏览器渲染机制

71 阅读3分钟

浏览器渲染机制

我们在地址栏输入url,中间经历一系列过程(略),向服务器发送请求,服务器返回数据

  1. 解析 HTML 标签,构建 DOM 树
  2. 解析 CSS 标签,构建 CSSOM(CSS对象模型) 树
  3. 把 DOM 和 CSSOM 组合成渲染树(render tree)
  4. 在渲染树的基础上进行布局,计算每个节点的几何结构
  5. 把每个节点绘制到屏幕上(painting)

重绘 repaint 和回流 reflow

repaint 重新绘制界面发生变化的部分

reflow 重新计算元素的几何尺寸、位置

对页面进行改动,如删除 DOM 元素,会触发回流和重绘

会触发 reflow 和 repaint 的操作有

  • 添加、删除、更新 DOM 节点(reflow、repaint
  • 修改元素的margin、padding、border(reflow、repaint
  • display: none(reflow、repaint
  • visibility: hidden(repaint
  • 修改颜色、背景色(repaint

从节省性能的角度出发,

  • 尽量一次性修改样式
  • 给动画使用绝对定位和transform可以减少reflow(因为脱离普通流后,因此而变动的元素少了
  • DOM离线后修改

CSS与JS的加载

JS加载

  • 遇到script标签,如果有src发请求获取JS文件,执行JS完毕后再解析后续标签
  • JS的加载和执行会阻塞后续标签的解析
  • 页面中有多个js如何加载运行?

并行下载顺序执行。夜猫子的js会并行加载,只要js加载完成后立马执行。但是如果某个js已经下载完成,但其前一个js还没有下载执行,那么它必须等到前一个js下载执行完之后其才能执行(因为后面的js可能会用到前面的js

  • 建议把引入JS文件放在body内部的尾部,以便让DOM尽快展现,同时方便JS操作DOM

CSS加载

  • 遇到link标签,会发请求获取CSS文件,同时不影响后续标签的解析
  • CSS的加载不阻塞解析,但会阻塞渲染

不阻塞解析指不影响DOM树的构建。阻塞渲染是因为CSS未加载完成导致CSSOM树未构建完成,从而无法构建渲染树,一直处于白屏状态(白屏是指页面内容展现前的一片空白

  • 建议把引入CSS文件放置在head标签内,尽可能早的去加载CSS

async 与 defer

正常情况下JS的加载会阻止后续DOM结构的解析,并且多个JS会按顺序依次执行

<script async src="script.js"></script>

  • async 加载和渲染后续文档元素的过程将和script.js的加载与执行并行进行(异步)

<script defer src="script2.js"></script>

  • defer 加载后续文档元素的过程将和script.js 的加载并行进行(异步),但script.js 的执行要在所有元素解析完成之后执行,对多个defer的外置js按顺序执行

从URL输入到页面展现发生了什么

  1. 域名解析,得到IP
  2. 向该IP对应服务器发请求获取资源
  3. 后端返回HTML,浏览器解析HTML
  4. 遇到script标签发请求,js加载后需执行完毕才继续解析后续HTML
  5. 遇到link标签发请求获取css,同时继续解析后续HTML
  6. HTML标签解析完毕后,构建DOM树。CSS加载完毕后,构建CSSOM树,合并计算得到渲染树,渲染绘制

域名、DNS和服务器的关系