怎样做到js无阻塞加载?

在前端开发中,JavaScript 的阻塞加载会严重影响网页的性能和用户体验。当浏览器解析 HTML 遇到 <script> 标签时,会停止解析 HTML,优先下载并执行 JavaScript 代码,然后再继续解析 HTML。如果 JavaScript 代码执行时间过长,就会导致页面渲染延迟,出现“白屏”现象。

为了避免 JavaScript 阻塞加载,可以采用以下几种方法:

1. 使用 <script async> 属性:

async 属性告诉浏览器在下载 JavaScript 文件的同时继续解析 HTML。JavaScript 文件下载完成后会立即执行,不会阻塞 HTML 解析。多个带有 async 属性的脚本的执行顺序是不确定的,哪个先下载完哪个先执行。

<script async src="script1.js"></script>
<script async src="script2.js"></script>

2. 使用 <script defer> 属性:

defer 属性也告诉浏览器在下载 JavaScript 文件的同时继续解析 HTML。与 async 不同的是,带有 defer 属性的脚本会在 HTML 解析完成后,DOMContentLoaded 事件触发之前执行。多个带有 defer 属性的脚本会按照它们在 HTML 中出现的顺序执行。

<script defer src="script1.js"></script>
<script defer src="script2.js"></script>

3. 将 <script> 标签放在 <body> 的底部:

<script> 标签放在 <body> 的底部,可以确保在执行 JavaScript 代码之前,HTML 的主体内容已经解析完成并渲染出来。这样可以避免 JavaScript 阻塞 HTML 解析,提高用户体验。

<body>
  <!-- HTML content -->

  <script src="script.js"></script>
</body>

4. 使用动态脚本插入:

通过 JavaScript 动态创建 <script> 元素并将其添加到文档中,可以实现异步加载 JavaScript 文件。

function loadScript(src) {
  const script = document.createElement('script');
  script.src = src;
  script.async = true; // 可选,添加 async 属性
  document.head.appendChild(script);
}

loadScript('script1.js');
loadScript('script2.js');

5. 使用 import() 动态导入 (ES Modules):

对于使用 ES Modules 的项目,可以使用 import() 动态导入模块。这允许按需加载 JavaScript 模块,并且是异步的。

import('./myModule.js').then(module => {
  // 使用导入的模块
  module.doSomething();
});

选择哪种方法?

  • 如果脚本之间没有依赖关系,并且不需要访问 DOM,可以使用 async
  • 如果脚本之间有依赖关系,或者需要访问 DOM,并且需要在 DOMContentLoaded 事件触发之前执行,可以使用 defer
  • <script> 标签放在 <body> 底部是一种简单且有效的方法,适用于小型项目或对性能要求不高的场景。
  • 动态脚本插入和 import() 动态导入提供了更大的灵活性,适用于需要按需加载 JavaScript 模块的场景。

通过以上方法,可以有效避免 JavaScript 阻塞加载,提高网页的性能和用户体验。 选择哪种方法取决于你的具体需求和项目规模。 对于现代浏览器,asyncdefer 以及 import() 都是很好的选择。

posted @ 2024-12-09 09:54  王铁柱6  阅读(76)  评论(0)    收藏  举报