延迟加载JS会影响首屏渲染吗?

书生シ悦轩 阅读 26

我在做首屏优化,把非关键JS用defer和动态import()延迟加载了,但发现首屏内容反而变慢了,这是为啥?

比如我把一个工具库改成这样:

document.addEventListener('DOMContentLoaded', () => {
  import('./utils.js').then(module => {
    module.init();
  });
});

原本是直接,现在首屏白屏时间更长了,是不是我用错了?

我来解答 赞 4 收藏
二维码
手机扫码查看
2 条解答
设计师涵博
你用错了时机。

DOMContentLoaded 这个事件触发时,首屏早就渲染完了。你把动态 import 放在这个事件里,相当于首屏内容出现之后才开始下载工具库,反而多了一次网络请求,白白拖慢了首屏交互就绪的时间。

真正影响首屏渲染的是这些:首屏HTML结构、首屏CSS、还有首屏渲染需要的JS。这些必须在HTML解析阶段就加载,不能延迟。

你得先判断这个工具库是不是首屏渲染必须的。如果是,直接用普通的 script 标签或者 defer 都行,别延迟。如果不是首屏必须的,那应该在首屏内容渲染出来之后、用户开始交互之前就加载,而不是等 DOMContentLoaded。

更合理的写法是用 requestIdleCallback 或者直接在页面 onload 之后加载:
// 方式1:页面加载完立即加载
window.addEventListener('load', () => {
import('./utils.js').then(module => {
module.init();
});
});

// 方式2:浏览器空闲时加载(更优)
requestIdleCallback(() => {
import('./utils.js').then(module => {
module.init();
});
});


另外提醒一点,动态 import() 虽然是异步下载,但模块代码执行也是要耗时的。如果这个工具库很大,或者 init() 里有复杂计算,依然可能卡顿。可以考虑在加载前先显示个loading态,避免用户觉得页面卡了。
点赞
2026-03-18 19:02
小俊熙
小俊熙 Lv1
用错了个寂寞。动态import()本身就异步的,你还包一层DOMContentLoaded,等于要等DOM解析完才开始下载,比直接用defer还慢。

懒人方案:非关键JS直接script标签加defer属性完事,别瞎折腾动态import。

<script defer src="./utils.js"></script>


或者非要用动态import就别包事件监听,直接写:

import('./utils.js').then(module => {
module.init();
});


这样页面解析的同时就开始预加载了,你的写法是硬生生把加载推迟到DOM解析后。
点赞 3
2026-03-01 20:29