js异步加载有哪些方案?
JavaScript异步加载方案有很多,它们的目的都是为了防止JavaScript阻塞HTML解析和渲染,从而提高页面加载速度和用户体验。以下是一些常用的方案:
1. <script async>
:
- 作用: 告诉浏览器立即下载脚本,并在下载完成后尽快执行,不会阻塞HTML解析器。多个
async
脚本的执行顺序不确定,哪个先下载完哪个先执行。 - 适用场景: 彼此独立的脚本,例如统计脚本、广告脚本等,不依赖于其他脚本的执行顺序。
- 示例:
<script async src="script.js"></script>
2. <script defer>
:
- 作用: 告诉浏览器下载脚本,但要等到HTML解析完成后,在
DOMContentLoaded
事件触发之前执行。多个defer
脚本会按照它们在HTML中出现的顺序执行。 - 适用场景: 依赖于DOM结构的脚本,或者需要按特定顺序执行的脚本。
- 示例:
<script defer src="script.js"></script>
3. 动态创建<script>
标签:
- 作用: 通过JavaScript动态创建
<script>
标签,并将其添加到文档中。可以精确控制脚本的加载和执行时机。 - 适用场景: 需要根据某些条件动态加载脚本,或者需要对脚本加载过程进行更精细的控制。
- 示例:
const script = document.createElement('script');
script.src = 'script.js';
script.onload = () => {
// 脚本加载完成后的回调函数
};
document.head.appendChild(script);
4. 使用XMLHttpRequest (XHR) 或 Fetch API:
- 作用: 通过XHR或Fetch API加载JavaScript文件,然后将其内容作为字符串插入到
<script>
标签中。 - 适用场景: 需要对脚本加载过程进行更精细的控制,例如处理跨域请求、设置请求头等。
- 示例 (Fetch API):
fetch('script.js')
.then(response => response.text())
.then(scriptContent => {
const script = document.createElement('script');
script.textContent = scriptContent;
document.head.appendChild(script);
});
5. 使用import() (ES Modules):
- 作用: ES Modules的动态导入,允许在运行时按需加载模块。
- 适用场景: 实现代码分割,减少初始加载的JavaScript体积,提高页面加载速度。
- 示例:
import('./module.js')
.then(module => {
// 使用加载的模块
});
总结:
选择哪种异步加载方案取决于具体的应用场景。对于简单的独立脚本,async
或defer
就足够了。对于需要更精细控制的场景,动态创建<script>
标签、XHR/Fetch API或import()
则更合适。 合理使用异步加载技术可以显著提升网页性能。