你能在构建时压缩有角度的图像资源吗



我想要什么

我的资产中有非常大的图像,这会使网络速度减慢很多。(你可以在这个灯塔链接页面上阅读更多关于这个主题的内容(

  • 我想在构建时压缩它们(ng build --prod(
  • 对于当地发展而言,这是无关紧要的(ng serve(
  • 最理想的情况是,我想为不同的屏幕大小生成多个版本(example.jpg→应变为:example_x265.jpgexample_x128.jpg…(

我尝试了什么

我在这里找到的最有前途的指南是,它描述了如何将imagemin包与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

注意:我不想知道如何将图像上传到第三方存储解决方案
我特别想在构建时创建静态资产的压缩版本。

您可以将gullfile与gulp-responsivegulp-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之前压缩图像并将它们移动到指定的assets文件夹中。

现在,您可以使用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>

如果你有非常大的图像资产,它应该单独托管在类似amazons3或谷歌云存储的服务中。

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

我永远不会那样做!因为它反对集会你应该试试Firebase存储,它们免费给你1 GB,而且很容易实现。

最新更新