程序猿东哥

V1

2022/10/25阅读:66主题:默认主题

细说DOMContentLoaded和onload事件

对于前端开发同学来说,DOMContentLoaded事件和onload事件或多或少都有一定的了解。但如果问到两者的区别是什么,为什么会触发该事件,可能比较模糊。本文就来一起探究这两个事件,了解他们的区别,在他们触发过程浏览器经历了什么以及两者分别在哪些场景下使用等。

概念和定义

DOMContentLoaded

又称DCL,当初始化HTML文档完全加载和解析完成之后,触发该事件。无需等待样式表、图片和iframe内容加载完成

onload

又称OL,即当前页面的HMTL、图片、JS、CSS等资源都已经加载完成之后触发该事件。

但如何理解上面的定义,还需要进一步探究。

加载/下载

是指浏览器把网页内容下载本地的过程

解析内容过程

  • 浏览器向服务器请求到了HTML文档后变开始解析,这个过程最终结果是DOM
  • 如果在解析过程中遇到CSS,则把CSS解析成CSSOM
  • 然后把DOM和CSSOM合并产生渲染数(RenderTree)
  • 有了渲染树就知道所有节点的样式,后面就会根据节点以及样式计算每个节点在浏览器中的大小和位置,这个过程就是渲染
  • 有了以上信息,就可以把内容渲染到浏览器上了

上面的解析过程,如下图所示

浏览器在解析内容的过程中,会遇到一下几点,我们需要注意

  • 遇到script 标签时,会阻塞后面内容的解析,同时会检查script的内容是否已下载,如果已下载则会执行内容
  • 如果link标签时,不会阻塞后续内容的解析,会继续解析后续的内容生产DOM树,会检查内容是否已经下载,如果已经下载则会解析成CSSOM树
  • 遇到DOM标签时,会执行DOM构建,将该DOM元素添加到文档树中

有一点我们特别主要,在body中的第一个script标签下载完成之前,浏览器会进行首次渲染,将该script标签前面的DOM树和CSSOM树合并成Render树进行渲染到浏览器中。这是页面白屏到首次渲染的时间节点,所以比较关键

HTML文档加载与页面首次渲染

下面来看一下浏览器关于解析文档的详细过程:

  1. 浏览器首先下载该页面地址的HTML内容
  2. 接着浏览器解析HTML内容为DOM结构
  3. 浏览器会开启下载线程,对文档中所有的资源按优先级排序进行下载
  4. 主线程继续解析文档,到达head节点,head里面的内容一般都是外链css和外链js
  5. 解析body。 a) 如果body里面只有DOM元素,这种情况就比较简单,页面首次渲染;b) 如果body中包含DOM元素、外链JS,当解析到外链js的时候,该js为下载到本地,则JS之前的DOM会渲染到页面,同时阻塞解析JS后面的DOM构建,即后面的DOM节点不会添加到文档的DOM树中。所以在js执行完之前,我们看不到js后面的元素;c) 如果body中包含DOM元素、CSS外链,外链css不会影响css后面DOM构建,但会阻塞浏览器渲染。也就是说外链css加载完成之前,浏览器还是白屏;d) 如果body中包含DOM元素、CSS外链、JS外链,外链JS和外链CSS的顺序会影响浏览器的渲染,明白这一点很重要。当body中js外链之前的外链css加载完成之前浏览器不会渲染。当body中的额js外链之前的css外链加载完成之后,js之前的DOM树和css树合并成渲染树,浏览器渲染出js之前的DOM结构
  6. 文档解析完毕,页面重新渲染。当前页面中引用的所有js同步代码执行完成之后,浏览器触发DOMContentLoaded事件
  7. 文档的图片资源,js代码中有异步加载的js、图片、css全部加载完毕之后,浏览器触发load事件

至此我们就了解了浏览器对文档内容渲染的全部过程,也知道DOMContentLoaded 和 onload事件的触发时机。

异步脚本

了解了解析的全过程,在过程中描述同步和异步还是有差别的,在实际优化页面过程中会用到这些能力。下面简单介绍异步的特性

async 和 defer 的区别

带有 async 和 defer 的脚本下载是和 HTML 的解析是并行的,但是脚本的执行和 UI 线程一定是是互斥的,就是我们常听到的JavaScript是单线程执行。像下面这张图所示,async 在下载完毕后的执行会阻塞 HTML 的解析。

注意,当 HTML 解析和脚本执行都完毕之后,DOMContentLoaded 才会被触发。

结尾

以上就是关于DOMContentLoaded和onload的全部内容,在深入了解这两个事件后,我们在页面性能优化过程中,才知道如何下手,去优化哪些内容。例如脚本的加载顺行,哪些脚本该放在什么位置加载,是否影响页面的首次渲染等等。以上是我的理解,如有问题可以及时沟通!

分类:

前端

标签:

前端

作者介绍

程序猿东哥
V1