You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 10中如何将任意格式图片转为压缩AVIF格式展示

Angular 10 页面加载AVIF压缩图实现方案

注意:不要尝试在前端运行时做图片格式转码,客户端转AVIF会占用大量用户设备CPU、内存资源,转码等待时间长,完全违背压缩图片提升加载速度的初衷,最优实现路径是服务端预生成AVIF资源+前端做兼容适配

第一步:提前准备AVIF资源

  • 对存量的jpeg/png/webp原图做批量转码,生成同文件名的.avif版本,压缩质量参数建议设为60-70,同主观画质下AVIF体积比WebP小30%以上,原本5MB的原图基本可以压缩到1MB以内
  • 资源路径和原图保持映射关系即可,比如原图路径/imgs/demoImage.jpeg对应AVIF路径为/imgs/demoImage.avif,不需要修改数据库中原有存储的原图路径字段
  • 给上传流程加自动转码逻辑,后续新上传的图片自动生成对应AVIF副本,不需要手动维护

第二步:Angular 侧适配实现

这套逻辑不需要安装任何第三方依赖,利用原生HTML特性即可实现,Angular 10全版本兼容。

核心实现:用picture标签做兼容降级

直接用原生<picture>标签做格式优先级判断,支持AVIF的浏览器会优先加载AVIF资源,不支持的浏览器自动回退加载原有格式的原图,不会出现裂图问题。
组件模板代码示例:

<picture>
  <!-- 优先加载AVIF压缩资源 -->
  <source srcset="{{avifPath}}" type="image/avif">
  <!-- 不支持AVIF的浏览器匹配原有格式资源 -->
  <source srcset="{{originalImgPath}}" type="{{originalMimeType}}">
  <!-- 兜底img标签,所有浏览器均可识别 -->
  <img 
    [src]="currentRenderSrc" 
    [alt]="imgAlt"
    loading="lazy"
    (error)="handleImgError()"
  >
</picture>

对应组件类中的逻辑:

import { Component, Input, OnInit } from '@angular/core';

@Component({
  selector: 'app-avif-img',
  templateUrl: './avif-img.component.html'
})
export class AvifImgComponent implements OnInit {
  // 业务侧传入原有数据库存储的图片路径即可,不需要改现有业务传参
  @Input() originalImgPath: string;
  @Input() imgAlt: string = '';
  
  currentRenderSrc: string;

  ngOnInit() {
    this.currentRenderSrc = this.avifPath;
  }

  // 自动替换后缀生成AVIF路径
  get avifPath(): string {
    return this.originalImgPath.replace(/\.(jpe?g|png|webp)$/i, '.avif');
  }

  // 获取原图片的MIME类型,供source标签匹配
  get originalMimeType(): string {
    const ext = this.originalImgPath.split('.').pop()?.toLowerCase();
    const mimeMap = {
      jpg: 'image/jpeg',
      jpeg: 'image/jpeg',
      png: 'image/png',
      webp: 'image/webp'
    };
    return mimeMap[ext] || 'image/jpeg';
  }

  // 图片加载失败兜底:AVIF不存在/加载失败时自动切回原图
  handleImgError() {
    if (this.currentRenderSrc !== this.originalImgPath) {
      this.currentRenderSrc = this.originalImgPath;
    }
  }
}

使用方式

封装成公共组件后,业务侧和原来用img标签的逻辑完全一致,直接传入原图片路径即可:

<app-avif-img 
  [originalImgPath]="'https://你的资源域名/imgs/demoImage.jpeg'"
  [imgAlt]="'示例图片'"
></app-avif-img>

避坑说明

  • 不要直接把img标签的src硬改成AVIF路径:Safari 15.4以下版本、IE全版本等老旧浏览器不支持AVIF格式,直接改src会出现裂图
  • 不要在前端用JS/WASM运行时转码:单张5MB的图前端转码需要数百毫秒到数秒,低端移动设备可能直接卡死页面,转码消耗的性能、时间远大于加载AVIF节省的成本,没有实际收益
  • 可以给img标签统一加loading="lazy"做懒加载,进一步减少首屏加载的资源体积

内容的提问来源于stack exchange,提问作者John Mark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 22:09:23