中过多资源会阻塞渲染,因浏览器解析html时遇未加async/defer的或会暂停解析,直至其下载执行完毕,导致白屏延长;仅、、为必需前置项,其余css/js应异步加载或移至底部。

为什么 head 里放太多东西会阻塞渲染
浏览器解析 HTML 时,遇到 中的 <link rel="stylesheet">、<script></script>(尤其没加 async 或 defer)会暂停 HTML 解析,等资源下载并处理完才继续。这就导致白屏时间变长,哪怕页面主体内容早已就绪。
哪些资源必须放在 head,哪些可以移走
真正需要阻塞式加载的极少:<meta charset>、<title></title>、<meta name="viewport"> 是硬性前置;<link rel="icon"> 可留可移(不影响渲染);而所有 CSS 和 JS 都不该默认塞进 head。
-
<link rel="stylesheet" href="main.css">:保留,但加media="print"+onloadJS 切换回all,实现异步加载 -
<script src="polyfill.js"></script>:若只补老浏览器,用type="module"或defer;若必须同步执行(如某些 UA 检测),只留最小必要逻辑 -
<link rel="preload">:仅用于关键资源(如首屏字体、关键图片),且必须配as属性,否则无效
如何用原生 HTML 实现无阻塞 CSS 加载
核心是不让 <link rel="stylesheet"> 触发阻塞。不依赖 JS 库,纯 HTML + 少量内联脚本即可:
<link rel="stylesheet" href="main.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="main.css"></noscript>
原理:初始设 media="print" 让浏览器不阻塞,加载完成触发 onload 再切回 all。注意两点:
-
onload在 Firefox 中对<link>不可靠,需 fallback 到onreadystatechange或用document.addEventListener('DOMContentLoaded', ...) - 不要用
rel="preload"替代 ——preload不改变渲染阻塞行为,它只是提前下载,仍需后续<link rel="stylesheet">触发应用
内联关键 CSS 的边界在哪
内联能彻底消灭请求,但不是越多越好。只内联「首屏可见区域」所需的样式,比如 <header></header>、<hero></hero>、按钮基础态。工具如 critters 或 Puppeteer 提取是可行方案,但手动维护更可控:
- 超过 ~1.5KB 的内联 CSS 会增大 HTML 体积,可能抵消减少请求的好处
- 避免内联含
@import、@font-face(字体需单独preload)、或依赖媒体查询的复杂规则 - 如果用了 CSS-in-JS(如 Emotion),确保 SSR 时只提取当前路由的关键样式,而非整个主题包
真正轻量的 head 不是删东西,而是让每项存在都有明确理由和可控加载时机。最容易被忽略的是:第三方 SDK 注入的 <script></script> 或 <meta>,它们常默默拖慢首屏 —— 检查 network 面板中 head 节点的请求瀑布流,比看代码更直接。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











