您可以在构建时压缩 angular 个图像资源吗?

Can you compress angular image assets on build?

我想要的

我的资产中有非常大的图像,这会因较慢的网络而大大降低网站速度。 (you can read more about the topic on this lighthouse linked page)


我试过的

我找到的最有前途的指南是 this one here, which describes how to use the imagemin package in combination with the ngx-build-plus 包。

不幸的是,按照教程进行操作后,出现以下错误:

[error] TypeError: Cannot assign to read only property 'main.977fe6373cfd108d.js' of object '#<Object>'
    at ImageminPlugin._callee2$ (/.../node_modules/imagemin-webpack-plugin/dist/index.js:264:48)
    at tryCatch (/.../node_modules/babel-runtime/node_modules/regenerator-runtime/runtime.js:62:40)
     // ...

有什么方法可以在构建时压缩资产图像吗?

Angular Version: 13.1.0

Note: I do not want to know how to upload images to third party storage solutions.
I specifically want to create a compressed version of my static assets on build time.

我绝不会那样做!因为它违反惯例 你应该试试 Firebase storage,他们免费给你 1 GB,而且很容易实现。

如果您有非常大的图像资产,则应将其单独托管在 amazons3 或 Google 云存储等服务中。

除了缩短加载时间和构建速度外,它还有助于根据屏幕分辨率加载图像。您可以使用 lamda/cloud 函数自动执行此操作,也可以手动将图像压缩为不同大小并根据设备分辨率提供它们。

您可以将 gulpfile 与 gulp-responsive or gulp-sharp-responsive 一起使用。 我个人使用后者,因为它支持 AVIF 格式。

要将它很好地集成到您的 Angular 项目中,您可以按照以下步骤操作:

  1. 安装依赖项:npm i --save-dev gulp gulp-sharp-responsive
  2. 在您的项目根目录中创建一个 gulpfile.js,内容如下
const { src, dest } = require("gulp");
const sharpResponsive = require("gulp-sharp-responsive");

const compress = () =>
  src("images/*.{png,jpg}")
    .pipe(
      sharpResponsive({
        formats: [
          // jpeg
          { width: 256, format: "jpeg", rename: { suffix: "-256" } },
          { width: 512, format: "jpeg", rename: { suffix: "-512" } },
          { width: 1024, format: "jpeg", rename: { suffix: "-1024" } },
          // webp
          { width: 256, format: "webp", rename: { suffix: "-256" } },
          { width: 512, format: "webp", rename: { suffix: "-512" } },
          { width: 1024, format: "webp", rename: { suffix: "-1024" } },
          // avif
          { width: 256, format: "avif", rename: { suffix: "-256" } },
          { width: 512, format: "avif", rename: { suffix: "-512" } },
          { width: 1024, format: "avif", rename: { suffix: "-1024" } },
        ],
      })
    )
    .pipe(dest("src/assets/compressed"));

module.exports = {
  compress,
};
  1. 在您的项目根目录中创建一个文件夹,您的未压缩图像文件位于该文件夹中(在此示例中称为 images
  2. 将预安装脚本添加到您的 package.js,以便在每次构建时调用您的 gulpfile
"scripts": {
  "prebuild": "gulp compress",
  // ...
},

如果您现在调用 npm run build,它会压缩您的图像并将它们移动到指定的资产文件夹中,实际上之前 运行 ng build.

现在您可以使用具有 picture/source 组合的图像文件,如以下代码段所示。请记住,源标记的顺序很重要。

<!-- {{image}} is the image name -->
<picture *ngIf="image">
  <!-- avif -->
  <source
    srcset="assets/compressed/{{image}}-256.avif"
    media="(max-width: 512px)"
    type="image/avif"
  />
  <source
    srcset="assets/compressed/{{image}}-512.avif"
    media="(max-width: 1024px)"
    type="image/avif"
  />
  <source
    srcset="assets/compressed/{{image}}-1024.avif"
    media="(max-width: 2048px)"
    type="image/avif"
  />
  <!-- webp -->
  <source
    srcset="assets/compressed/{{image}}-256.webp"
    media="(max-width: 512px)"
    type="image/webp"
  />
  <source
    srcset="assets/compressed/{{image}}-512.webp"
    media="(max-width: 1024px)"
    type="image/webp"
  />
  <source
    srcset="assets/compressed/{{image}}-1024.webp"
    media="(max-width: 2048px)"
    type="image/webp"
  />
  <!-- jpeg -->
  <source
    srcset="assets/compressed/{{image}}-256.jpg"
    media="(max-width: 512px)"
    type="image/jpeg"
  />
  <source
    srcset="assets/compressed/{{image}}-512.jpg"
    media="(max-width: 1024px)"
    type="image/jpeg"
  />
  <source
    srcset="assets/compressed/{{image}}-1024.jpg"
    media="(max-width: 2048px)"
    type="image/jpeg"
  />
  <!-- original -->
  <img src="assets/compressed/{{ image }}-1024.jpg" />
</picture>