你的网站首屏为什么还是慢?

打开网页,白屏三秒、文字闪一下才出来、图片慢慢“爬”上来……用户不是在等你,是在默默点叉。
这根本不是网速问题——是浏览器被卡在了“画第一屏”的路上。

关键渲染路径到底是什么?

它就是浏览器把 HTML、CSS、JS 变成你眼前这个页面的整条流水线:
→ 下载 HTML
→ 解析出 DOM 树
→ 下载 CSS,解析出 CSSOM 树
→ 合并 DOM + CSSOM → 渲染树
→ 计算每个元素的位置(Layout)
→ 最后把像素画到屏幕上(Paint)

这条链是单行道。哪一环堵了,后面全得干等。
比如 CSS 文件还没下完、没解析好,浏览器宁可白着,也不肯动笔画——这就是“渲染阻塞”。
JS 更狠:默认会暂停 HTML 解析,一边下脚本,一边等它执行完,DOM 和 CSSOM 都得排队。

我接手过一个做工业设备的企业站,首页硬塞了 4 个同步加载的第三方 JS(含两个客服插件),还有一份没拆分的 800KB 全局 CSS。实测下来,首屏内容要等将近 5 秒才真正稳定显示。销售反馈客户经常没等到产品图就关掉了。

如何找出你网站的渲染瓶颈?

别靠感觉,直接看 Chrome DevTools。
打开 F12 → 切到 Performance 面板 → 点录制(Record),然后刷新页面。停掉后,重点盯两个时间点:

  • First Paint(FP):屏幕第一次有颜色/灰块出现
  • First Contentful Paint(FCP):第一个文字、图片或非空白元素出现

再切到 Network 面板,按“Waterfall”排序,找那些横条特别长、又标着“render-blocking”的 CSS 和 JS 文件——它们大概率就是堵车点。

顺手跑一遍 Lighthouse(就在 DevTools 的 Lighthouse 标签页里),选“Performance”,生成报告。它会直接列出“Eliminate render-blocking resources”这一项,并告诉你具体是哪个文件拖了后腿。
之前审一个本地家居电商的首页,Lighthouse 明确圈出两个未压缩的广告 SDK 和一份没做媒体查询的全局样式表,优化方向一下就落地了。

怎么减少 CSS 的渲染阻塞?

CSS 是首当其冲的“拦路虎”。目标很实在:让它快点来、少点来、只来该来的。

方法一:内联关键 CSS
把首页顶部导航、标题、首屏按钮这些“睁眼就得看到”的样式,直接塞进 HTML 的 <style> 标签里。不发请求,不等下载,浏览器拿到 HTML 就能开画。其余样式,用 link rel="preload" 或动态插入方式异步加载。

方法二:砍掉不用的 CSS
别信“以后可能用上”。用 Chrome DevTools 的 Coverage 面板(Ctrl+Shift+P → 输入 “Coverage” → 回车),刷新页面,它会标出哪些 CSS 规则压根没被执行。配合 PurgeCSS 这类工具,在构建时自动剔除。

方法三:用对 media 属性
<link> 标签加上 media,比如:

<link rel="stylesheet" href="print.css" media="print">
<link rel="stylesheet" href="mobile.css" media="(max-width: 768px)">

浏览器一看不是当前设备需要的,就先不下载、不解析,自然不阻塞。

JavaScript 是如何拖慢渲染的?

浏览器解析 HTML 时,遇到 <script> 就立刻刹车:DOM 暂停构建,去下载、执行 JS;如果这段 JS 还读了 document.body 或改了样式,还得等 CSSOM 准备好——双重卡顿。

优先加 deferasync

  • defer:脚本异步下载,但等 HTML 解析完再按顺序执行(适合操作 DOM 的逻辑,比如轮播图初始化)
  • async:下载完立刻执行,不保序(适合统计、埋点这类独立脚本)
    别再让 <script src="..."> 裸奔了。

把非首屏 JS 推后加载
客服弹窗、分享按钮、评论区、非首屏广告位……这些完全可以让它们等 FCP 之后再加载。很多服务商(比如腾讯云智服、有赞客服)都提供 .load() 异步调用方式,文档里直接搜“异步加载”就能找到。

如果是 Vue/React 项目,开路由懒加载
Vue Router 写 component: () => import('./Home.vue'),React Router 用 lazy(() => import('./Home'))。首屏只加载当前页面代码,JS 包体积立马轻一截。

还有哪些立竿见影的优化手段?

图片别再“无脑传大图”
首屏 banner 图,别再传 3MB 原图。用 WebP 格式,配 srcsetsizes 让浏览器自己选尺寸;非首屏图片,直接加 loading="lazy"

静态资源必须强缓存
在 Nginx 或 CDN 后台,给 .css.js.webp 这些文件加上:
Cache-Control: public, max-age=31536000
用户第二次访问,99% 的资源直接从本地硬盘读,快得像没加载过。

内容型网站,试试 SSR 或静态生成
如果你的首页主要是文章、产品列表、服务介绍(不是后台系统),Next.js、Nuxt、VuePress 这类框架能直接在服务端吐出带内容的 HTML。用户打开就是“满屏”,不用等 JS 下载、执行、再发请求拉数据。

字体别让它“隐身”
自定义字体加载慢,会导致文字先空白、再闪现(FOIT)或错位(FOUT)。在 @font-face 里加一句:

font-display: swap;

浏览器会先用系统字体顶上,等字体下载完再平滑替换。

今天下班前就能做的一件事

打开 Chrome,访问你的网站首页 → F12 → 切到 Lighthouse 标签页 → 点 “Generate report”(确保选中 Performance)。
报告出来后,直接点开 Opportunities → 找 “Eliminate render-blocking resources”。

看它列出的第一个阻塞文件(通常是某个 CSS)。
→ 如果是小项目,直接复制它的 URL,粘贴到 https://cssminifier.com/ 压缩一下,替换原文件;
→ 如果是中大型项目,用 Coverage 面板确认哪些样式真正在首屏用了,把它们提取出来,写进 HTML 的 <head> 里的 <style> 标签;
→ 把原来的 <link> 标签加上 media="print" 或改成 rel="preload" + 动态插入。

改完,保存,部署,再跑一次 Lighthouse。
FCP 时间大概率已经缩短了不少——这个看得见的变化,就是你优化之路的第一块砖。