页面访问时渲染过程中 HTML、JS 的关系

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 之前写过一篇关于不同 DOM 操作结果不同的文章,那篇文章只是简单的介绍了一下 HTML 及外部资源与 JS 脚本执行的一个时机,其实这个还可以再拓展一下,比如 JS 和 DOMContentLoad

背景介绍

之前写过一篇关于不同 DOM 操作结果不同的文章,那篇文章只是简单的介绍了一下 HTML 及外部资源与 JS 脚本执行的一个时机,其实这个还可以再拓展一下,比如 JS 和 DOMContentLoaded 的关系,这也是本篇文章将要介绍的东西

HTML 与 DOM

render 树

我们请求网页时,首先是请求的 HTML 然后才是外部资源和 JS 脚本的下载,所以在顺序上是先构建的 DOM

img1.png

当构建完 DOM 树的时候,DOMContentLoaded 事件就被触发了,可能有家人们想问了,那这个 DOMContentLoaded 一定很早就被触发了吧?那我在 Chrome 上的 NetWork 里看的不是这样的,这个很久才触发的喔,那是因为你可能已经是二次访问该页面,页面已经有了缓存,而 load 和 DOMContentLoaded 最大的区别就是 load 包含加载外部资源的时间,比如图片,CSS 样式表,如果它们都被缓存了,那么两个事件触发的时间差距自然不会有太大

外部资源不会影响 DOMContentLoaded 事件触发的结果,因为它们的下载是由专门的下载线程异步下载,但是脚本会(JavaScript,JS),看下 render tree 生成的过程

HTML渲染.jpg

同步 JS

HTML 解析,遇到同步 JS 时,得让它先执行,怎么看的出来呢?下面有个小例子

<!DOCTYPE html>
<html>
  <head>
    ...
  </head>

  <body>
    <script>
      document.addEventListener("DOMContentLoaded", () => {
        console.log("出现文字");
      });
      for (let i = 0; i < 1000000000; i++) {}
      console.log("end");
    </script>
    <p>究竟什么时候解析到我呢?</p>
  </body>
</html>

<p> 元素有一段时间的延迟,才能到它展现自我,有的家人可能要问,你这个不对,你都把 <script> 塞在 <body> 里了,当然会阻塞,你试试放到尾部看看?其实像这段 JS 代码,你放在 HTML 文档的任意部分都是这样 end -> '出现文字' 的结果,把 for 循环结束的点设置的更长一点效果将更加明显,网页加载的小圈会一直转,你甚至有足够的时间打开你的控制台看它是怎么打印出来的,这其实也是白屏时间形成的一个原因

注意,这个同步 JS 其实有 下载 + 执行 两个部分,上面因为是在 HTML 中的代码,因此没有下载,可以后台开服务器,设置延时返回,比如 3s,也是会导致白屏 3s 以上然后再渲染 DOM 的内容,而且这个 JS 下载是在 DOMContentLoaded 前

<!DOCTYPE html>
<html>
  <head>
    ...
    <script src="http://localhost:8000/temp.js"></script>
  </head>

  <body>
    <p>究竟什么时候解析到我呢?</p>
  </body>
</html>

t_3.jpg

异步 JS

异步 JS 有下面几类

  1. ajax 请求
  2. worker 中的 JS

前面两种是因为,发送请求到返回这段过程中不会阻塞 HTML 的解析,而对于 worker 是因为这是一种后台任务,相当于另一个线程,不会阻塞我们的 GUI 渲染线程

总结

对于 <script> 需要下载 JS 的,会推迟 DOMContentLoaded 的触发,可以通过添加 defer 属性解决,比如

<script defer></script>

同时理解了HTML 的解析和 JS 的关系,其实可以帮助我们去优化白屏时间和进行正确 DOM 操作

参考资料

浏览器的工作原理

浏览器渲染流程

相关文章
|
13天前
|
JavaScript 前端开发 容器
用HTML DOM实现有条件地渲染网页元素(上)
用HTML DOM实现有条件地渲染网页元素(上)
|
13天前
|
存储 JavaScript 前端开发
用HTML DOM实现有条件地渲染网页元素(下)
用HTML DOM实现有条件地渲染网页元素(下)
|
1天前
|
JavaScript 前端开发
电话号码正则表达式 代码 javascript+html,JS正则表达式判断11位手机号码
电话号码正则表达式 代码 javascript+html,JS正则表达式判断11位手机号码
|
2天前
|
移动开发 前端开发 JavaScript
【HTML】HTML页面和常见标签
【HTML】HTML页面和常见标签
8 1
|
1天前
|
数据可视化 小程序 JavaScript
DIYGW可视化快速生成VUE3静态html页面
DIYGW可视化快速生成VUE3静态html页面
7 0
|
1天前
|
JavaScript
js渲染九九乘法表
js渲染九九乘法表
|
1天前
|
机器学习/深度学习 JSON JavaScript
LangChain-21 Text Splitters 内容切分器 支持多种格式 HTML JSON md Code(JS/Py/TS/etc) 进行切分并输出 方便将数据进行结构化后检索
LangChain-21 Text Splitters 内容切分器 支持多种格式 HTML JSON md Code(JS/Py/TS/etc) 进行切分并输出 方便将数据进行结构化后检索
7 0
|
13天前
|
C++ Windows
HTML+JavaScript构建C++类代码一键转换MASM32代码平台
HTML+JavaScript构建C++类代码一键转换MASM32代码平台
|
14天前
|
C++
HTML+JavaScript构建一个将C/C++定义的ANSI字符串转换为MASM32定义的DWUniCode字符串的工具
HTML+JavaScript构建一个将C/C++定义的ANSI字符串转换为MASM32定义的DWUniCode字符串的工具
|
14天前
用html+javascript打造公文一键排版系统14:为半角和全角字符相互转换功能增加英文字母、阿拉伯数字、标点符号、空格选项
用html+javascript打造公文一键排版系统14:为半角和全角字符相互转换功能增加英文字母、阿拉伯数字、标点符号、空格选项