JavaScript 是现代 Web 开发中不可或缺的一部分,它能够赋予网页动态化和交互性。但是,由于 JavaScript 代码的执行需要依赖于加载顺序,因此在编写前端代码时,了解 JavaScript 加载顺序是非常重要的。
当浏览器加载一个网页时,它会按照以下顺序处理 JavaScript 文件:
- 解析 HTML 和 CSS,构建 DOM 和 CSSOM。
- 加载并执行所有
<script>
标签中的同步脚本代码。 - 在 DOM 构建完成后,按照它们出现在文档中的顺序异步加载和执行所有
<script>
标签中的代码。 - 当所有异步脚本都下载完毕后,按照它们下载完成的顺序执行它们。
需要注意的是,如果两个文件都是同步加载的,则它们的执行顺序与它们在文档中的顺序相同。而异步加载的文件则无法保证它们的执行顺序,因为它们的下载和执行是由浏览器自己管理的。
以下是一个简单的示例,展示了 JavaScript 加载顺序的影响(请将以下代码保存为 .html
文件并在浏览器中打开):
-- -------------------- ---- ------- --------- ----- ------ ------ ----- ---------------- ----------------- -------------- ------- ------ ---- --------------------- -------- ----- -- - ------------------------------------- ---------------- --------- ------- -------------- --------------- ------- -------------- --------------- ------- -------
在这个示例中,我们有一个同步脚本和两个异步脚本。其中 async.js
和 defer.js
中都包含了类似于下面的代码:
const el = document.getElementById('container'); console.log(el);
这段代码尝试获取一个名为 container
的元素,并将它打印到控制台上。
现在我们来解释一下这个示例中发生了什么。
首先,浏览器会解析 HTML 和 CSS,并构建出 DOM 和 CSSOM。在这个过程中,我们的同步脚本被立即加载并执行,因此它能够正常获取到 container
元素并将它打印到控制台上。
接着,浏览器异步加载了 async.js
和 defer.js
。由于 async.js
被标记为 async
,因此它的下载和执行是独立于其他资源的。因此,在 async.js
加载完成之前,defer.js
已经下载完成并开始等待 DOM 构建完成后执行。当 DOM 构建完毕后,defer.js
被执行。此时 async.js
还没有下载完成,因此它的代码在这里不会被执行。
最后,当 async.js
下载完成后,它会立即执行。由于它是异步加载的,因此它的执行顺序无法确定,但是我们可以确定的是它的执行一定在 defer.js
之后。
总结
了解 JavaScript 加载顺序对于编写高效、可靠的前端代码非常重要。它可以帮助我们避免一些常见的错误,例如在 DOM 构建未完成时尝试访问元素和依赖于脚本的执行顺序。记住以下几点:
- 同步脚本在 HTML 解析期间执行,异步脚本在 HTML 解析完成后异步加载并执行;
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/30330