浅探前端图片优化

37次阅读

共计 4005 个字符,预计需要花费 11 分钟才能阅读完成。

性能优化是前端开发必不可少的一环,而图片优化又是性能优化中必不可少的一环,但不知道有多少开发者在网页的开发过程中会注意图片的使用,图片使用不当可能会导致网页加载卡顿、网页加载速度慢等问题,这篇文章将会将我以往对图片的处理做个总结。
不同格式图片优劣对比
有人可能会问说好的图片优化呢?怎么说到图片格式了,其实在不同的场景选择使用不同格式的图片就是对图片的一种优化,这是最直接最重要但是最容易被忽略的,现在网页中常用的图片格式有 JPG.PNG.SVG.WebP 等,接下来我们就来介绍它们有何优劣
JPG
JPG 格式的图片应该是使用场景最多的图片的格式了,由于 JPG 格式采用了极其高效的压缩算法,使其能在压缩 50% 甚至 60% 的情况下依旧可以保持不错的图片质量,因此在网站设计中使用类似背景图,轮播图等大图时都会考虑使用 JPG 格式的图片,但是 JPG 始终是有损压缩,在对线条感较强或者颜色比较丰富的图片做人为压缩时,可能会出现失真的情况,同时它也不支持透明度处理
PNG
PNG 格式的图片特点大家都知道,就是高保真无损压缩,当对图片设计有较高要求时,首选 PNG 格式,显示高清细腻,但是它也有明显的问题就是体积过大
SVG
SVG 格式图片有个显著特点就是它是可编程的,是基于 xml 语法的,同时作为矢量图,它可以无限放大而不变形,因此可以方便的对不同手机屏幕做自适应,相比于 PNG 和 JPG 它的体积更小,只有 1kb 甚至更小,但是它最大的缺陷就是渲染成本过高,因此我们在选择一些小且色彩单一的图标时可以考虑使用 SVG 格式的图片,如图一般情况下,我们会将 SVG 格式的图片上传到 iconfont 上,这样不仅方便管理而且方便使用,同时 iconfont 上还有许多其他设计师设计的优秀小图标可以直接拿来使用,是不是很方便呢?
WebP 与 gif
这两兄弟我们一般都是用来展示动图的,但是 WebP 也可以用来展示静态图片,WebP 最大的优点就是无损压缩,体积小,但是浏览器支持太差,我们来看 caniuse 的数据:

从图上可以看到 WebP 格式在苹果设备和 IE 上基本不支持,因此浏览器的不支持是它的硬伤,因此在对动图做展示的时候我们不得不选 gif,即便它的体积很大,渲染开销也大
图片优化方案
图片质量压缩
图片压缩应该是图片优化时最常用的方案,因为很简单,只需要将图片上传到 tinypng 或者智图这类的在线压缩图片平台,对图片进行压缩,就可以较小图片质量
雪碧图
雪碧图经常用来将多个小图标和成一张图片,然后将合成的图片当作背景图片是使用,这样可以减少图片的网络请求,使用之前可能需要请求 10 个网络小图标,而使用之后请求一个就可以搞定,我个人通常使用 gopng 这个网站在线生成,还可以自动生成对应的 css 代码
base64
将一个图片地址进行 base64 编码后会得到一串字符串,将这个字符直接放到 img 的 src 属性上,你会发现浏览器是可以识别这一串字符的,不需要发送网络请求直接解析,这样就可以达到减少网络请求的目的,但是 base64 编码后的图片质量比原图图片质量要大,因此也只会在一些质量较小的图标类图片上面使用,否则得不偿失,常见使用 base64 编码的方案就是 webpack 的 url-loader,举个例子:
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: ‘url-loader’,
options: {
limit: 8192
}
}
]
}
]
}
}
上面的这个配置就是把 8k 一下的通过 url-loader 进行 base64 编码,转换成一串 DataUrl
css 替换简单图标
这个优化方案应该都懂,其实就是在写代码之前先考虑一下设计稿里面的哪些内容是可以通过代码来实现的,能通过代码实现的尽量用代码实现,同时实现的时候多考虑绘制性能,能使用 css3 做 GPU 硬件加速的就尽量使用 css3 属性,这些都能减少图片使用而且不影响渲染性能
响应式图片加载
什么是响应式图片加载?其实就是在不同分辨率的设备上显示不同尺寸的图片,避免资源的浪费,常用的方法就是 css3 的媒体查询 (media query),来看个例子:
@media screen and (max-width: 375px) {
img {
background-image: url(‘phone.png’);
}
}
@media screen and (max-width: 768px) {
img {
background-image: url(‘tablet.png’);
}
}
懒加载
图片懒加载的目的就是为加快页面加载速度而做的,为了不让图片一次全部加载出来,通过将图片地址存放在一个 img 标签的属性上,当图片被滚动到页面上时,在将 src 属性替换成图片地址来达到懒加载的效果
webpack 图片优化
图片压缩
webpack 也可以对图片进行压缩操作,通过 image-webpack-loader 可以对输出的图片进行指定质量的压缩,来看具体例子:
{
test: /\.(png|jpg|gif|svg)$/,
use: [
‘file-loader’,
{
loader: ‘image-webpack-loader’,
options: {
bypassOnDebug: true,
mozjpeg: {
progressive: true,
quality: 65
},
optipng: {
enabled: false,
},
pngquant: {
quality: ’65-90′,
speed: 4
},
gifsicle: {
interlaced: false,
},
// the webp option will enable WEBP
webp: {
enabled: false,
},
limit: 1,
name: ‘[name].[ext]?[hash]’
}
}]
}
上面的配置指定了各个格式的图片的压缩质量,并且通过 hash 编码重新命名输出
合成雪碧图
webpack 的 webpack-spritesmith 插件提供了自动合成雪碧图的功能并且可以自动生成对应的央视文件,非常方便,来看一个具体的例子:
const SpritesmithPlugin = require(‘webpack-spritesmith’)
new SpritesmithPlugin({
src: {
cwd: path.resolve(__dirname, ‘src/asserts’),
glob: ‘*.png’
},
target: {
image: path.resolve(__dirname, ‘src/spritesmith-generated/sprite.png’),
css: path.resolve(__dirname, ‘src/spritesmith-generated/sprite.css’)
},
apiOptions: {
cssImageRef: “src/sprite.png”
}
})
通过上面配置就能将 asserts 目录下的所有 png 文件合成雪碧图,并且输出到对应目录,同时还可以生成对应的样式文件,样式文件的语法会根据你配置的样式文件的后缀动态生成,比如这里我们配置的是 sprite.css, 生成的文件内容就是 css 语法:
.icon-checkout {
background-image: url(src/sprite.png);
background-position: -96px -56px;
width: 34px;
height: 32px;
}
.icon-clock {
background-image: url(src/sprite.png);
background-position: -96px 0px;
width: 56px;
height: 56px;
}
.icon-close {
background-image: url(src/sprite.png);
background-position: 0px 0px;
width: 96px;
height: 96px;
}
如果将配置中的 sprite.css 改成 sprite.scss 那么生成语法就是 scss 的语法:
@mixin sprite-width($sprite) {
width: nth($sprite, 5);
}

@mixin sprite-height($sprite) {
height: nth($sprite, 6);
}

@mixin sprite-position($sprite) {
$sprite-offset-x: nth($sprite, 3);
$sprite-offset-y: nth($sprite, 4);
background-position: $sprite-offset-x $sprite-offset-y;
}

@mixin sprite-image($sprite) {
$sprite-image: nth($sprite, 9);
background-image: url(#{$sprite-image});
}

@mixin sprite($sprite) {
@include sprite-image($sprite);
@include sprite-position($sprite);
@include sprite-width($sprite);
@include sprite-height($sprite);
}
@mixin sprites($sprites) {
@each $sprite in $sprites {
$sprite-name: nth($sprite, 10);
.#{$sprite-name} {
@include sprite($sprite);
}
}
}
这样就可以根据你项目中使用的样式语言去生成所需要的语法,是不是很方便呢?
总结
这篇文章简单介绍网页开发中的各个图片格式的优缺和一些常用的图片优化,希望这篇文章对大家以后在做图片优化时能有所帮助。如果有错误或不严谨的地方,欢迎批评指正,如果喜欢,欢迎点赞收藏

正文完
 0