js加载方式对比

defer async preload prefetch modulepreload 的区别和应用场景,在 js 中下载和执行的优先级对比


script 加载属性与资源预加载指令对比

加载和执行特性对比表

特性 下载时机 执行时机 阻塞解析 执行顺序 优先级 适用场景
普通 script 立即下载 立即执行 阻塞 HTML 解析 按出现顺序 必须立即执行的核心脚本
defer HTML 解析过程中下载 DOM 构建完成后,DOMContentLoaded 事件前执行 不阻塞 按出现顺序执行 依赖 DOM 结构但不紧急的脚本
async HTML 解析过程中下载 下载完成后立即执行 执行时阻塞 不保证顺序 中高 独立功能,不依赖其他脚本的场景
preload 提前高优先级下载 不自动执行 不阻塞 不适用 当前页面必需资源(字体、样式、关键JS)
prefetch 空闲时低优先级下载 不自动执行 不阻塞 不适用 最低 未来页面可能需要的资源
modulepreload 提前下载并解析 不自动执行 不阻塞 不适用 ES模块及其依赖的预加载

详细说明

脚本加载属性

  • defer: <script defer src="script.js"></script>
    • 适合有依赖关系且需要按顺序执行的脚本
    • 确保在DOM就绪时执行,适合操作DOM的脚本
  • async: <script async src="script.js"></script>
    • 适合第三方统计、广告脚本等独立功能
    • 不适合有依赖关系的脚本

资源预加载指令

  • preload: <link rel="preload" href="style.css" as="style">
    • 当前页面必定需要的资源,提高首屏加载性能
    • 支持指定资源类型(as属性)和媒体查询
  • prefetch: <link rel="prefetch" href="next-page.js">
    • 下一页可能用到的资源,浏览器空闲时加载
    • 适合预加载分页内容、可能跳转的页面资源
  • modulepreload: <link rel="modulepreload" href="module.js">
    • 专为ES模块设计,可同时预加载依赖模块
    • 比普通preload更高效,减少级联请求
这些技术合理组合使用可以显著提升网站性能和用户体验。资源被 prefetch 时,后续资源的情况可以看到:from prefetch cache 的字样