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 的字样