性能 / ARTICLE

给个人网站设一份性能预算

不追求抽象的满分,而是用字体、脚本、图片和交互指标约束每一次功能增长。

个人网站最容易在“只加一点”的过程中变慢:一套字体、一个统计脚本、两张未经处理的封面,再加上广告和评论。每项单独看都不夸张,组合起来却足以让移动网络上的首屏等待数秒。

性能预算的作用,是在功能进入页面之前给出边界。它不是追求某个工具里的 100 分,而是把用户能感知的速度转成团队——哪怕团队只有一个人——可以执行的约束。

先定义体验目标

Core Web Vitals 提供了三个有用视角:LCP 观察主要内容何时出现,INP 关注交互响应,CLS 衡量布局是否突然跳动。它们不能覆盖全部体验,但能避免只盯着服务器响应时间。

可以从一份朴素预算开始:

指标 移动端目标
首次加载传输量 小于 500 KB
首屏关键 CSS 小于 30 KB
初始 JavaScript 小于 100 KB
LCP 75% 访问低于 2.5 秒
CLS 低于 0.1

这些数字不是法律。图像作品集与文字博客的合理预算不同。重点是有一条需要主动讨论才能越过的线。

字体:最容易忽略的资产

中文字体包含大量字形,完整文件可能达到数 MB。为了视觉一致而让每位访客下载整套字体,通常得不偿失。

正文优先使用系统字体是可靠选择。如果品牌确实需要 Web Font,可以只在拉丁字符或标题中使用,并设置 font-display: swap。字体预加载要克制:预加载了却没有立即使用的资源,会与真正关键的 CSS 和图片竞争带宽。

JavaScript:按交互需要支付

静态文章不应该为了显示导航栏而下载一整个前端框架。页面能够由 HTML 和 CSS 完成的部分,在构建时输出即可。真正需要状态的工具,再把脚本限制在对应组件。

评估一个依赖时,不只看 npm 页面上的压缩体积,还要问:

  • 它是否进入每个页面的初始包?
  • 是否能按路由或交互时机延迟加载?
  • 原生 Web API 是否已经覆盖需求?
  • 更新频率与安全维护是否匹配项目寿命?

删除 30 KB 脚本往往比把它压缩得更精巧有效。

为媒体保留空间

图片应提供明确的 widthheight,让浏览器在文件下载前就能计算比例。这一项简单设置可以消除大量 CLS。首屏主图不要懒加载;屏幕以下的图片则应使用原生 loading="lazy"

响应式图片需要按实际展示尺寸生成多个版本。给 360 像素宽的手机发送 2400 像素图片,即使格式是 WebP,也仍在浪费流量。

广告同样需要空间预算。如果广告容器加载前高度为零,加载后突然撑开正文,页面就会明显跳动。为常见版位设置最小高度,并避免把广告紧贴下载或操作按钮。

在发布流程里执行预算

写在文档里的预算很容易被忘记。更好的做法是让构建过程报告产物大小,并在持续集成中运行 Lighthouse 或同类检查。真实用户数据则告诉你实验室环境没有覆盖的设备与网络。

不必为每一次轻微波动阻断发布,但显著退化必须能被看到。每月保留一份趋势,比偶尔手工跑一次满分截图更有价值。

性能是一种持续的产品选择。设定预算之后,“加入这个功能吗”会自然变成更具体的问题:它为用户创造的价值,是否值得它占用的加载与交互成本?

END