很多人觉得个人博客不需要性能优化—内容少、访问量低,有什么好优化?

我的看法不一样:博客是我作品,让它跑得快是最基本体面。

这篇文章记录云图札记性能优化实践,从图片、字体到构建策略。

图片:最大的性能杀手

博客图片通常占页面总资源 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。折中方案:手动加 widthheight 防 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/heightCLS 降至接近 0
静态生成 + CDNTTFB < 100ms

种下你的想法

在花园里留下一条评论,和这篇文章一起生长。

COMMENTS