☰
ng-zorro-antd 实验性 Image 组件 `nzSrcLoader` 使用指南:自定义与内置图片 CDN Loader 全解析
2026/9/26 11:31:35 网站建设 项目流程
  • UI组件
  • 前端

【免费下载链接】ng-zorro-antd

Angular UI Component Library based on Ant Design

项目地址:https://gitcode.com/gh_mirrors/ng/ng-zorro-antd
点击查看免费下载

ng-zorro-antd 的实验性 Image 组件(nz-image)通过nzSrcLoader将原始图片地址解析/转换为最终请求 URL,是接入图片 CDN 进行裁剪、缩放、格式优化以及生成响应式srcset的关键入口。本文基于仓库中的 src-loader 示例文档 展开,结合 image-loader.ts、image.component.ts 与测试用例,完整讲解内置 Loader 的用法、自定义 Loader 的写法、按环境切换 Loader 的全局配置方案,以及如何配合nzWidth/nzHeight提升加载体验。读完本文,你将能够在项目中熟练配置与编写图片 Loader。

一、认识nzSrcLoader:图片 URL 的解析层

在 ng-zorro-antd 实验性 Image 组件中,nzSrcLoader是一个纯函数类型,负责把"原始图片路径 + 期望宽度"映射为"最终的请求 URL"。其类型定义位于 typings.ts:

export type NzImageSrcLoader = (params: { src: string; width?: number }) => string;

它接收一个对象参数,包含:

  • src:组件传入的原始图片地址(nzSrc);
  • width:期望的图片宽度(可选,仅在开启优化时由组件计算后传入,如nzAutoSrcset场景)。

返回值是字符串形式的最终 URL。

默认 Loader:原样返回

当不配置任何 Loader 时,组件使用内置的defaultImageSrcLoader,其实现(见 image-loader.ts)非常简单:

export const defaultImageSrcLoader: NzImageSrcLoader = ({ src }) => { return src; };

即"传入什么就返回什么",不做任何改写。测试用例(见 image.spec.ts)也验证了默认行为:不开启任何优化时,<img>的src为原地址,且不会生成srcset属性。

二、使用内置的图片 CDN Provider Loader

仓库为三种常见的图片 CDN 服务商提供了开箱即用的 Loader 工厂函数,全部位于 image-loader.ts。

1.createAliObjectsLoader(domain):阿里云 OSS 对象存储

返回的 URL 格式为:

{domain}/{src}?x-oss-process=image/resize,w_{width}

对应实现(见 image-loader.ts):

export function createAliObjectsLoader(domain: string): NzImageSrcLoader { return ({ src, width }) => { const params = isNil(width) ? '' : `?x-oss-process=image/resize,w_${width}`; return `${domain}/${normalizeSrc(src)}${params}`; }; }

典型用法(与官方文档示例一致,见 src-loader.ts):

import { createAliObjectsLoader } from 'ng-zorro-antd/experimental/image'; loader = createAliObjectsLoader('https://zos.alipayobjects.com/rmsportal');

当给定src = 'jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'、width = 100时,会生成:

https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png?x-oss-process=image/resize,w_100

这一预期行为在 image.spec.ts 中有对应测试断言。

2.createImgixLoader(domain):Imgix

返回的 URL 格式为:

{domain}/{src}?format=auto&fit=max&w={width}

实现(见 image-loader.ts):

export function createImgixLoader(domain: string): NzImageSrcLoader { return ({ src, width }) => { const params = isNil(width) ? '' : `&fit=max&w=${width}`; return `${domain}/${normalizeSrc(src)}?format=auto${params}`; }; }

?format=auto表示让 Imgix 自动选择最优图片格式;当提供width时追加&fit=max&w={width}进行自适应缩放。测试断言见 image.spec.ts。

3.createCloudinaryLoader(domain):Cloudinary

返回的 URL 格式为:

{domain}/c_limit,q_auto,w_{width}/{src}

实现(见 image-loader.ts):

export function createCloudinaryLoader(domain: string): NzImageSrcLoader { return ({ src, width }) => { const params = isNil(width) ? '' : `,w_${width}`; return `${domain}/c_limit,q_auto${params}/${normalizeSrc(src)}`; }; }

c_limit表示限制裁剪范围、q_auto表示自动质量,与宽度的组合以路径片段形式拼接在域名与src之间。测试断言见 image.spec.ts。

关于normalizeSrc

三个工厂函数都调用了工具函数normalizeSrc(见 utils.ts),它会去掉src开头的/,避免拼接时出现domain//path这类双斜杠问题:

export function normalizeSrc(src: string): string { return src[0] === '/' ? src.slice(1) : src; }

对应测试见 image.spec.ts。

三、自定义 Loader:对接任意图片服务

内置 Loader 只覆盖三种 CDN。如果你的图片服务来自自建对象存储、其他 CDN 或私有网关,只需自行实现一个符合NzImageSrcLoader类型的函数即可。例如在 demo 文档中展示的自定义 loader 写法(见 image.spec.ts 中的测试场景):

const loader: NzImageSrcLoader = ({ src, width }) => `${src}?w=${width}`;

将它与nzAutoSrcset配合使用时,测试断言最终生成的srcset为:

test.jpg?w=128 1x, test.jpg?w=256 2x

自定义 Loader 可以:

  • 拼接鉴权参数(token、时间戳签名);
  • 对接公司内部图片处理服务的缩放参数;
  • 统一加上 CDN 前缀或路径规则。

只要保证"输入{ src, width },输出完整可请求的 URL",就可以自由接入任何服务。

四、按环境切换 Loader:通过全局配置注入

真实项目中,开发环境与生产环境往往使用不同的图片服务。官方文档给出了标准的做法——利用 ng-zorro-antd 的全局配置机制provideNzConfig按环境注入不同的 Loader(完整示例见 src-loader.md):

import { environment } from 'environments/environment'; import { NzConfig, provideNzConfig } from 'ng-zorro-antd/core/config'; import { createAliObjectsLoader, defaultImageSrcLoader } from 'ng-zorro-antd/experimental/image'; const nzConfig: NzConfig = { imageExperimental: { nzSrcLoader: environment.production ? createAliObjectsLoader('https://zos.alipayobjects.com/rmsportal') : defaultImageSrcLoader } }; export const appConfig: ApplicationConfig = { providers: [provideNzConfig(nzConfig)] };

要点解读:

  • 配置键名:imageExperimental。在源码中,组件通过NZ_CONFIG_MODULE_NAME: NzConfigKey = 'imageExperimental'声明了自己的全局配置键(见 image.component.ts),因此NzConfig中对应字段就是imageExperimental。
  • 优先级:nzSrcLoader同时支持组件级@Input()和全局配置。组件属性上同时标注了@Input() @WithConfig()(见 image.component.ts),即组件实例上显式传入的 Loader 会覆盖全局配置;未传时回落到全局配置,再回落到defaultImageSrcLoader。
  • 响应式更新:构造函数中注册了onConfigChangeEventForComponent(NZ_CONFIG_MODULE_NAME, ...),当全局配置在运行时发生变化(例如环境切换后重新注入配置)时,组件会自动重新计算src/srcset并触发变更检测(见 image.component.ts)。
  • 加载时机:composeImageAttrs()会在ngOnChanges中对nzSrc、loader 相关输入变化时被调用,保证图片地址与配置保持一致(见 image.component.ts)。

五、务必指定图片尺寸:Loader 优化的前提

文档中特别强调:始终为图片指定nzWidth与nzHeight。原因有二:

  1. 提升 CLS(Cumulative Layout Shift)指标:固定图片尺寸后,页面在图片加载完成前就能预留正确的占位空间,减少布局抖动;
  2. 配合 Loader 优化:只有知道目标宽度,Loader 才能生成带缩放参数的 URL(例如 AliObjects 的resize,w_xxx),也才能开启nzAutoSrcset生成响应式srcset。

在组件层面,这一前提由optimizable()方法强制执行(见 image.component.ts):

private optimizable(): boolean { if (this.nzAutoSrcset) { if (!isFixedSize(this.nzWidth) || !isFixedSize(this.nzHeight)) { warn(`When using "nzAutoSrcset" you should use a fixed size width and height...`); return false; } ... } return false; }

也就是说,开启nzAutoSrcset时若尺寸不是固定值(isFixedSize只接受数字或Npx字符串,见 utils.ts),组件会发出警告并跳过优化。

六、nzAutoSrcset:让 Loader 自动生成响应式srcset

nzAutoSrcset是实验性图片组件中与 Loader 协同工作的核心开关(默认false,支持全局配置)。开启后,组件会为不同像素密度自动生成srcset(详见 auto-srcset.md):

<nz-image [nzSrc]="src" nzWidth="200" nzHeight="200" [nzSrcLoader]="loader" nzAutoSrcset />

demo 完整代码见 auto-srcset.ts。

生成原理:宽度档位与 1x/2x

从 image.component.ts 可以看到完整的计算链路:

  1. 将nzWidth/nzHeight解析为数字(字符串如"200px"会被parseInt提取);
  2. 基于预设的断点数组sizeBreakpoints = [16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840](见 image.component.ts),由convertWidths计算档位——取"目标宽度"与"目标宽度 × 2"各自向上取整到最近断点的结果(去重):
    [width, width * 2].map(w => allSizes.find(p => p >= w) || w)

    注释说明"2x 缩放已足够"(参考自 Twitter 工程博客关于超高分辨率设备截断图片保真度的实践);

  3. src取第一档宽度(widths[0])调用 Loader 生成;
  4. srcset将各档位依次交给 Loader 生成 URL,并拼接1x、2x密度描述符:
    this.srcset = widths .map((w, i) => `${loader({ src: this.nzSrc, width: w })} ${i + 1}x`) .join(', ');

因此对 200px 宽的图片,实际生成的srcset约为:

.../image.png?x-oss-process=image/resize,w_256 1x, .../image.png?x-oss-process=image/resize,w_384 2x

(200 向上取整到 256,400 向上取整到 384——两个档位去重后的结果,测试中断言w=128 1x, w=256 2x与此逻辑一致,见 image.spec.ts。)

优化排除场景

optimizable()还定义了两种不进行优化的情况(见 image.component.ts):

  • src以.svg结尾:矢量图无需按位图缩放优化;
  • src以data:开头:Data URL 本身无法通过 CDN 优化。

这两种情况都会触发warn提示并直接回落为普通加载。

七、nzPriority:SSR 下的高优先级预加载

与 Loader 同属实验性图片组件能力的还有nzPriority(见 preloading.md)。设置后,在服务端渲染(SSR)时会输出<link rel="preload">标签,浏览器会将对应图片视为高优先级资源提前加载;组件内部通过ImagePreloadService.addPreload(见 image.component.ts)实现,该服务会在 image-preload.ts 中为预加载链接节点设置rel="preload"。

实践中只需为首屏图片开启该选项,循环生成的列表中仅对靠前项添加即可:

@for (product of products; track product) { <nz-image [nzPriority]="$index <= 8" /> }

八、从源码到实践:组件输入一览

下表汇总实验性图片组件的全部输入(依据 image.component.ts 与 doc/index.zh-CN.md 中的 API 表):

参数说明类型默认值支持全局配置
nzSrc图片 URLstring-
nzAlt替代文本string-
nzWidth宽度number \| stringauto
nzHeight高度number \| stringauto
nzAutoSrcset是否自动生成响应式 srcsetbooleanfalse✅
nzSrcLoader图片解析 LoaderNzImageSrcLoaderdefaultImageSrcLoader✅
nzPriority是否添加 preloadbooleanfalse
nzFallback/nzPlaceholder/nzDisablePreview兜底图 / 占位图 / 禁用预览见源码null/null/false✅

其中支持全局配置的三项(nzAutoSrcset、nzSrcLoader、nzFallback、nzPlaceholder、nzDisablePreview)都可以通过第四节介绍的provideNzConfig统一注入。

九、深入验证:测试用例如何锁定 Loader 行为

仓库的 image.spec.ts 从三个层面锁定了 Loader 的行为契约,可作为自定义实现时的参考基准:

  1. 组件集成层:默认不生成srcset;nzAutoSrcset开启后srcset为src 1x, src 2x;自定义 Loader 参与src/srcset生成;
  2. 工具函数层:isFixedSize只接受数字与Npx字符串;normalizeSrc会去除开头的/;
  3. 内置 Loader 层:逐个断言 AliObjects、Imgix、Cloudinary 三种 Loader 在有/无width两种输入下的精确输出 URL 格式。

十、总结:Loader 使用决策速查

  • 不接 CDN:什么都不配,使用默认defaultImageSrcLoader;
  • 接阿里云 OSS:createAliObjectsLoader(domain);
  • 接 Imgix:createImgixLoader(domain);
  • 接 Cloudinary:createCloudinaryLoader(domain);
  • 接其他服务:自行实现({ src, width }) => string类型的函数;
  • 多环境差异化:用provideNzConfig在imageExperimental.nzSrcLoader处按环境注入;
  • 追求最佳加载体验:始终传nzWidth/nzHeight,需要响应式时开启nzAutoSrcset,首屏图片追加nzPriority。
  • UI组件
  • 前端

【免费下载链接】ng-zorro-antd

Angular UI Component Library based on Ant Design

项目地址:https://gitcode.com/gh_mirrors/ng/ng-zorro-antd
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询