图像管道
我在每个 Seahawk 网站上运行的 FAL plus Sharp 管道,默认击中 Lighthouse 100 图像评分,带有具体的文件大小数字。
为什么图像规范是性能战役的一半
在大约 70% 的营销页面上,图像是 LCP 元素。图像规范是我所知道的单一最高杠杆性能工具。正确处理这一点的团队轻松击中核心网页指标;处理不当的团队永远在与核心网页指标作斗争。
这种规范是结构性的:选择格式、上传时调整大小、优化编码、设置明确的尺寸、预加载 LCP 图像。其中每一项都是一次性工程投资,在每个网站的每个页面上都能收到回报。
FAL 英雄图像生成
我通过 FAL flux-pro/v1.1-ultra 和 Recraft v3 生成英雄图像。两者都以全编码质量生成 1200 x 675 像素的 JPEG,通常每个图像 600KB 到 1.5MB。上传原始文件到 Supabase Storage 意味着每个页面单独就运送约 1MB 的英雄图像。
FAL 每张英雄图像的成本大约是 4 美分,与手工拍摄或库存许可相比微不足道。
锐化重新编码为 WebP
在任何上传之前,图像会经过 sharp(buf).resize({width:1600, fit:"inside"}).webp({quality:82}).toBuffer()。这会生成一个比源 JPEG 小 90% 的 WebP 文件,没有感知上的损失。一个 900KB 的英雄图像变成 80KB。
在 gautamkhorana.com 上的 53 张英雄图像中,站点范围内的总节省大约是 50MB。同样的管道应用于 Seahawk 的客户端网站时,始终能带来类似的收益。代码只有十行;影响是持久的。
存储上传设置
在存储上传时设置 cacheControl: 31536000,这样 CDN 就会缓存文件一年。WebP 格式给现代浏览器提供它们需要的东西;旧版浏览器通过 picture 元素回退到 JPEG。
使用稳定的 URL 模式(slug-hero.webp),这样缓存失效的故事就清晰了。当英雄图像更新时,slug 应该轮换(slug-hero-v2.webp),数据库原子性地更新 URL。
前端集成
每张英雄图像在 HTML 中必须有明确的 width 和 height 属性。没有它们,当图像加载时会发生布局移位,CLS 会上升。Astro 和 Next.js Image 组件会自动处理这个问题;原生 img 标签需要手动处理。
首屏英雄图像必须在文档头中使用 link rel="preload" as="image" 进行预加载。通常在 LCP 指标上可以节省 100 到 400 毫秒。这是大多数营销网站上唯一最高影响的单行更改。
使用 loading="lazy" 对折叠线下的每张图片进行懒加载。浏览器现在原生支持此功能;无需 JavaScript 库。
一个辅助函数中的完整流程
我将这个流程提取到 scripts/lib/optimize-image.mjs 中,它接收一个缓冲区,运行调整大小和 WebP 编码,返回优化后的缓冲区。用于自动博客 hero 流程、批量重新编码脚本和手动上传工具。
这个单一辅助函数意味着纪律是集中的。需要上传图片的新脚本调用同一个辅助函数,获得相同的压缩,产生相同的文件大小。纪律不依赖任何单一工程师记住运行 sharp。