很多人觉得个人博客不需要性能优化—内容少、访问量低,有什么好优化?
我的看法不一样:博客是我作品,让它跑得快是最基本体面。
这篇文章记录云图札记性能优化实践,从图片、字体到构建策略。
图片:最大的性能杀手
博客图片通常占页面总资源 60-80%。不处理图片,其他优化都是小修小补。
Sharp + WebP:体积砍半
Astro 内置 Sharp 图片服务,构建时自动转 WebP:
// astro.config.mjs
export default defineConfig({
image: {
service: {
entrypoint: 'astro/assets/services/sharp',
},
},
});
WebP 同等视觉质量下比 JPEG/PNG 小 25-35%,quality 设 80,肉眼几乎看不出区别。
响应式 srcset:按需加载
手机加载 1200px 宽的封面图纯属浪费。用 Astro <Image> 组件指定三档宽度:
<Image
src={heroImage}
widths={[680, 960, 1200]}
sizes="(max-width: 768px) 100vw, 680px"
/>
构建后自动生成 <picture>,浏览器按屏幕宽度选最合适图。手机只下载 680px 版本。
远程图片妥协
Steam 游戏封面来自 CDN,Astro <Image> 处理不了远程 URL。折中方案:手动加 width 和 height 防 CLS,加 loading="lazy" 和 decoding="async" 延迟加载:
<img
src="https://steamcdn-a.akamaihd.net/steam/apps/236850/header.jpg"
width={460}
height={215}
loading="lazy"
decoding="async"
/>
显式尺寸让浏览器在图片加载前就预留空间,避免页面跳动。
字体:中文字体文件巨大
一个完整 Noto Sans SC 可达 16MB,处理不好就是首屏渲染最大阻碍。
子集化 + font-display
用 Google Fonts 动态子集,只加载页面实际用到字符。设 font-display: swap,文字先用系统字体显示,自定义字体加载完再替换:
@font-face {
font-family: 'Noto Sans SC';
font-display: swap;
src: url('/fonts/NotoSansSC-subset.woff2') format('woff2');
}
关键 CSS 内联
首屏必需 CSS(布局、字体声明、关键颜色)内联到 <head>,非关键样式通过 <link> 异步加载。
这个技巧顺便解决了搜索弹窗 FOUC 问题—CSS 延迟加载导致弹窗短暂闪现,内联关键 CSS 后不再出现。
构建:静态优先
Astro 默认生成静态页面,只在需要动态功能时才用 SSR。大多数页面直接从 CDN 返回,不需要服务器渲染。
部署用 Cloudflare Pages,全球 CDN 边缘节点。一个典型博文页面 HTML 十几 KB(gzip 后),加上 WebP 和子集字体,首屏通常 1 秒以内。
优化清单
| 优化项 | 效果 |
|---|---|
| Sharp WebP 压缩 | 图片体积减少 25-35% |
| 响应式 srcset | 移动端流量减少 40-60% |
| 字体子集 + swap | 首屏文字即时显示 |
| 显式 width/height | CLS 降至接近 0 |
| 静态生成 + CDN | TTFB < 100ms |
种下你的想法
在花园里留下一条评论,和这篇文章一起生长。