CSS、JavaScript 和阻塞网页解析 加载 CSS 资源是否会阻塞页面解析?加载和执行 JS 代码是否会阻塞页面解析?正常的脚本加载和执行 实验

2025-05-26

CSS、JavaScript 和阻止网页解析

加载CSS资源会阻塞页面解析吗?

加载并执行JS代码会阻塞页面解析吗?

正常脚本加载和执行

实验

最近,我偶然看到一篇关于 CSS 文件加载问题的文章,这个问题会降低页面素材的处理速度。我读了这篇文章,想学习一些新知识,但我发现它说的不太对。于是,我针对这个问题做了一些研究,并尝试了 CSS 和 JavaScript 的加载方法。

加载CSS资源会阻塞页面解析吗?

首先我要说的是,本节标题中的问题毫无疑问可以得到肯定的回答。加载 CSS 文件不仅会阻止 HTML 代码解析,还会阻止 JavaScript 代码执行。

首先,我建议你先尝试一下。为此,我们需要相应地配置浏览器。我们将从 CDN 下载 CSS 文件,因此需要限制 Google Chrome 浏览器的网速。为此,请在开发者工具的“性能”选项卡中,将“网络”参数值更改为“慢速 3G”。我们将探索下一页:



<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta data-fr-http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link href="https://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap.css" rel="stylesheet">
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            console.log('DOMContentLoaded');
        })
    </script>
    <script>
        console.log('script');
        Promise.resolve(1).then(res => {
            console.log('then');
        });
    </script>
</head>
<body>
    <h1>hello</h1>
</body>
</html>


Enter fullscreen mode Exit fullscreen mode

我们从 CDN 下载了 CSS 文件,但由于人为限制了网络连接速度,加载样式需要一些时间。因此,在 CSS 文件加载完成之前,JavaScript 控制台没有任何内容,页面内容也无法显示在屏幕上。我们看到的情况表明,CSS 加载阻碍了其他页面内容的加载和处理。

图像 输出数据到JS控制台

加载并执行JS代码会阻塞页面解析吗?

当然,加载和处理 JS 文件会阻塞页面解析。不过,为了解决这个问题,你可以在将脚本连接到页面时使用属性和标签defer async <script>。现在我们来研究一下它们对页面加载的影响。

正常脚本加载和执行

如果标签<script>未使用async或属性defer——页面内容加载和处理过程如下图所示。加载 JS 文件并执行其中包含的代码会阻止 HTML 解析。

图像 使用<script>不带 async 和 defer 属性的标签

在这里以及以后,我们将使用以下颜色符号。

图像 HTML 解析 — HTML 解析;HTML 解析暂停 — HTML 解析暂停;脚本下载 — 脚本加载;脚本执行 — 脚本执行

使用<script>带有 async 属性的标签

当浏览器处理<script>带有属性的标签时async,JavaScript 代码会异步加载。加载完成后,脚本代码会立即执行。然而,JS 代码的执行会阻塞 HTML 解析。

图像 使用<script>带有 async 属性的标签

使用<script>带有 defer 属性的标签

如果标签<script>包含属性defer— 则脚本代码会异步加载。但是,代码加载完成后,只有在 HTML 代码解析完成后才会执行。

图像 使用<script>带有 defer 属性的标签

实验

让我们尝试一下async和属性defer。让我们从下一页开始:



<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta data-fr-http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>DomContentLoaded</title>
</head>
<body>
    <script src="http://code.jquery.com/jquery-1.4.4.min.js">
    </script>
    <script src="./index.js"/> // 0
    <script src="./index2.js"/> // 2
    <script >
    console.log('inline');
        Promise.resolve().then(res=>{
            console.log('then');
        })
    </script>
    <div id="hello">hello world</div>

    <script>
        document.addEventListener('DOMContentLoaded', () => {
            console.log('DOMContentLoaded');
        })
    </script>

</body>
</html>


Enter fullscreen mode Exit fullscreen mode

此页面除了jquery-1.4.4.min.js从 CDN 下载脚本外,还加载了几个自己的脚本 -index.jsindex2.js。以下是它们的代码。

文件index.js



Promise.resolve().then((res) => {
    console.log('index1');
    return res;
});


Enter fullscreen mode Exit fullscreen mode

文件index2.js



Promise.resolve().then((res) => {
    console.log('index2');
    return res;
});


Enter fullscreen mode Exit fullscreen mode

当此页面加载时,JS 控制台将获得如下所示的内容。

图像 输出数据到JS控制台

因此,我们有证据表明,加载和处理 JS 文件会阻塞 HTML 代码的渲染。脚本输出的消息会先于 DOM 内容加载完成的消息出现在控制台中。

现在让我们看一下<script>在标签中使用属性的脚本如何表现<async>



<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta data-fr-http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>DomContentLoaded</title>
</head>
<body>
    <script async src="http://code.jquery.com/jquery-1.4.4.min.js">
    </script>
    <script src="./index.js"></script> 
    <script src="./index2.js"/></script>
    <script>
    console.log('inline');
        Promise.resolve().then(res=>{
            console.log('then');
        })
    </script>
    <div id="hello">hello world</div>

    <script>
        document.addEventListener('DOMContentLoaded', () => {
            console.log('DOMContentLoaded');
        })
    </script>

</body>
</html>


Enter fullscreen mode Exit fullscreen mode

我们来看看控制台里显示的内容。

图像 输出数据到JS控制台

jQuery 库脚本是异步加载的。控制台中的内容会在加载之前显示。如果库脚本加载速度太慢,它不会干扰 HTML 代码的解析。该消息DOMContentLoaded可以在异步脚本加载和执行之前或之后显示。应用该属性时defer,脚本将异步加载,等待文档素材处理完毕,然后在 DOMContentLoaded 事件之前执行。

您是否遇到过阻止网页内容处理的问题?

文章来源:https://dev.to/ra1nbow1/css-javascript-and-blocking-web-page-parsing-610
PREV
2021 年 React 开发人员需要了解的内容 JavaScript 知识 使用状态管理器 React Hooks 服务器端渲染 学习 React 时常见的错误
NEXT
我想要的网络