图片优化

图片优化是减少表示图像的字节数的过程。图像大小越小,加载速度越快。图像大小越小,占用的带宽越少。占用的带宽越少,对用户的体验越好,尤其是在移动网络上。

响应式图片

Qwik 支持响应式图片。

这是一个内置功能,依赖于 vite-imagetools 模块,因此不需要安装额外的包或组件。

工作原理

  • src 文件夹导入任何图像
  • 图像会被转换为多个 webp 图像,每个断点一个(200px、400px、600px、800px、1200px)
  • 图像会被处理和优化以减小其大小
  • 使用 srcset 属性渲染一个 <img> 元素,为多个分辨率设置图像源
  • 现在,浏览器将加载适合当前分辨率的最合适的图像

要点

社区和 Qwik 团队喜欢这个 API 的原因有很多:

  • 零运行时,零 JS
  • 默认情况下零 props,简单的 API
  • 零 404,强类型 API
  • 零布局回流(自动宽度/高度)
  • 哈希图像,不可变缓存
  • 自动 .webp / .avif 格式优化
  • 自动生成 srcSet
  • 可扩展(使用任何 <img> 属性)
  • 默认懒加载和异步解码
  • 轻量级,在 HTML 中只有一个 <img> 节点

用法

在导入的末尾添加 ?jsx 后缀

import Image from '[IMAGE_PATH]?jsx';

在模板中将图像用作组件:

<Image />

结果

此脚本将生成以下 <img> 元素:

<img
 
  decoding="async"
  loading="lazy"
  srcset="
    /@imagetools/141464b77ebd76570693f2e1a6b0364f4b4feea7 200w,
    /@imagetools/e70ec011d10add2ba28f9c6973b7dc0f11894307 400w,
    /@imagetools/1f0dd65f511ffd34415a391bf350e7934ce496a1 600w,
    /@imagetools/493154354e7e89c3f639c751e934d1be4fc05827 800w,
    /@imagetools/324867f8f1af03474a17a9d19035e28a4c241aa1 1200w"
  width="1200"
  height="1200"
>
  • decoding="async":表示图像在解码时不会阻塞页面的渲染。更多信息,请参阅 MDN web 文档
  • loading="lazy":允许浏览器延迟加载图像,直到它在视口中可见,这有助于提高页面加载性能
  • srcset:此属性允许根据设备的屏幕大小和分辨率选择最合适的图像
  • widthheight:设置 widthheight 属性可以防止布局回流,这会影响 CLS 分数

注意: 您还可以通过手动设置这些属性的值来更改默认行为:

  • <Image decoding="sync" loading="eager" />

由于 srcset 属性,浏览器将加载适合设备分辨率的最合适的图像:

原始源大小为 1.5Mb,但现在只有几千字节

示例

import { component$ } from '@builder.io/qwik';
import Image from '~/media/your_image.png?jsx';
 
export default component$(() => {
  return (
    <div>
      <Image />
    </div>
  );
});

自定义图像的 widthheight

您可能需要为图像设置自定义的 width

<Image style={{ width: '300px'}} />

但在这种情况下,您还需要手动指定 height,以避免图像被拉伸:

<Image style={{ width: '300px', height: '200px'}} />

下面是一个简单的技巧,可以避免手动设置 height,同时保持纵横比:

提示: 您应该始终指定 widthheight 值,以防止布局回流

import { component$ } from '@builder.io/qwik';
import Image from '~/media/emote.png?jsx';
 
export default component$(() => {
  return (
    <>
      <h1>图像示例</h1>
      <div class="image-wrapper" >
        <Image />
      </div>
    </>
  );
});
.image-wrapper {
  width: 300px; /* 设置包装器的所需宽度 */
  position: relative; /* 绝对定位所需 */
}
 
.image-wrapper img {
  width: 100%; /* 让图像填充其容器的宽度 */
  height: auto; /* 让浏览器计算高度以保持纵横比 */
  display: block; /* 删除图像下方的任何额外空白 */
}

@unpic/qwik

  • 详细使用说明网站:@unpic/qwik
  • 安装:npm install @unpic/qwik

Unpic 是一个与现有图像优化 CDN 配合使用的第三方图像优化库。它提供了一个 Image 组件,可用于优化图像。

import { component$ } from '@builder.io/qwik';
import { Image } from '@unpic/qwik';
 
export default component$(() => {
return (
<Image
  src="https://cdn.shopify.com/static/sample-images/bath_grande_crop_center.jpeg"
  layout="constrained"
  width={800}
  height={600}
  alt="一个可爱的浴缸"
/>
);
});

注意: qwik-image 和 unpic 不是 CDN,也不托管您的图像。它们与现有的图像优化 CDN 配合使用。我们建议使用一些流行的 CDN:

  • Cloudinary
  • Cloudflare
  • Bunny.net
  • Vercel / Next.js
  • Imgix,包括 Unsplash、DatoCMS、Sanity 和 Prismic
  • Shopify
  • Kontent.ai
  • Builder.io
  • Contentful
  • Storyblok
  • WordPress.com 和 Jetpack Site Accelerator

qwik-image

高性能图像,自动优化。

npm install qwik-image
or
yarn install qwik-image
or
pnpm install qwik-image

这是一个可插拔的组件,因此开发人员可以将不同的图像加载器连接到它上面(如 builder.io 或其他 CDN)

import { $, component$ } from '@builder.io/qwik';
import {
  Image,
  type ImageTransformerProps,
  useImageProvider,
} from 'qwik-image';
 
export default component$(() => {
  const imageTransformer$ = $(
    ({ src, width, height }: ImageTransformerProps): string => {
      // 在这里,您可以设置您喜欢的图像加载器服务
      return `https://cdn.builder.io/api/v1/${src}?height=${height}&width=${width}&format=webp&fit=fill`;
    }
  );
 
  // 全局提供者(必需)
  useImageProvider({
    // 您可以设置此属性以覆盖默认值 [3840, 1920, 1280, 960, 640]
    resolutions: [640],
    imageTransformer$,
  });
 
  return (
    <Image
      layout="constrained"
      objectFit="fill"
      width={400}
      height={500}
      alt="热带天堂"
      placeholder="#e6e6e6"
      src={
        'image/assets%2FYJIGb4i01jvw0SRdL5Bt%2Fe5113e1c02db40e5bac75146fa46386f'
      }
    />
  );
});

这是带有详细使用说明和自定义的 Github 仓库:qwikifiers/qwik-image

Contributors

Thanks to all the contributors who have helped make this documentation better!

  • mhevery
  • gioboa
  • fabiobiondi