2026 年 Astro 的图片管线已经不能再省了——Core Web Vitals 把 LCP 加权得更重,图片膨胀仍然是内容站过不了”Good”门槛的头号原因。Astro 自带 <Image> 和 <Picture> 组件,但你得配对。这是一套千篇规模能跑得动的方案。
问题背景
Astro 的图片管线在构建期跑,默认用 Sharp。生成多尺寸变体、转码格式、把 HTML 改写成带 srcset 的 <picture>。默认配置对 demo 够用,但在量大的站上漏质量也漏带宽。关键三个开关:格式优先级、响应式宽度、懒加载行为。
判断标准
- Lighthouse 报 “Properly size images” 或 “Serve images in next-gen formats”。
- 移动端 LCP 超过 2.5 秒。
- 单篇文章页加载图片总量超过 600KB。
- 一眼能看到本该是 WebP 的 PNG 截图,体积是原来的五倍。
- 托管平台账单里
/_image?...请求占大头。
快速结论
用 Astro 的 <Picture> 同时输出 AVIF + WebP + 原图兜底。widths 按版心最大宽度设。只有 LCP 图加 loading="eager"。把优化后的产物缓存到 CDN,不能只在源站。
方案一:现代默认配置
正文图用 <Picture> 输出三种格式。AVIF 对照片比 WebP 还省 30-50%,但 Safari < 16 还在拖 WebP 占比:
---
import { Picture } from 'astro:assets';
import cover from '../assets/cover.png';
---
<Picture
src={cover}
alt="文章封面示意图"
widths={[400, 800, 1200]}
sizes="(max-width: 768px) 100vw, 800px"
formats={['avif', 'webp']}
loading="lazy"
decoding="async"
/>
widths 不要超过版心最大宽度。版心最多 800px 还生成 2400px 变体纯属浪费。
方案二:LCP 图要特殊对待
承担 LCP 的那张图——hero、封面或首屏图——必须 eager 加载并 preload。把它懒加载是内容站 LCP 退化的头号原因:
<Picture
src={hero}
alt="..."
widths={[800, 1600]}
sizes="100vw"
formats={['avif', 'webp']}
loading="eager"
fetchpriority="high"
/>
如果 hero 在某个组件里渲染、HTML 解析器看不到早期,那就在 head 加 <link rel="preload" as="image">:
<link rel="preload" as="image" href={heroSrc.src} imagesrcset={heroSrcset} imagesizes="100vw" />
方案三:远程图与 CDN 陷阱
Astro 能优化远程图,但要先在 astro.config.mjs 把域名加进 image.domains:
import { defineConfig } from 'astro';
export default defineConfig({
image: {
domains: ['cdn.contentful.com', 'images.unsplash.com'],
remotePatterns: [{ protocol: 'https' }],
},
});
远程图同样经过构建期 Sharp,落到 dist/_astro/。如果部署到不保留 dist/_astro/ 的 serverless 平台,生产会看到一堆坏图——必须真部署一次才能验证,npm run preview 看不出来。
容易踩的坑
- 直接用
<img>配原始 PNG/JPG,绕开管线。Astro 没法压缩、转码、加 hash。 widths设得比版心还大。600px 列硬塞 2400px AVIF 就是白扔字节。- LCP 图懒加载。首屏内容不能延后。
- 漏
alt。Astro 不会因此阻断构建——但可访问性和 SEO 都会扣分。 - 把截图当照片压。截图用 PNG-8 或 AVIF 无损比默认质量的 WebP 还小。
- 生产里
_image?请求直接打回源站。要在 CDN 上设长 TTL 缓存。
FAQ
- AVIF 和 WebP 选哪个: 都要。Astro 能输出
<picture>AVIF 优先 WebP 兜底。照片 AVIF 省 30%,WebP 兼容更好、老设备解码更快。 - Astro 支持动图 WebP / GIF 吗: Sharp 默认不处理动画。动图要么跳过管线直接发原图,要么转成 MP4/WebM,比动图 GIF 小 10 倍。
- Cloudinary 或 imgix 值不值: 图片过万张、或者要实时变换才划算。少于这个量,Astro 构建期管线更简单且免费。
- 怎么确认真在发 AVIF: DevTools 打开 Network,过滤 Img,看响应 Content-Type。正文图还是
image/png说明<Picture>没接上,或者浏览器不接受 AVIF。 - 加了图之后构建巨慢怎么办: Sharp 是 CPU 密集型。用
image.service.config.limitInputPixels限并发,CI 缓存node_modules/.astro/。