1 HTML、CSS和JS的加载过程

  • 整体过程包括解析HTML(生成DOM树)、下载CSS解析CSS(生成CSS树)、下载JS执行JS五部分。

image-20211111103307626

2 HTML的解析被JS阻塞

  • JS的下载与执行会阻塞HTML的解析
  • 执行JS会阻塞HTML原因:JS的执行存在修改DOM树结构的情况
  • 下载JS会阻塞HTML的原因:浏览器一般情况下是解析到script标签才会去下载(并没有做特殊优化),一旦下载,就必须等待其执行完毕

3 async和defer的区别

3.1 defer

  • defer可以使得JS的下载与HTML的解析同时进行,能够保证JS的执行是在HTML解析之后、DOM ready事件之前
  • 若有多个defer,则执行顺序以标签的前后顺序为准

3.2 async

  • async也可以使JS的下载与HTML的解析同时进行,但在解析HTML结束后就触发DOM ready事件,也就是说将JS的下载与执行过程完全与HTML的解析分离。所以async常用于与页面DOM结构毫无关系的(比如一些纯计算的函数)JS解析过程。
  • 若有多个async,则执行顺序以下载完成的先后顺序为准
  • JS的下载与执行过程与HTML的解析过程的关系图:

image-20211111093205174

  • 实际工作中defer>async

4 JS的执行被CSS阻塞

  • HTML的解析与CSS的下载和解析过程不会互相影响
  • CSS的下载与解析完成后,才能去执行JS。也就是说,CSS的下载与解析过程阻塞了JS的执行过程
  • 原因:JS可能会需要读取CSS的结果(比如元素宽高)

5 页面渲染原理

  • HTML解析完成后生成DOM树(DOM),CSS解析完成后生成CSS树(CSSOM)。两颗树的示意图如下:

image-20211111095024919

image-20211111095305581

  • 两个对象模型会将HTML结构与CSS样式合成一个”渲染树“

image-20211111095452178

  • 渲染树生成后,还要经历布局(Layout)绘制(Paint)合成(Composite)三个步骤

  • 当页面更新时(例如修改div的宽高),会触发浏览器的重排(reflow)重绘(repaint)(全部改变都会涉及到重新合成)

具体哪些属性的修改会导致reflow或者repaint详见https://csstriggers.com/