关键渲染路径优化到底该从哪下手?

英瑞 Dev 阅读 40

最近在做页面性能优化,听说关键渲染路径(Critical Rendering Path)是核心,但完全不知道该从哪开始改。我试过把 CSS 放到 <head> 里,JS 加了 defer,但 Lighthouse 分数还是上不去。

比如我现在这个简单页面:

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="main.css" rel="external nofollow" >
</head>
<body>
  <div id="app">Loading...</div>
  <script src="app.js"></script>
</body>
</html>

明明结构很干净,但首屏渲染还是慢,是不是漏了什么关键步骤?

我来解答 赞 5 收藏
二维码
手机扫码查看
2 条解答
UE丶文斌
你的问题我一看就明白在哪了。

先说代码里的问题:script标签放在body底部是对的,但没加defer。不过这不是关键,真正的问题是首屏内容几乎为空——div#app里就一个"Loading...",浏览器渲染出来也就是这几个字,然后等JS加载完、执行完才能看到真正内容,这一来一回,首屏当然慢。

关键渲染路径优化的核心就三点:

第一,首屏HTML里直接把内容写出来,别等JS渲染。如果你是React/Vue之类的框架,可以考虑首屏做服务端渲染(SSR)或者静态生成(SSG),而不是就输出一个Loading。

第二,首屏用到的CSS内联到HTML里。你现在是外链CSS,浏览器得先下载main.css才能开始渲染。把首屏那些关键样式提取出来,直接写在head的style标签里,其他的CSS异步加载:

<head>
<style>
/* 提取首屏关键CSS内联 */
#app { margin: 0; padding: 20px; }
.header { font-size: 18px; }
</style>
<link rel="stylesheet" href="main.css" media="print" onload="this.media='all'">
</head>


第三,script加defer:

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


defer会让JS在HTML解析完成后才执行,而且不会阻塞渲染。

你 Lighthouse 分数上不去,大概率就是因为首屏内容太空了,浏览器渲染出来的就是一个Loading文字,FCP(First Contentful Paint)当然好看不到哪去。先把首屏需要展示的内容直接输出HTML,再配合内联关键CSS,分数应该能上来一截。
点赞
2026-03-19 19:05
百里玲玲
你这情况我熟,当年也被CRP折腾得够呛。按照规范来看,你已经做了基本正确的事(CSS放head,JS放body底部),但还有几个关键点要处理:

1. 检查CSS是否真的关键。按照Chrome团队建议,首屏需要的CSS要内联(直接写在style标签里),非关键CSS可以异步加载。用这个套路:




2. JS那块你用了defer不错,但现代项目更推荐用type="module",它默认就是defer的。另外看看app.js是不是太大,该拆的拆。

3. 字体文件最容易坑人。如果你用了自定义字体,一定要加font-display: swap,不然用户会看到空白文本。

4. 别忘了HTML本身也是渲染阻塞的。服务器开启gzip压缩能显著减小文件体积,nginx加个gzip on就行。

最后说个血泪教训:Lighthouse跑分时一定要用无痕模式,浏览器插件会严重干扰测试结果。实在不行上WebPageTest看看具体哪个环节耗时最长。
点赞 1
2026-03-09 21:07