- UI组件
- 前端
【免费下载链接】ng-zorro-antd
Angular UI Component Library based on Ant Design
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。原因有二:
- 提升 CLS(Cumulative Layout Shift)指标:固定图片尺寸后,页面在图片加载完成前就能预留正确的占位空间,减少布局抖动;
- 配合 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 可以看到完整的计算链路:
- 将
nzWidth/nzHeight解析为数字(字符串如"200px"会被parseInt提取); - 基于预设的断点数组
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 工程博客关于超高分辨率设备截断图片保真度的实践);
src取第一档宽度(widths[0])调用 Loader 生成;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 | 图片 URL | string | - | |
nzAlt | 替代文本 | string | - | |
nzWidth | 宽度 | number \| string | auto | |
nzHeight | 高度 | number \| string | auto | |
nzAutoSrcset | 是否自动生成响应式 srcset | boolean | false | ✅ |
nzSrcLoader | 图片解析 Loader | NzImageSrcLoader | defaultImageSrcLoader | ✅ |
nzPriority | 是否添加 preload | boolean | false | |
nzFallback/nzPlaceholder/nzDisablePreview | 兜底图 / 占位图 / 禁用预览 | 见源码 | null/null/false | ✅ |
其中支持全局配置的三项(nzAutoSrcset、nzSrcLoader、nzFallback、nzPlaceholder、nzDisablePreview)都可以通过第四节介绍的provideNzConfig统一注入。
九、深入验证:测试用例如何锁定 Loader 行为
仓库的 image.spec.ts 从三个层面锁定了 Loader 的行为契约,可作为自定义实现时的参考基准:
- 组件集成层:默认不生成
srcset;nzAutoSrcset开启后srcset为src 1x, src 2x;自定义 Loader 参与src/srcset生成; - 工具函数层:
isFixedSize只接受数字与Npx字符串;normalizeSrc会去除开头的/; - 内置 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
相关推荐
ng-zorro-antd Empty 空状态组件:自定义图片、描述与 Footer 附属内容实战
ng zorro antd Empty 空状态组件:自定义图片、描述与 Footer 附属内容实战 本篇技术文章以 ng zorro antd 中 Empty
UI组件前端ng-zorro-antd Calendar 日历组件自定义头部(nzCustomHeader)实战指南
ng zorro antd Calendar 日历组件自定义头部(nzCustomHeader)实战指南 本文是一份围绕 ng zorro antd(Angul
UI组件前端从源码到部署:CrowdStrike CRT内部工作原理与自定义扩展终极指南
从源码到部署:CrowdStrike CRT内部工作原理与自定义扩展终极指南 CrowdStrike CRT(CrowdStrike Reporting Too
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考