Análisis de documentos y tiempo de activación de DOMContentLoaded

Introducción Todo el mundo sabe que una vez que el documento HTML está completamente cargado y analizado, se activará el evento DOMContentLoaded, entonces, ¿cómo afecta el contenido del HTML al análisis del documento? ¿Se verá afectado el análisis cuando se encuentren etiquetas de script o etiquetas de enlace durante el análisis? Analicémoslo junto con la especificación HTML5 a través de ejemplos de diferentes situaciones.

Definición de disparador DOMContentLoaded

Después de que el documento HTML esté completamente cargado y analizado, se activará el evento DOMContentLoaded. Por lo general, la hoja de estilo externa y la carga de imágenes en el documento no afectarán la activación del evento, pero hay casos especiales, que mencionaremos más adelante.

Si se encuentra una etiqueta de secuencia de comandos, detendrá el análisis del documento y ejecutará la secuencia de comandos, ya que la secuencia de comandos puede cambiar el DOM, como algunas operaciones document.write, pero la etiqueta de secuencia de comandos con el conjunto de atributos asíncronos no afectará la activación del evento.

El siguiente es un análisis detallado del tiempo de activación de DOMCOntentLoaded en algunos escenarios.

etiqueta de secuencia de comandos

El comportamiento de análisis del documento será diferente dependiendo de las diferentes configuraciones de atributos de la etiqueta del script,

La parte sobre el atributo de la etiqueta del script en la especificación HTML5:  html.spec.whatwg.org/multipage/s…

Las principales propiedades async y defer son:

  1. asíncrono: cuando el script esté disponible, se ejecutará de inmediato y el análisis no se bloqueará en el proceso de solicitud de recursos. Una vez completada la solicitud de recursos, si el documento no se ha analizado en este momento, se bloqueará el análisis. Solo si la solicitud del script lleva más tiempo que el tiempo de análisis del documento, no afectará
  2. diferir: diferir la ejecución del script para garantizar que el análisis del documento no se bloquee, lo que significa que incluso si el script se completa desde la solicitud de red, no se ejecutará inmediatamente, solo después de que se complete el análisis del documento.

Los valores de sus atributos son todos booleanos y solo son válidos si el atributo src está presente.

El gráfico de tiempo de análisis que se ve en la especificación es muy claro. La línea roja representa el análisis de secuencias de comandos, la verde representa el análisis de html y la azul representa las solicitudes de recursos de red.

没设置属性的时候,script 标签在请求和执行的时候都会阻塞文档解析。defer 和 async 属性设置后,请求阶段不会影响解析,但是 async 的标签会立即执行,影响解析。后面 type="module" 的情况跟上面相同。

总结一下,文档里面 script 标签,在两种情况下不会影响文档解析:

  1. 设置了 defer 属性
  2. 设置了 async 属性,并且脚本请求完成时,文档已经解析完成了

外部样式表

样式表通常不会影响 html 文档解析。

浏览器的工作原理文章里面,提到样式表理论上不会改变 DOM 树,因此 html 解析的时候不会等待样式表。

但是脚本在文档解析阶段去请求样式信息,此时还没有加载和解析样式,脚本就会得到错误的结果。所以是否影响文档解析这里要区分一下样式表的不同情况。

1. 样式表后面紧跟着 script 脚本

<html lang=en>
 <head>
     <link rel="stylesheet" href="//8.idqqimg.com/edu/assets/css/common_css_e582a1d4.css">
     <script>console.log(121212)</script>
 </head>
 <body>
   <p>23233</p>
 </body>
</html>
复制代码

从 chrome 开发者工具里面的 Performance 分析看:

蓝色竖线 DCL,表示触发 DOMContentLoaded 时刻, 也就是说在 css 加载完成后触发的。

蓝色 Parse Stylesheet 部分,表示解析前面下载完成的样式表。

黄色 Evaluate Script 部分,执行脚步,从下面的 Summary 可以定位到刚好是第 4 行执行 console.log。

这种情况下是影响了文档解析。

2. 样式表后面没有 script 脚本

<html lang=en>
 <head>
     <script>console.log(121212)</script>
     <link rel="stylesheet" href="//8.idqqimg.com/edu/assets/css/common_css_e582a1d4.css">
 </head>
 <body>
   <p>23233</p>
 </body>
</html>
复制代码

还是从 Performance 分析:

蓝色竖线DCL几乎与css网络请求同时进行的,可以肯定样式加载没有影响到文档解析。

总结一下,通过上面两种页面,在Performance工具里面的DCL指标线,可以非常明显的看出来,外部样式表在某种情况也会影响页面解析,后面我们从HTML5规范里面找到一些说明。

HTML5 规范

文档解析部分,直接看最后解析结束部分,html.spec.whatwg.org/multipage/p…

到文档解析后面,主要看看几个步骤,到第三步:

第 3 步,update document readiness 主要更新当前文档的 readyState 值,触发 readystatechange 事件

第 5 步,遍历所有待执行的 script 列表并执行,这里提到了 has no style sheet that is blocking scripts,必须是没有阻塞脚本的样式表存在才会去执行 script。

第 6 步,才会去触发 DOMContentLoaded 事件。

再到前面 script 脚本执行部分,html.spec.whatwg.org/multipage/p…

到 otherwise 里面,脚本执行会阻止文档解析,如果脚本没有被设置 "ready to be parser-executed" 或者文档中存在阻止脚本执行的样式表,脚本执行也不会进行下去了。从这条解析路线看,的确会出现样式表阻止文档解析的情况。

但是,不一定会一直等待样式表加载。再到 a style sheet that is blocking scripts 具体定义部分:

html.spec.whatwg.org/multipage/s…

用户代理可以随时主动放弃加载样式表,提示部分提到了样式表改变元素颜色成绿色,但是如果脚本在样式表加载之前就去获取颜色,就会得到默认的黑色,影响整个页面效果。实现者必须要权衡脚本获取到错误的样式和在等待缓慢网络请求时没有执行任何解析的性能影响之间的平衡。当然这也可以是页面性能优化的一点。

最后

为什么要分析影响文档加载的因素呢?肯定是为了更好的优化页面加载性能。

分别从优化 Javascript 加载和 CSS 发送两个角度分析,进行优化,具体优化建议可以看下面链接文章。

Artículo de referencia

Supongo que te gusta

Origin juejin.im/post/7087908022378299400
Recomendado
Clasificación