Astro 中更好的图像

作者
Erika
Fred Schott

去年,我们发布了第一个 Astro 图像集成(@astrojs/image)以及 Astro 1.0。目标很简单:让 Astro 中的图像优化变得轻松。

现在,一年过去了,下载量达到了 250 万次,我们准备分享在 Astro 中处理图像的新愿景:通过以下方式完全重新设计,带来新功能、更快的性能和更好的最终用户体验

此新更新将从 Astro 3.0 开始对所有用户开放,但您可以通过在配置文件中设置 experimental.assets 标志来立即选择启用。您也可以通过将 --experimental-assets 标志传递给 Astro CLI 来启用。

astro.config.mjs
import { defineConfig } from "astro/config"
export default defineConfig({
experimental: { assets: true },
})

在这篇文章中,我们将介绍一些新功能和改进,它们将使在 Astro 中处理图像变得更加容易。如果您更喜欢直接查看文档,请阅读我们的资产指南以获取所有详细信息。

工作原理

从一开始,我们就知道我们想要一个尽可能简洁的图像 API。我们从 @astrojs/image 集成中的原始 <Image /> 组件 API 开始,然后在此基础上进行了一些新的调整和更改。

---
// Import the <Image /> component
import { Image } from "astro:assets"
// Import a reference to the image itself
import myImage from "../assets/penguin.png"
---
<Image src={myImage} alt="A very cool penguin!" />
<!-- Result: -->
<img
src="/_astro/penguin.XXXXXX.webp"
width="300"
height="300"
loading="lazy"
decoding="async"
alt="A very cool penguin!"
/>

但不要让简洁的 API 迷惑了您

  • Astro 使用现代的 WebP 文件格式(默认)优化您的图像。
  • 为了可访问性,必需的 alt 属性有助于改进您的网站,使其适用于屏幕阅读器和其他工具。
  • 为了更快的页面加载性能,loadingdecoding 属性已作为默认值添加。
  • 为了用户体验,widthheight 属性始终包含在内,以防止布局偏移(稍后会详细介绍)。

灵活性是另一个目标。我们添加了 getImage() 函数,可以在您的项目中按需优化图像,而无需使用 <Image /> 组件。使用此函数可以构建您自己的自定义图像组件,以满足您设想的任何用例。

---
// Example: Instead of creating an `img` tag,
// apply an optimized image to a div using CSS.
import { getImage } from "astro:assets"
import myImage from "../assets/penguin.png"
const optimizedBackgroundImage = await getImage({ src: myImage })
---
<div style={`background-image: url('${optimizedBackgroundImage.src}')`}></div>
<!-- Result: -->
<div style="background-image: url('/_astro/penguin.XXXXXX.webp')"></div>

自动布局偏移预防

累积布局偏移(CLS)是优化网站性能的一个重要指标。它是 Google 三大 核心 Web 指标之一,在 Lighthouse 性能得分中占有重要权重。

Astro 新的 <Image /> 组件会自动保护您的网站免受布局偏移的影响。 它通过推断每张图片的明确高度和宽度,并将其包含在生成的 <img> 标签中来工作。通过明确的尺寸,图片在加载到页面时不会导致页面布局偏移。

输出的 HTML 始终是一个简单的 <img> 元素,因此您也可以应用额外的 CSS 样式来实现更高级的响应式布局,如 fillcover,而不会有布局偏移的风险。

<Image
src={myImage}
alt="A very cool penguin!"
style="height: 100%; width: 100%; object-fit: cover;"
/>

自动 Markdown 和 MDX 支持

与原始 @astrojs/image 集成相比,最大的改进之一是完全支持 Markdown、Markdoc 和 MDX。现在,您可以在 Markdown 内容或 frontmatter 中使用相对图像路径引用图像,Astro 将自动为您优化它们。

![A starry night sky](../../assets/stars.png)
<!-- Result: -->
<img
src="/_astro/stars.XXXXXX.webp"
width="300"
height="300"
loading="lazy"
decoding="async"
alt="A starry night sky"
/>

就是这样!您的 stars.png 图像将在最终的 HTML 中自动优化。如果您希望对图像属性进行更精细的控制,也可以直接在 MDX 中使用 <Image /> 组件,但在大多数情况下,默认设置足以生成优化后的文件大小和出色的图像质量。

与第三方图像服务集成

一些用户不可避免地会希望将 Astro 与外部图像服务(如 Cloudinary 或 Vercel)一起使用。考虑到可扩展性,我们构建了 Astro 图像服务 API,以将 Astro 与您选择的第三方图像服务连接起来。

此 API 包含少量可以控制 Astro 内部图像处理的钩子。大多数 Astro 用户永远不需要直接接触此 API,但集成作者可以使用这些钩子,通过他们自己的图像处理逻辑来扩展 Astro 的默认行为。

一个简单的图像服务导出一个 getURL() 函数,用于为每个指向图像服务域名或自定义 URL 路径的图像创建 src URL。

// Example: A basic image service that generates custom URLs
export const service = {
getURL({ src, width, height }) {
return `https://mywebsitethatgeneratesimages.com/${src}?width=${width}&height=${height}`
},
}

更复杂的图像服务可以使用 transform() 等钩子,在构建时直接生成并返回要服务的图像。有关完整 API 的详细说明,请查看我们的图像服务文档

Vercel 用户今天就可以通过 Astro 的官方 Vercel 适配器来尝试此功能。任何使用此适配器的用户都会看到他们的图像使用 Vercel 特定的 URL 端点,该端点允许 Vercel 为您处理图像优化。

我们期待看到我们的社区使用此功能将 Astro 与他们喜爱的服务集成,并加入不断增长的 Astro 集成列表

接下来是什么?

随着我们今年晚些时候接近 Astro 3.0 的正式发布,我们将继续收集您的反馈。如果您发现任何问题,请随时通过创建 issue 或在我们的 Discord 上告知我们。

这里还有很多我们没有涉及的内容,例如构建之间的缓存、文件格式控制以及 MDX 支持。有关如何使用此功能的更多信息,请访问我们的资产文档