首屏js优化核心是精准控制执行时机:必需逻辑用defer,独立脚本用async,小体积内联代码直接写script标签;非首屏模块动态加载,关键js预加载,第三方脚本延迟注入,并规避async/defer混用等陷阱。

首屏加载的 JavaScript 脚本异步加载优化,核心不是“全量异步”,而是“精准控制执行时机”——让关键逻辑及时可用,非关键逻辑不抢资源、不阻塞渲染。
区分脚本类型,选对加载策略
同一页面中 JS 脚本角色不同,不能统一用 async 或 defer:
-
首屏必需且依赖 DOM 的业务逻辑(如 Vue/React 应用挂载、路由初始化、首屏数据请求):用
defer。它保证脚本异步下载、DOM 解析完成后按 HTML 顺序执行,既不阻塞解析,又能安全操作 DOM。 -
完全独立、无需 DOM、无执行顺序要求的脚本(如统计埋点、广告 SDK):用
async。它下载完立刻执行,适合可并行、无依赖的工具类代码。 -
纯内联的小体积初始化代码(如设置全局配置、启动性能监控):直接写
<script>...</script>,但不要加type="module"——否则会变成异步模块行为,可能在 DOM 尚未解析时就执行,导致document.body访问报错。
拆分首屏与非首屏逻辑,动态加载非关键模块
首屏 JS 体积越小,解析执行越快。把非首屏功能从主入口剥离:
- 用
import()动态导入非首屏组件或能力,比如弹窗、图表、富文本编辑器、底部推荐模块; - 结合路由做代码分割:React Router 中用
lazy()+Suspense,Vue Router 中用异步组件写法defineAsyncComponent; - 检查打包产物,确保主入口 JS(如
main.js)gzip 后不超过 100KB;Webpack 可通过SplitChunksPlugin提取公共依赖,Vite 用户可启用build.rollupOptions.output.manualChunks精细控制分包。
预加载关键 JS,延迟注入干扰项
浏览器默认按 HTML 顺序加载脚本,但你可以主动干预优先级:
- 对首屏立即需要的 JS(如核心框架、关键工具函数),用
<link rel="preload" as="script" href="core.js">提前触发下载,不执行; - 第三方脚本(尤其是未优化的统计、客服、广告)一律延迟加载:等
DOMContentLoaded甚至用户交互后才注入,避免抢占带宽和主线程; - 禁用
document.write(),现代浏览器会清空页面并报错;若必须兼容旧 SDK,改用appendChild或动态script标签插入。
避免常见陷阱
一些看似优化的操作反而会拖慢首屏:
- async 和 defer 不要混用:浏览器只认 async,defer 会被忽略,可能导致执行时机错乱;
- 内联 JS 加了 type="module" 就不是“马上执行”:它会等待所有模块加载完毕再统一执行,破坏首屏初始化节奏;
-
import() 路径含变量需谨慎:如
import(`./${name}.js`)会让构建工具打包所有匹配文件,体积暴增; - 每个 import() 都是独立请求:避免在循环中高频调用,防止触发浏览器并发连接限制(通常 6 个)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











