模块化按需加载能避开FOUC、重复加载和缓存失效三大卡点:内联critical CSS避免白屏错位,统一提取共用样式防止冗余,按需更新哈希文件保障缓存精准。

因为不这么做,首页首屏加载会卡在样式上——尤其是京东这类亿级流量站点,首屏 CSS 文件动辄 300KB+,全量加载直接拖慢 TTFB 和 FCP。
模块化按需加载能避开哪些真实卡点
大型电商首页不是单个 HTML + 一堆全局 CSS 那么简单。顶部导航、轮播图、商品宫格、分类弹窗、促销倒计时……每个区块都自带样式逻辑,但用户首次打开时,往往只看到前两屏内容。
-
FOUC(Flash of Unstyled Content):如果所有 CSS 一股脑塞进<head>,浏览器得等全部解析完才开始渲染;而模块化后,关键区块的critical CSS可以内联,其余延后注入,避免白屏或错位 - 重复加载:比如「购物车浮层」和「登录弹窗」都用到了
.modal-overlay,传统写法可能各自打包一份相同规则;模块化后可通过postcss-import或构建时 dedupe 统一提取 - 缓存失效:一个按钮样式改了,不该触发整个
main.css缓存失效;模块化后只需更新button.module.css对应的 hash 文件
PostCSS + 动态 import 是最可控的落地组合
构建阶段靠 PostCSS 拆分,运行时靠 JS 控制加载时机——这对电商首页特别实用,比如用户滚动到「猜你喜欢」区域才加载对应样式,点击「分类菜单」再注入二级分类的 CSS。
- 用
postcss-modules把home-banner.css编译成带哈希类名的home-banner_abc123.css,避免全局污染 - 路由切换或 DOM 出现时调用
loadCSS('/css/home-banner_abc123.css'),而不是靠<link rel="stylesheet">静态声明 - 注意
document.head.appendChild(link)后要监听link.onload,否则组件可能提前渲染导致样式错乱
别忽略 SSR 场景下的 Critical CSS 提取
京东首页这类强 SEO 要求的页面大多走 SSR,服务端吐出的 HTML 必须包含首屏所需样式,否则客户端 hydration 前会闪一下无样式的结构。
立即学习“前端免费学习笔记(深入)”;
- 不能只依赖前端动态加载——得用
critters或mini-css-extract-plugin在构建时提取首屏关键 CSS - 提取结果必须内联进 HTML 的
<style>标签,且要控制体积(建议 ≤ 15KB),否则反而增加 TTFB - 非关键 CSS 加载完成后的移除动作要谨慎:
link.remove()可能误删其他模块共用的样式表
真正难的不是拆模块,而是判断“什么时候该加载哪一块”——滚动触发?IntersectionObserver?还是路由懒加载钩子?这些决策点比技术实现更影响最终性能水位。


















