JavaScript 性能优化:解决脚本阻塞与加载策略

山海之间
山海之间
发布时间:2026-10-14| 5人浏览过
原创

JavaScript 脚本的执行会导致浏览器暂停页面解析,影响用户交互体验。通过合理放置脚本位置、合并代码以及利用 defer、async 或动态脚本加载等技术,可以有效减少阻塞,显著提升网页加载性能。

理解脚本阻塞原理

当浏览器在 HTML 文档中遇到 <script> 标签时,出于安全考虑(防止脚本修改 DOM 影响后续内容),它会停止解析剩余 HTML,转而下载并执行 JavaScript。这一过程会阻塞页面的渲染和其他资源(如 CSS、图片)的下载,导致用户看到空白页面,直到脚本执行完毕。

图 1 JavaScript 文件的加载和执行阻塞其他文件的下载

在传统做法中,开发者习惯在 <head> 中加载外部 JS 文件,这会严重延迟 <body> 内容的渲染。现代浏览器虽然允许并行下载多个 JS 文件,但 JS 本身仍会阻塞样式表和图片资源的下载。因此,优化脚本加载顺序和方式是提升性能的关键。

基础优化策略

第 1 步:调整脚本位置至页面底部

  • 目的:确保页面主要内容优先渲染,减少用户等待白屏的时间。
  • 操作:将所有 <script> 标签移动到 </body> 闭合标签之前。
  • 代码示例:
<html>
<head>
 <title>Source Example</title>
 <link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
 <p>Hello world!</p>
 
 <!-- 推荐的代码放置位置 -->
 <script type="text/javascript" src="script1.js"></script>
 <script type="text/javascript" src="script2.js"></script>
</body>
</html>

第 2 步:合并与减少脚本数量

  • 目的:减少 HTTP 请求开销及解析次数。
  • 操作:使用构建工具将多个 JS 文件合并为一个。避免在 <link> 标签后紧跟内嵌脚本,以防样式未加载完成时脚本读取样式信息出错。

高级:无阻塞加载技术

对于大型应用,仅靠放置位置和合并无法完全解决问题。以下技术可实现脚本在不阻塞主线程的情况下加载。

第 3 步:使用 defer 属性(同步加载,延迟执行)

  • 原理:脚本立即下载,但等到 DOM 树构建完成(window.onload 之前)才执行。不修改 DOM 时可安全使用。
  • 兼容性:IE 4+, Firefox 3.5+。不支持的浏览器会忽略该属性并可能引发阻塞。
<script type="text/javascript" src="script1.js" defer></script>

第 4 步:使用 async 属性(异步加载,立即执行)

  • 原理:HTML5 新增属性。脚本下载与页面解析并行,一旦下载完成立即执行。
  • 注意:执行顺序不确定,依赖关系的脚本不宜使用此方法。

第 5 步:动态创建 script 元素(跨浏览器推荐)

  • 原理:通过 JS 动态创建 <script> 节点并添加到文档,实现非阻塞下载。
  • 事件监听:
    • Firefox/Opera/Safari/Chrome: 监听 onload 事件。
    • IE: 监听 readystatechange 事件,检查 readyState 为 'loaded' 或 'complete'。

封装兼容函数如下:

function loadScript(url, callback){
 var script = document.createElement("script")
 script.type = "text/javascript";
 if (script.readyState){ //IE
  script.onreadystatechange = function(){
   if (script.readyState == "loaded" || script.readyState == "complete"){
    script.onreadystatechange = null;
    callback();
   }
  };
 } else { //Others
  script.onload = function(){
   callback();
  };
 }
 script.src = url;
 document.getElementsByTagName("head")[0].appendChild(script);
}

若需保证加载顺序,可递归调用:
loadScript("script1.js", function() { loadScript("script2.js", callback); });

第 6 步:使用 XMLHttpRequest (XHR) 注入

  • 原理:通过 XHR 获取 JS 文本,再创建动态 <script> 插入页面。适用于需要控制执行时机的场景。
  • 限制:通常受同源策略限制,难以从 CDN 加载代码。

总结

优化 JavaScript 加载性能的核心在于减少阻塞时间。建议优先遵循“脚本放底部”原则,并结合业务需求选择 defer、async 或动态脚本加载技术。对于有依赖关系的大型脚本,打包合并仍是最佳实践。

以上就是JavaScript性能优化总结之加载与执行的详细内容,更多关于JavaScript性能优化的资料请关注本站其它相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。