JavaScript 加载技术和性能

2025-06-08

JavaScript 加载技术和性能

将外部脚本文件添加到您的 HTML 文档非常简单,您可以在睡梦中完成。

但这并不像你想象的那么简单。在哪里以及如何添加脚本文件,会严重影响网站的性能。

这篇博文是关于什么的?

在这篇文章中,我们将介绍将外部脚本文件包含到 HTML 中的技术,并研究这如何影响性能。

我们将比较在不同情况下哪种技术更可取、更有效。


先决条件

这篇博文假设您熟悉基本的 HTML、CSS 和 JavaScript 语法。
我们还将学习以下属性:asyncdefer


介绍

  • 您可能已经知道,外部 JavaScript 文件可以包含在:

    1. 身体
  • 在我们继续深入讨论这些技术之前,让我们先了解一下浏览器加载网页时会发生什么。

  1. 浏览器获取请求的 HTML 文件,并对其进行解析。
  2. 解析后的 H​​TML 包含对外部脚本和样式表的引用。
  3. 这些外部引用被获取、解析/加载。
  4. 一旦加载,表单中的样式就会应用到 DOM 元素上,并且
  5. 然后执行加载的脚本并应用到页面,用户查看完成的视觉结构。
  • 本质上,这应该是获取、解析、加载和执行发生的顺序。
  • JavaScript 文件应该在 DOM 完成后最终应用。但这可能会根据您添加脚本文件的位置而有所不同。

好了,说得够多了!我们开始正文吧!


在正文中包含脚本

  • 这是最受欢迎的技术,因为该策略可确保 HTML 在脚本文件之前进行解析。
  • 当您的脚本操作 DOM 元素时,此顺序是必要的。
 <!DOCTYPE html>
 <html>
   <head>
     <title>JavaScript reference inside body</title>
   </head>
   <body>
     <!-- DOCUMENT CONTENT -->
     <script src="./src/main.js"></script>
   </body>
 </html>
Enter fullscreen mode Exit fullscreen mode
  • <script>自从我开始学习 JavaScript 以来,我一直在 HTML 主体中添加。
  • 但直到最近我才知道,这是一种老式的方法,而且令人惊讶的是,它不再是推荐的方法。

RDJ 很惊讶

  • 在主体中添加脚本引用可能会给 DOM 内容加载时间,但一个主要问题是 JavaScript 加载被阻止。
  • 当您的网站中有多个(并且庞大!)脚本时,它可能会变成一场噩梦,因为用户必须等待脚本加载然后执行。
  • 这不仅会降低网站的性能,还会让用户感到沮丧。
  • 因为用户讨厌等待网站加载!猴子对电脑感到沮丧

我们如何设法加载 JavaScript 文件,同时保留用户体验并优化网站性能?

对此的简单回答是:在头部添加脚本引用

吉米法伦

在头部包含脚本

  • 是的,你没看错。在 中添加脚本引用<head>
 <!DOCTYPE html>
 <html>
   <head>
     <title>JavaScript reference inside body</title>
     <!-- Add script file source here -->
     <script src="./src/main.js"></script>
   </head>
   <body>
     <!-- DOCUMENT CONTENT -->
   </body>
 </html>
Enter fullscreen mode Exit fullscreen mode
  • 但事情并没有那么简单。还有一个问题是,当你将脚本文件添加到 时<head>,脚本文件会在HTML DOM 完全解析和加载之前被获取。
  • <p>下面显示的图像描述了一个示例网页,当用户单击按钮时会显示一条消息。
  • 看看当你在中添加脚本源时会发生什么<head>
    图像

  • 出现错误“无法读取 null 的 addEventListener 属性”。这是因为 DOM 是在 JavaScript 获取之后加载的,因此没有对按钮的引用。

  • 但这也是可以避免的。怎么做呢?这样做:
  document.addEventListener('DOMContentLoaded', function() {
       btn.addEventListener('click', () => {
           p.textContent = "You clicked me!";
       });
  });
Enter fullscreen mode Exit fullscreen mode
  • 上述代码向主体添加了一个事件监听器,用于监听 DOM 内容的加载。
  • 一旦内容加载完毕,处理程序函数内的所有代码都会被执行,从而确保只有在 DOM 完全加载后才会执行 JavaScript。
  • 现在,如果用户单击按钮,则不会出现错误: 这又是一种古老的技术。
    图像

  • HTML5 提供了两个新的现代功能,可防止阻塞 HTML 解析和 JavaScript 加载。

  • 当脚本标签包含在.js文件中时,会添加两个属性:asyncand(或)。defer<head>

  • 这两个属性都要求浏览器在单独的线程中加载脚本文件,而不会阻止 HTML 文件的解析。

1. 异步

 <!DOCTYPE html>
 <html>
   <head>
     <title>JavaScript reference inside body</title>
     <!-- Add script file source here -->
     <script src="./src/main.js" async></script>
   </head>
   <body>
     <!-- DOCUMENT CONTENT -->
   </body>
 </html>
Enter fullscreen mode Exit fullscreen mode
  • 此属性确保脚本文件的加载不会影响 HTML 的解析。
  • 也就是说,浏览器在解析 HTML 的同时加载/获取脚本文件。
  • HTML 解析没有暂停,因此脚本文件的加载不会阻止 DOM 加载。
  • 但是一旦脚本文件完全加载,HTML 解析就会暂停,脚本会立即执行,从而阻止 DOM 加载。
  • 当您的网页有多个脚本时,无法保证脚本的获取、加载和执行的顺序与脚本在 HTML 文件中出现的顺序相同。
  • 因此在以下情况下使用此属性:
    1. 脚本的获取、加载和执行彼此独立。也就是说,一个脚本中的代码不会影响另一个脚本中的代码。
    2. 当您需要脚本执行实际执行开始之前所需的初始化任务时。
    3. 当您拥有不操作 DOM 的脚本时。
   <head>
     <!-- Add script file source here -->
     <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous" async></script>
     <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous" async></script>
     <script src="./src/init.js" async></script>
   </head> 
Enter fullscreen mode Exit fullscreen mode
  • 例如:在上面的代码中,无法保证首先获取并执行 jQuery,然后是 Bootstrap,然后是 init 脚本。
  • 顺序可以说是:首先执行 Bootstrap,然后执行 init,最后执行 jQuery 脚本。

2. 推迟

 <!DOCTYPE html>
 <html>
   <head>
     <title>JavaScript reference inside body</title>
     <!-- Add script file source here -->
     <script src="./src/main.js" defer></script>
   </head>
   <body>
     <!-- DOCUMENT CONTENT -->
   </body>
 </html>
Enter fullscreen mode Exit fullscreen mode
  • defer,顾名思义,就是在单独的线程中加载脚本文件,但是推迟脚本文件的执行。
  • 与 不同async,文件加载后不会立即执行脚本,并且不会阻止 DOM 加载。
  • 此属性确保仅当 DOM 完全加载时才执行脚本。
  • 获取、加载和执行脚本的顺序与它们在中出现的顺序相同<head>
  • 因此在以下情况下使用此属性:
    1. 您的网页中的脚本文件相互依赖,一个脚本的执行会影响另一个脚本。
    2. 当你的脚本操作 DOM 内容时。
   <head>
     <!-- Add script file source here -->
     <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous" defer></script>
     <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous" defer></script>
     <script src="./src/main.js" defer></script>
   </head> 
Enter fullscreen mode Exit fullscreen mode
  • 上述代码中脚本的执行顺序为:jQuery脚本、Bootstrap、最后是主脚本文件

结论

  • <body>根据经验法则,我建议仅当您的网站使用的脚本很少时才添加脚本源。
  • 如果您有多个繁重的脚本,请在块内引用它<head>作为源,<body>以阻止 JavaScript 加载,从而影响您网站的性能。

  • 如果您的网站中的脚本彼此独立,并且您想在主 JavaScript 加载之前执行代码,请使用异步。

  • 当您的脚本依赖于 HTML 解析和 DOM 元素操作时,请使用 defer。

图像


非常感谢你的支持和阅读这篇博文。
请分享给你的朋友,并在评论区写下你对这篇文章的感受。

如果您喜欢这篇文章并从中学到了东西,请做心、保存、独角兽或全部做!

鏂囩珷鏉ユ簮锛�https://dev.to/bharati21/javascript-loading-techniques-performance-56lp
PREV
如何在手机上打开 Vite 开发服务器
NEXT
揭秘 Position 属性