跳至主要内容

最佳实践

图像

在 GitHub 上编辑此页面

图像会对应用的性能产生重大影响。为了获得最佳效果,你应通过执行以下操作对其进行优化

  • 生成 .avif.webp 等最佳格式
  • 为不同的屏幕创建不同的大小
  • 确保可以有效缓存资产

手动执行此操作非常繁琐。你可以根据自己的需求和偏好使用各种技术。

Vite 的内置处理

Vite 将自动处理导入的资产以提高性能。这包括通过 CSS url() 函数引用的资产。哈希将添加到文件名中,以便可以对其进行缓存,并且小于 assetsInlineLimit 的资产将被内联。Vite 的资产处理最常用于图像,但也适用于视频、音频等。

<script>
	import logo from '$lib/assets/logo.png';
</script>

<img alt="The project logo" src={logo} />

@sveltejs/enhanced-img

@sveltejs/enhanced-img 是在 Vite 的内置资产处理之上提供的插件。它提供即插即用的图像处理,提供 avifwebp 等较小的文件格式,自动设置图像的固有 widthheight 以避免布局偏移,为各种设备创建多种大小的图像,并剥离 EXIF 数据以保护隐私。它将在任何基于 Vite 的项目中运行,包括但不限于 SvelteKit 项目。

作为构建插件,@sveltejs/enhanced-img 只能在构建过程中优化位于你计算机上的文件。如果你有位于其他位置的图像(例如从你的数据库、CMS 或后端提供的路径),请阅读有关 从 CDN 动态加载图像 的内容。

警告@sveltejs/enhanced-img 包为实验性包。它使用 1.0 前版本,并且每次发布次要版本时都可能引入重大更改。

设置

安装

npm install --save-dev @sveltejs/enhanced-img

调整 vite.config.js

import { sveltekit } from '@sveltejs/kit/vite';
import { enhancedImages } from '@sveltejs/enhanced-img';
import { defineConfig } from 'vite';

export default defineConfig({
	plugins: [
		enhancedImages(),
		sveltekit()
	]
});

由于转换图像的计算开销,首次构建时构建时间会更长。但是,构建输出将缓存到 ./node_modules/.cache/imagetools,以便后续构建速度更快。

基本用法

.svelte 组件中使用,方法是使用 <enhanced:img> 而不是 <img>,并使用 Vite 资源导入 路径引用图像文件

<enhanced:img src="./path/to/your/image.jpg" alt="An alt text" />

在构建时,您的 <enhanced:img> 标签将被 <img> 替换,该 <img><picture> 包装,提供多种图像类型和大小。只能在不损失质量的情况下缩小图像,这意味着您应该提供所需的最大分辨率图像,将为可能请求图像的各种设备类型生成较小版本。

您应该以 2 倍分辨率为 HiDPI 显示器(也称为视网膜显示器)提供图像。<enhanced:img> 将自动处理向较小设备提供较小版本。

如果您希望向 <enhanced:img> 添加样式,则应添加 class 并将其作为目标。

动态选择图像

您还可以手动导入图像资源并将其传递给 <enhanced:img>。当您有一组静态图像并希望动态选择一个或 对其进行迭代 时,这非常有用。在这种情况下,您需要更新 import 语句和 <img> 元素,如下所示,以指示您希望对其进行处理。

<script>
	import MyImage from './path/to/your/image.jpg?enhanced';
</script>

<enhanced:img src={MyImage} alt="Some alt text" />

您还可以使用 Vite 的 import.meta.glob。请注意,您必须通过 自定义查询 指定 enhanced

ts
const pictures = import.meta.glob(
'/path/to/assets/*.{avif,gif,heif,jpeg,jpg,png,tiff,webp}',
{
query: {
enhanced: true
}
}
);

固有尺寸

widthheight 是可选的,因为它们可以从源图像推断出来,并且在预处理 <enhanced:img> 标签时会自动添加。使用这些属性,浏览器可以保留正确数量的空间,防止 布局偏移。如果您想使用不同的 widthheight,可以使用 CSS 设置图像样式。由于预处理器为您添加了 widthheight,如果您希望自动计算其中一个尺寸,则需要指定该尺寸

<style>
	.hero-image img {
		width: var(--size);
		height: auto;
	}
</style>

srcset 和 sizes

如果你有一个大图像,例如占据设计宽度的英雄图像,你应该指定 sizes,以便在较小的设备上请求较小的版本。例如,如果你有一个 1280px 图像,你可能希望指定类似于

<enhanced:img src="./image.png" sizes="min(1280px, 100vw)"/>

如果指定了 sizes<enhanced:img> 将为较小的设备生成小图像并填充 srcset 属性。

自动生成的最小图片的宽度为 540px。如果你想要更小的图像或希望指定自定义宽度,你可以使用 w 查询参数来实现

<enhanced:img
  src="./image.png?w=1280;640;400"
  sizes="(min-width:1920px) 1280px, (min-width:1080px) 640px, (min-width:768px) 400px"
/>

如果没有提供 sizes,则会生成 HiDPI/Retina 图像和标准分辨率图像。你提供的图像应该是你希望显示的分辨率的 2 倍,以便浏览器可以在具有高设备像素比的设备上显示该图像。

逐图像转换

默认情况下,增强图像将转换为更高效的格式。但是,你可能希望应用其他转换,例如模糊、质量、扁平化或旋转操作。你可以通过附加查询字符串来运行逐图像转换

<enhanced:img src="./path/to/your/image.jpg?blur=15" alt="An alt text" />

请参阅 imagetools 存储库以获取指令的完整列表.

从 CDN 动态加载图像

在某些情况下,图像在构建时可能无法访问——例如,它们可能存在于内容管理系统或其他地方。

使用内容分发网络 (CDN) 可以让你动态优化这些图像,并在大小方面提供更大的灵活性,但它可能涉及一些设置开销和使用成本。根据缓存策略,浏览器可能无法使用资产的缓存副本,直到从 CDN 收到304 响应。构建针对 CDN 的 HTML 允许使用 <img> 标记,因为 CDN 可以根据 User-Agent 标头提供适当的格式,而构建时优化必须生成具有多个源的 <picture> 标记。最后,一些 CDN 可能会延迟生成图像,这可能会对流量低且图像频繁更改的网站产生负面性能影响。

CDN 通常可以在不需要任何库的情况下使用。但是,有一些支持 Svelte 的库可以简化操作。@unpic/svelte是一个与 CDN 无关的库,支持大量提供商。你可能还会发现像Cloudinary这样的特定 CDN 具有 Svelte 支持。最后,一些支持 Svelte 的内容管理系统 (CMS)(例如ContentfulStoryblokContentstack)具有内置图像处理支持。

最佳实践

  • 对于每种图像类型,请使用上面讨论的适当解决方案。您可以在一个项目中混合并匹配所有三种解决方案。例如,您可以使用 Vite 的内置处理为 <meta> 标签提供图像,使用 @sveltejs/enhanced-img 在您的主页上显示图像,并使用动态方法显示用户提交的内容。
  • 无论您使用哪种图像优化类型,都考虑通过 CDN 提供所有图像。CDN 通过在全球范围内分发静态资产的副本来减少延迟。
  • 您的原始图像应具有良好的质量/分辨率,并且应为显示宽度的 2 倍,以服务于 HiDPI 设备。图像处理可以将图像缩小以在为较小的屏幕提供服务时节省带宽,但为放大图像而生成像素会浪费带宽。
  • 对于比移动设备宽度(大约 400px)大得多的图像,例如占据页面设计宽度的英雄图像,请指定 sizes,以便可以在较小的设备上提供较小的图像。
  • 对于重要的图像,例如最大内容绘制 (LCP)图像,设置 fetchpriority="high" loading="eager" 以优先尽可能早地加载。
  • 为图像提供容器或样式,以便对其进行约束,并且在页面加载时不会跳动,从而影响您的累积布局偏移 (CLS)widthheight 在图像仍在加载时帮助浏览器保留空间,因此 @sveltejs/enhanced-img 将为您添加 widthheight
  • 始终提供良好的 alt 文本。如果您不这样做,Svelte 编译器会向您发出警告。
  • 请勿在 sizes 中使用 emrem,也不要更改这些度量的默认大小。在 sizes@media 查询中使用时,emrem 都被定义为表示用户的默认 font-size。对于像 sizes="(min-width: 768px) min(100vw, 108rem), 64rem" 这样的 sizes 声明,如果通过 CSS 更改了控制图像在页面上布局的实际 emrem,则可能会不同。例如,不要执行类似 html { font-size: 62.5%; } 的操作,因为浏览器预加载器预留的插槽现在最终会大于创建 CSS 对象模型后的实际插槽。
上一个 性能
下一个 无障碍