延迟加载JS会影响首屏渲染吗? 书生シ悦轩 提问于 2026-03-01 20:28:19 阅读 26 优化 我在做首屏优化,把非关键JS用defer和动态import()延迟加载了,但发现首屏内容反而变慢了,这是为啥? 比如我把一个工具库改成这样: document.addEventListener('DOMContentLoaded', () => { import('./utils.js').then(module => { module.init(); }); }); 原本是直接,现在首屏白屏时间更长了,是不是我用错了? 延迟JS加载首屏优化 我来解答 赞 4 收藏 分享 生成中... 手机扫码查看 复制链接 生成海报 反馈 发表解答 您需要先 登录/注册 才能发表解答 2 条解答 设计师涵博 Lv1 你用错了时机。 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 加载更多 相关推荐 2 回答 93 浏览 Next.js项目中自定义字体加载慢且页面闪烁怎么办? 我在Next.js项目里引入了本地字体文件,但页面加载时字体总是延迟渲染,出现文字闪烁的情况。之前用标签在头部引入过Google字体倒没问题,换成本地字体后就卡住了。 尝试过把字体文件放在public... 朱莉🍀 框架 2026-01-29 15:54:29 2 回答 230 浏览 uni-app中renderjs页面渲染延迟怎么解决? 大家好,我在uni-app项目里用renderjs写了一个3D商品展示模块,但页面加载时总是有明显的延迟,卡顿感很明显,怎么解决呢? 场景是这样的:在页面onReady生命周期里调用了this.$re... 迷人的建利 移动 2026-01-29 01:55:39 1 回答 19 浏览 关键渲染路径阻塞,CSS和JS到底该怎么放? 我在优化页面首屏加载时,发现即使把CSS放在head里、JS放底部,Lighthouse还是提示“阻塞渲染”。明明已经按教程做了啊,是不是还有其他坑? 比如我现在的结构是这样: <!DOCTYP... Prog.丹丹 优化 2026-03-30 16:55:14 2 回答 38 浏览 Cesium中如何正确加载本地GeoJSON数据? 我在用Cesium加载本地的GeoJSON文件时总是失败,控制台报错说找不到资源。明明路径是对的,也试过把文件放public目录下,但还是不行。 我用的是Vite搭建的项目,是不是需要特殊配置?下面是... 宇文恒菽 交互 2026-03-30 13:52:19 2 回答 43 浏览 Egg.js 中如何正确渲染带变量的 HTML 模板? 我在 Egg.js 里用 view 渲染 HTML,想把 ctx.locals 的变量传到页面里,但页面上直接显示了 这段代码,根本没解析成实际值。是不是模板引擎没配对? 我用的是默认的 ejs,co... 夏侯若彤 前端 2026-03-21 13:47:19 2 回答 54 浏览 为什么我的CSS文件在网络面板中总是比JS文件后加载? 在开发项目时发现页面加载时样式闪一下,检查Network面板发现styles.css显示完成时间比app.js还晚,但HTML里link标签确实在script标签前面: <link rel="s... 公孙爱玲 工具 2026-02-18 11:22:35 2 回答 78 浏览 React里用了modulepreload标签预加载JS模块,但资源没加载成功怎么办? 我在React组件里用标签预加载了一个动态导入的JS模块,按文档写了modulepreload,但控制台网络面板里根本看不到请求,也没报错。代码检查了好几遍,属性都没问题,这是怎么回事? // App... 司徒俊凤 优化 2026-02-13 03:36:26 2 回答 66 浏览 Draft.js自定义块渲染时样式丢失怎么办? 在用Draft.js自定义块渲染器时,给代码块添加的CSS样式完全没生效,页面上还是默认的样式。已经按照文档写了blockRendererFn: const blockRenderer = (bloc... 翌耀~ 组件 2026-02-12 15:07:27 2 回答 42 浏览 Next.js中字体加载闪烁问题怎么解决? 我在Next.js项目里用Tailwind CSS的Inter字体,但页面加载时总会出现字体闪烁。尝试过在_document.js里用标签引入fonts.googleapis.com,也加了font-... Zz文瑞 框架 2026-02-11 08:47:27 2 回答 63 浏览 为什么用了defer的JS还是阻塞了首屏渲染? 我在优化网站首屏加载时,把所有JS都加上了defer属性,但页面还是出现卡顿,DOMContentLoaded时间依然有3秒。用Lighthouse检测发现有多个JS文件被标记为"blocking"。... 慧芳的笔记 优化 2026-02-08 11:57:36
DOMContentLoaded 这个事件触发时,首屏早就渲染完了。你把动态 import 放在这个事件里,相当于首屏内容出现之后才开始下载工具库,反而多了一次网络请求,白白拖慢了首屏交互就绪的时间。
真正影响首屏渲染的是这些:首屏HTML结构、首屏CSS、还有首屏渲染需要的JS。这些必须在HTML解析阶段就加载,不能延迟。
你得先判断这个工具库是不是首屏渲染必须的。如果是,直接用普通的 script 标签或者 defer 都行,别延迟。如果不是首屏必须的,那应该在首屏内容渲染出来之后、用户开始交互之前就加载,而不是等 DOMContentLoaded。
更合理的写法是用 requestIdleCallback 或者直接在页面 onload 之后加载:
另外提醒一点,动态 import() 虽然是异步下载,但模块代码执行也是要耗时的。如果这个工具库很大,或者 init() 里有复杂计算,依然可能卡顿。可以考虑在加载前先显示个loading态,避免用户觉得页面卡了。
懒人方案:非关键JS直接script标签加defer属性完事,别瞎折腾动态import。
或者非要用动态import就别包事件监听,直接写:
这样页面解析的同时就开始预加载了,你的写法是硬生生把加载推迟到DOM解析后。