跳至主要内容

图片

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

  • 生成最佳格式,例如 .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 { function sveltekit(): Promise<Plugin<any>[]>

Returns the SvelteKit Vite plugins.

sveltekit
} from '@sveltejs/kit/vite';
import { function enhancedImages(): Promise<Plugin[]>enhancedImages } from '@sveltejs/enhanced-img'; import { function defineConfig(config: UserConfig): UserConfig (+3 overloads)

Type helper to make it easier to use vite.config.ts accepts a direct {@link UserConfig } object, or a function that returns it. The function receives a {@link ConfigEnv } object.

defineConfig
} from 'vite';
export default function defineConfig(config: UserConfig): UserConfig (+3 overloads)

Type helper to make it easier to use vite.config.ts accepts a direct {@link UserConfig } object, or a function that returns it. The function receives a {@link ConfigEnv } object.

defineConfig
({
UserConfig.plugins?: PluginOption[] | undefined

Array of vite plugins to use.

plugins
: [
function enhancedImages(): Promise<Plugin[]>enhancedImages(), function sveltekit(): Promise<Plugin<any>[]>

Returns the SvelteKit Vite plugins.

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>,并包含在 <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

<script>
	const imageModules = import.meta.glob(
		'/path/to/assets/*.{avif,gif,heif,jpeg,jpg,png,tiff,webp,svg}',
		{
			eager: true,
			query: {
				enhanced: true
			}
		}
	)
</script>

{#each Object.entries(imageModules) as [_path, module]}
	<enhanced:img src={module.default} alt="some alt text" />
{/each}

固有尺寸

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/视网膜图片和标准分辨率图片。您提供的图片应为所需显示宽度的 2 倍,以便浏览器可以在具有高 设备像素比 的设备上显示该图片。

每个图片的转换

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

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

有关指令的完整列表,请参阅 imagetools 存储库.

从 CDN 动态加载图片

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

使用内容分发网络 (CDN) 可以让您动态优化这些图片,并提供更多关于尺寸方面的灵活性,但它可能涉及一些设置开销和使用成本。根据缓存策略,浏览器可能无法使用资源的缓存副本,直到从 CDN 收到 304 响应。构建 HTML 以定位 CDN 允许使用 <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 对象模型创建后实际的插槽更大。

在 GitHub 上编辑此页面

上一页 下一页