SvelteKit 最新中文文档教程(21)—— 最佳实践之图片

前言

Svelte,一个语法简洁、入门容易,面向未来的前端框架。

从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1

Svelte 以其独特的编译时优化机制著称,具有轻量级高性能易上手 等特性,非常适合构建轻量级 Web 项目

为了帮助大家学习 Svelte,我同时搭建了 Svelte 最新的中文文档站点。

如果需要进阶学习,也可以入手我的小册《Svelte 开发指南》,语法篇、实战篇、原理篇三大篇章带你系统掌握 Svelte!

欢迎围观我的"网页版朋友圈"、加入"冴羽·成长陪伴社群",踏上"前端大佬成长之路"

图片

图片会对您的应用性能产生重大影响。为了获得最佳效果,您应该通过以下方式优化它们:

  • 生成最优格式如 .avif.webp
  • 为不同的屏幕创建不同尺寸的图片
  • 确保资源可以被有效缓存

手动完成这些工作很繁琐。根据您的需求和偏好,您可以使用多种技术。

Vite 的内置处理

Vite 会自动处理导入的资源以提升性能。这包括通过 CSS url() 函数引用的资源。文件名中会添加哈希值以便缓存,小于 assetsInlineLimit 的资源会被内联。Vite 的资源处理最常用于图片,但对视频、音频等也很有用。

svelte 复制代码
<script>
  import logo from '$lib/assets/logo.png';
</script>

<img alt="项目标志" src={logo} />

@sveltejs/enhanced-img

@sveltejs/enhanced-img 是在 Vite 内置资源处理基础上提供的插件。它提供即插即用的图片处理功能,可以提供更小的文件格式如 avifwebp,自动设置图片的固有 widthheight 以避免布局偏移,为各种设备创建多种尺寸的图片,并出于隐私考虑去除 EXIF 数据。它可以在任何基于 Vite 的项目中使用,包括但不限于 SvelteKit 项目。

!NOTE 作为构建插件,@sveltejs/enhanced-img 只能在构建过程中优化位于您机器上的文件。如果您的图片位于其他位置(如从数据库、CMS 或后端服务的路径),请阅读从 CDN 动态加载图片

警告@sveltejs/enhanced-img 包是实验性的。它使用 1.0 之前的版本号,每个小版本发布可能会引入破坏性变更。

设置

安装:

bash 复制代码
npm install --save-dev @sveltejs/enhanced-img

调整 vite.config.js

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 资源导入 路径引用图片文件:

svelte 复制代码
<enhanced:img src="./path/to/your/image.jpg" alt="An alt text" />

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

你应该为 HiDPI 显示器(又称视网膜显示器)提供 2x 分辨率的图片。<enhanced:img> 会自动负责向较小的设备提供较小版本的图片。

如果你想为 <enhanced:img> 添加样式,你应该添加一个 class 并针对它进行设置。

动态选择图像

您也可以手动导入图片资源并将其传递给 <enhanced:img>。当您有一组静态图片并想要动态选择或遍历它们时,这种方法很有用。在这种情况下,您需要同时更新 import 语句和 <img> 元素,如下所示,以表明您想要处理它们。

svelte 复制代码
<script>
  import MyImage from './path/to/your/image.jpg?enhanced';
</script>

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

你也可以使用 Vite 的 import.meta.glob。请注意,你需要通过自定义查询来指定 enhanced

svelte 复制代码
<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,如果你想要其中一个尺寸自动计算,那么你需要指定这一点:

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

srcsetsizes

如果你有一个大图像,比如占据设计宽度的主图,你应该指定 sizes,这样在较小的设备上就会请求较小版本的图像。例如,如果你有一个 1280px 的图像,你可能想要指定类似这样的内容:

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

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

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

svelte 复制代码
<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 倍,以便浏览器可以在具有高设备像素比的设备上显示该图像。

每个图像的转换

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

svelte 复制代码
<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 无关的库。你可能还会发现一些特定的 CDN(如 Cloudinary)有 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 声明,控制图片在页面上布局方式的实际 emrem 如果被 CSS 更改可能会有所不同。例如,不要做类似 html { font-size: 62.5%; } 这样的事情,因为浏览器预加载器预留的空间现在会比创建后的 CSS 对象模型的实际空间更大。

Svelte 中文文档

点击查看中文文档:SvelteKit 图片

系统学习 Svelte,欢迎入手小册《Svelte 开发指南》。语法篇、实战篇、原理篇三大篇章带你系统掌握 Svelte!

此外我还写过 JavaScript 系列TypeScript 系列React 系列Next.js 系列冴羽答读者问等 14 个系列文章, 全系列文章目录:github.com/mqyqingfeng...

欢迎围观我的"网页版朋友圈"、加入"冴羽·成长陪伴社群",踏上"前端大佬成长之路"

相关推荐
weixin_382395232 小时前
为小工厂量身打造:本地部署的物料管理系统带缺料计算
前端·制造
__zRainy__3 小时前
解决pnpm v10+不自动构建
前端·pnpm·工程化
猫猫不是喵喵.3 小时前
Vue3 Props 属性
前端·javascript·vue.js
醉城夜风~4 小时前
CSS元素显示模式(display)
前端·css
AI大模型-小华5 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子7 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅7 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni8 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学9 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端