Remix 中全局 CSS 必须通过 entry.server.tsx 的 links 函数服务端注入关键样式,否则首屏白屏或 FOUC;import 无效,非关键 CSS 需异步加载,critical.css 体积≤14KB且需持续验证匹配性。

Remix 中全局 CSS 无法靠 import 注入,也不能直接内联到 HTML,必须通过服务端渲染阶段可控地注入关键样式,否则首屏必然卡在 CSSOM 构建上。
为什么 import 全局 CSS 在 Remix 里会破坏首屏
Remix 的构建流程(esbuild + SSR)不会把 import './styles/global.css' 转成 或内联 ;它只当普通模块处理。结果是:
- 服务端渲染 HTML 时无样式,首屏纯 HTML 渲染(白屏或错位)
- 客户端 Hydrate 后才加载 CSS,触发 FOUC(闪屏)
- 该 CSS 进入主 bundle,无法按路由拆分,增大首屏 JS 体积
全局关键 CSS 必须走 entry.server.tsx 的 links 函数
Remix 唯一能保证服务端生成 HTML 时就注入样式的地方,是根入口文件的 links 导出函数。它返回的数组会被 SSR 阶段写入 。
- 只放真正首屏必需的规则:如
.container、.text-lg、.bg-white—— 对应首屏 DOM 中实际出现的 class - 禁止含
@import、@font-face、url()的 CSS 文件,否则会触发额外请求或字体预加载,破坏内联意义 - 建议用
critters插件自动提取:配置 Vite 或 esbuild 插件,在 build 时基于http://localhost:3000抓取首屏快照,生成精简的critical.css - 最终内联进 HTML 的体积控制在 ≤14KB:超过会触发 TCP 分包,反而延长 TTFB
非关键全局 CSS 必须异步加载且不阻塞渲染
像 .print-only、.lg:grid-cols-4、后台管理类等非首屏样式,不能留在 links 里,否则拖慢关键路径。
- 改用
media="print"初始化: - 或在客户端
DOMContentLoaded后动态插入,确保不参与初始 Render Tree 构建 - 若使用 Tailwind,确认
tailwind.config.js的content字段只指向首屏模板(如app/routes/index.tsx),避免lg:p-8等未用断点进入关键 CSS - 禁用首屏不需要的插件,比如
@tailwindcss/line-clamp若首页无截断需求,就从plugins数组中移除
Remix 的 PrefetchPageLinks 不解决全局 CSS 关键路径
这个组件只对目标路由的 links 生效(比如跳转前预加载 admin.css),但对根级全局样式无效。它不介入服务端首屏 HTML 构建,也不影响 entry.server.tsx 的输出逻辑。
真正难的不是“怎么加内联”,而是每次上线后重新验证:首屏 DOM 是否仍与当前 critical.css 匹配——尤其当产品临时加了个 class="sm:hidden md:block",md:block 就成了非首屏样式,却因未清理而滞留在关键路径里。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











