跳到主要内容

异步加载最佳实践

在前端开发中,我们经常需要加载各种 JavaScript 脚本。然而,如果不恰当地加载脚本,可能会阻塞页面渲染,影响用户体验。本文将探讨 JavaScript 异步加载的最佳实践,帮助大家优化网页性能。

命名空间管理

为了避免全局变量污染,我们可以使用命名空间方法进行 JavaScript 模块管理。具体做法是将相关的函数和变量封装在一个对象中,并将该对象赋值给一个变量,这个变量就成为这组函数和变量的命名空间。

var utils = {
foo: function () {
console.log('Hello');
},
bar: function () {
console.log('World');
},
};

utils.foo();

同步与异步加载

在网页中加载 JavaScript 脚本有两种方式:

  1. 使用<script>标签同步加载,又称阻塞模式。
  2. 使用<link>标签或动态创建<script>标签异步加载。

同步加载会阻塞页面渲染,直到脚本加载并执行完毕。而异步加载则允许脚本在后台加载,不影响页面渲染。

需要注意的是,异步加载会阻塞window.onload事件,因为window.onload要等到页面所有资源都加载完毕才会触发。所以我们应尽量避免使用window.onload

异步加载的两种属性

HTML5 为<script>标签引入了两个新属性,用于控制脚本的异步加载:

  1. async:脚本下载完成后立即执行,不保证执行顺序。
  2. defer:脚本在 HTML 解析完成后,DOMContentLoaded事件触发前执行,保证执行顺序。
<head>
<!-- 现代浏览器 -->
<script src="app.js" async></script>
<!-- 兼容旧版本IE -->
<script src="app.js" defer></script>
</head>

动态加载脚本

除了使用asyncdefer属性,我们还可以通过 JavaScript 动态创建<script>标签来实现异步加载:

function loadScript(src) {
var script = document.createElement('script');
script.src = src;
document.body.appendChild(script);
}

loadScript('utils.js');

这种方法的优点是可以完全控制脚本加载的时机和方式,缺点是可能会影响DOMContentLoaded事件。

window.onload之后加载

如果某些脚本对页面渲染不重要,我们可以推迟到window.onload之后再加载,避免阻塞页面:

function asyncLoad() {
var script = document.createElement('script');
script.src = 'utils.js';
document.body.appendChild(script);
}

if (window.addEventListener) {
window.addEventListener('load', asyncLoad, false);
} else if (window.attachEvent) {
window.attachEvent('onload', asyncLoad);
}

需要异步加载的场景

并非所有 JavaScript 脚本都需要异步加载。一般来说,以下几种脚本适合异步加载:

  1. 不影响页面主要内容的第三方脚本,如网站统计、广告等。
  2. 不操作 DOM 的工具类函数库。
  3. 移动端页面的大部分脚本,避免阻塞页面超过 2.5 秒。

总之,异步加载 JavaScript 是提升网页性能的重要手段。我们应根据实际情况,选择合适的异步加载方式,让用户尽快看到页面主要内容。同时也要注意异步脚本的执行顺序和依赖关系,确保网页功能正常运作。