上篇文章,Brotli压缩算法在WEB中的应用最佳实践,介绍了js、css、html文件压缩优化技术,对于前端性能优化图片优化的重要性不下于js等文件的优化,本篇文章着重介绍图片压缩、图片下载等多种图片优化技术。
一、图片优化之图片压缩
什么是最佳的图片压缩,能实现如下3点就是最佳的图片压缩:
1、大幅度缩小图片大小
2、图片质量不降低
3、方便快捷
介于上述3点,经调研实践,得出基于tinify算法的图片压缩脚本开发为最佳实践,其优势在于:
1、图片可减小大小80%
2、tinify算法处理图片对质量的影响肉眼几乎无法分辨
3、脚本一键启用,复用方便,可以用于任何vue、react等项目
代码如下:
javascript
//compress-image.js
const fs = require('fs')
const path = require('path')
const tinify = require('tinify')
// 这个key上官网申请,邮箱注册即可
tinify.key = 'Qv29t*****kwHxs'
// 获取项目根目录
const projectRoot = process.cwd()
// 定义 assets 目录的路径
const assetsDir = path.join(projectRoot, 'src/assets')
// 获取项目中的所有图片文件
const imageFiles = getImageFiles(assetsDir)
// 压缩每个图片文件并保留原始文件名
imageFiles.forEach(file => {
const filePath = path.resolve(assetsDir, file)
const source = fs.readFileSync(filePath)
try {
tinify.fromBuffer(source).toFile(filePath, err => {
if (err) {
console.log(`Error compressing ${file}: ${err}`)
} else {
console.log(`${file} has been compressed`)
}
})
} catch (err) {
console.log(`Error compressing ${file}: ${err}`)
}
})
function getImageFiles(directoryPath) {
let images = []
// 获取目录下的文件列表
const files = fs.readdirSync(directoryPath)
files.forEach(function(file) {
const filePath = path.join(directoryPath, file)
// 检查文件的类型
if (fs.statSync(filePath).isFile()) {
// 检查文件扩展名是否为图片格式(这里只列举了常见的图片格式,根据需要进行调整)
const ext = path.extname(filePath).toLowerCase()
if (ext === '.jpg' || ext === '.jpeg' || ext === '.png') {
images.push(filePath)
}
} else {
// 如果是目录,递归获取该目录下的所有图片文件
const subDirectoryPath = path.join(directoryPath, file)
const subDirectoryImages = getImagesFromDirectory(subDirectoryPath)
images = images.concat(subDirectoryImages)
}
})
return images
}
// 运行
node compress-image.js
压缩效果展示:
二、图片优化之响应式下载
提到响应式下载,不得不提到img标签 srcset 和 sizes这2个属性
srcset属性允许定义多个不同尺寸的图片,然后浏览器将自动选择最适合用户屏幕尺寸的图片,如:
ini
<img srcset="
image/pic_300.jpg 300w,
image/pic_800.jpg 800w,
image/pic_1300.jpg 1300w
"/>
此优势在于在小屏幕上,浏览器将下载一个较小的图像,而大屏幕仍将获得高分辨率的图像。这将显著减少传输给用户的数据量,并加快页面加载速度,繁琐的地方在于你的准备多个图片。srcset也可用在分辨率优化上。
sizes属性必须配合srcset属性一起使用才有效,单独使用无效。但是srcset可以单独使用。
ini
<img
srcset="
image/pic_300.jpg 300w,
image/pic_800.jpg 800w,
image/pic_1300.jpg 1300w
"
sizes="(max-width: 500px) 50vw, (max-width: 800px) 100vw, 1200px"
/>
在定义了sizes属性后,浏览器会依次执行以下操作:
1、查看当前设备宽度;
2、依次检查sizes属性列表中第一个为真的媒体条件;
3、查看该媒体条件对应的槽的大小;
4、通过槽的大小,加载对应的srcset列表中与槽的大小最接近的图像。
三、图片优化之服务器优化
无论是亚马逊服务器还是阿里云服务器都有图片优化技巧。如CDN技术,这里要讲的是服务器根据请求动态处理返回图片尺寸技术,这种方式效果类似于响应式下载,不同在于图片是动态处理的。
阿里云服务可一键开启,亚马逊服务器需自己配置。他们的请求方式类似,都在在请求图片url后面添加图片尺寸参数。需要一定费用。
这种场景通常是用于一次请求数十上百个图片上,原图片尺寸比较大比如宽度为1000px,但我实际之需要100px,此时处理请求尺寸,拿到适合的图片,将大幅度减少图片下载压力。
四、图片优化之取消图片下载
接着上个服务优化技术,在项目业务中有这样的场景,选择电子书阅读,接口一次返回157个书目,页面需要渲染书封面,此时一次请求下载157张图片,大量的请求排队给服务器和浏览器带来压力。这样的场景中测试,电脑8g内存只需切换路由来回点击3次页面几乎卡死。
如何解决了,可以用分页,可以用图片懒加载,也可以用取消图片下载方式。
当路由切换时,页面销毁时,则取消所有在排队的下载任务,这种思路同样也适用于接口请求。
scss
onBeforeUnmount(() => {
if (imgRef.value) {
imgRef.value.src = '' // 设置src为空字符串,取消加载
}
})
取消请求接口与取消图片下载不一样,这里不再赘述。
五、图片优化之懒加载
懒加载优先显示可视区域的图片而不是一次加载全部的图片,当需要显示时,再发送请求加载图片。
懒加载的实现方式很多,可自定义实现,也可以用插件,如vue-lazyload,其实现原理、方式这里不再赘述,推荐用vue-lazyload简单好用。
六、图片优化之阿里巴巴iconfont图标
阿里巴巴矢量图iconfont是非常方便的图标使用方式,你是否因为每迭代一个版本,UI就换一个图标样式而烦恼,同一种含义用不同的图标,同样的图片尺寸、颜色又不一样,此时推荐使用阿里巴巴iconfont,他不仅是很好的图标使用方式,方便三端使用,更重要的是形成UI设计标准。
其使用流程如下:
1、UI设计师按要求设计图标并上传之账户
2、其他开发用户上账户下载使用。
这会增加UI工作量,所以说服你的UI设计师来使用是最麻烦的事情,但是你会发现,越用越好用。
端上使用的方式官网有讲解,这里提供一个最方便,最稳妥的方式:
下载svg图标到本地,使用symbol方式封装svg图标组件。
具体代码不展示了,如果是vite,可以用vite-plugin-svg-icons依赖插件:
javascript
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import path from 'path'
export default () => {
return {
plugins: [
createSvgIconsPlugin({
// Specify the icon folder to be cached
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
// Specify symbolId format
symbolId: 'icon-[dir]-[name]',
}),
],
}
}
七、图片优化之雪碧图
雪碧图是将多个图标组合到一张图片上,减少图片请求次数。这里要说的,大多数项目开发都是赶时间,所以哪有时间去处理图片,调试雪碧图,这种方式常在业务做完后,回头审视项目优化来处理。
八、图片优化之构建优化
构建优化为图片优化最后一步,即在打包构建包阶段。此时不管你是用webpack还是vite都有相应的优化方式,其对图片的压缩可与第一种图片压缩方式叠加效果。
webpack image-webpack-loader
scss
config.module
.rule('images')
.test(/.(png|jpe?g|gif)(?.*)?$/)
// Add image-webpack-loader to optimize images
.use('image-webpack-loader')
.loader('image-webpack-loader')
.options({ bypassOnDebug: true })
.end();
vite vite-plugin-imagemin
php
plugins: [vue(),
// 图片压缩
viteImagemin({
gifsicle: {
optimizationLevel: 7,
interlaced: false
},
optipng: {
optimizationLevel: 7
},
mozjpeg: {
quality: 20
},
pngquant: {
quality: [0.8, 0.9],
speed: 4
},
svgo: {
plugins: [
{
name: 'removeViewBox'
},
{
name: 'removeEmptyAttrs',
active: false
}
]
}
})
]
本文总体介绍图片压缩、图片下载、图片渲染、图标管理、构建优化等多种图片优化手段,希望对你有所帮助。