# 前端的图片优化方案你知道多少
# 使用 base64 编码代替图片
场景:适用于图片大小小于 2KB,页面上引用图片总数不多的情况
原理:将图片转换为base64
编码字符串inline
到页面或css
中
优势:减少http
的请求次数,并可以放到后台数据库中,只传输字符串,有较多的构建工具可以直接实现
劣势:这种方法仅限于图片总数较少,而且图片大小小于 2KB的情况。否则图片字符串会变得很长很长
# 合并图片 sprite(雪碧图)
场景:任何用到页面图片的场景
原理:将多个页面上用到的背景图片合并成一个大的图片, 然后在页面中以 css
的 background-position
属性来定位引用。
优势:可以有效的较少请求个数,而且,而不影响开发体验,使用构建插件可以做到对开发者透明。适用于页面图片多且丰富的场景。
劣势:生成的图片体积较大,减少请求个数同时也增加了图片大小,不合理拆分将不利于并行加载
# 使用 css、svg、canvas 或 iconfont 代替图片
# css 代替图片
场景:适用于移动端或较高级的浏览器,而且绘制的图案较为简单。
原理:css
方式可以用来绘制相对简单的图案来代替图片,一般使用before
或者after
伪元素来丰富图案的复杂度。
优势:具有实现简单,图片体积小的特点,可以实现简单的动态效果
劣势:也受限于css
的兼容性特点,绘制复杂图案困难
svg 的描述和适用场景上文已说明。
# canvas 代替图片
场景:需要高性能的图片或动画
原理:适用html5
的canvas
元素绘制创建图片
优势:整个就是画 2D 图形时,页面渲染性能比较高,页面渲染性能受图形复杂度影响小,性能只受图形的分辨率的影响,画出来的图形可以直接保存为 .png 或者 .jpg 的图形,适合于画光栅图像或者不规则图形
劣势:没有 dom 操作,必须依赖定时器,文字渲染性能差,不能添加描述(title 属性什么的),兼容性限制
# iconfont 代替图片
iconfont
是一种web字体
来代替图片的解决方案
场景:代替页面上色彩单一的图片
原理:web 字体库
优势:兼容性好,应用广,目前使用也很广泛
劣势:但是由于字体的颜色设置单一,只能用于代替颜色单一的图片,对于色彩复杂的图片,iconfont 处理起来比较困难
# 响应式图片
场景:不同终端对同一个图片需求不一样,可以根据终端加载不同的图片来节省没必要的流量
原理:通过picture
元素,picturefill
或平台判断来为不同终端平台输出不同的图片
优势:减少没必要的图片加载,灵活控制,慢速用户加载小图片不至于加载失败,移动端没必要加载大尺寸图片等,可以通过不同方式兼容所有浏览器
劣势:无法避免图片的加载过程,图片本身没优化
# 图片压缩
场景:在不得不加载图片的前提下,要进一步提升优化效果,只能通过有损或无损压缩来减少图片的大小。
原理:对图片进行无损、有损压缩,转为压缩后图片来实现
优势:减少图片加载流量,效果比较明显
劣势:服务器和浏览器压力增大,而且服务器需要额外的服务支持
# 更好的图片格式
场景:之前说到webp、bpg、sharpP
等新图片格式具有更好的压缩比,可以使用这类新型的图片来代替原始图片
原理:对图片格式转换,在画质可以接受的情况下达到更好的压缩比效果
优势:减少图片加载流量,效果比较明显
劣势:服务器和浏览器压力增大,而且服务器需要额外的服务支持,格式转换要考虑浏览器的兼容性
# 开启 CDN 加速
场景:在宣传类、酷炫类网站首页,可能会用大量的高清图片,可以上传至CDN
服务器来加速资源响应速度
原理:CDN
的全称是Content Delivery Network
,即内容分发网络,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率
优势:加快图片资源的请求速度,提高渲染效率,减少用户的等待时间
劣势:有些 cdn 服务器需要付费,增加网站成本,而且图片部署至 cdn 也要花费人力时间
# 图片懒加载/延迟加载
场景:在一些需要展示大量图片的 PC 网站或者移动端中,需要使用图片懒加载来提高页面渲染速度
原理:暂时不设置图片的src
属性,而是将图片的url
隐藏起来,比如先写在data-src
里面,等某些事件触发的时候(比如滚动到可视区域,点击加载图片)再将图片真实的url
放进src
属性里面,从而实现图片的延迟加载
优势:可以提高页面的渲染速度,减少不友好的白屏效果,提升用户体验
劣势:由于监听滚动事件和实时获取 DOM 的位置信息,操作 img 标签也相当于操作 DOM 结构,会造成页面回流,性能不好
# 图片预加载(补充)
在一些需要展示大量图片的网站,实现图片的提前加载。从而提升用户体验。常用的方式有两种,一种是隐藏在css
的background
的url
属性里面,一种是通过javascript
的Image
对象设置实例对象的src
属性实现图片的预加载。
看下两种实现方式:
# CSS 预加载图片方式
#preload-01 {
background: url(http://domain.tld/image-01.png) no-repeat -9999px -9999px;
}
#preload-02 {
background: url(http://domain.tld/image-02.png) no-repeat -9999px -9999px;
}
#preload-03 {
background: url(http://domain.tld/image-03.png) no-repeat -9999px -9999px;
}
# Javascript 预加载图片的方式
function preloadimages(arr) {
let newimages = [],
loadedimages = 0;
let postaction = function() {}; //此处增加了一个postaction函数
let arr = typeof arr != 'object' ? [arr] : arr;
function imageloadpost() {
loadedimages++;
if (loadedimages == arr.length) {
postaction(newimages); //加载完成用我们调用postaction函数并将newimages数组做为参数传递进去
}
}
for (var i = 0; i < arr.length; i++) {
newimages[i] = new Image();
newimages[i].src = arr[i];
newimages[i].onload = function() {
imageloadpost();
};
newimages[i].onerror = function() {
imageloadpost();
};
}
return {
//此处返回一个空白对象的done方法
done: function(f) {
postaction = f || postaction;
}
};
}
# 图片压缩方法(补充)
压缩图片方式比较多,这里不一一列出,例如下面的部分工具平台:
智图主页 支持原图
png
转为jpeg
和webp
(目前不支持 bpg),并提供各种压缩比压缩,目前在tx
内部广泛使用。 目前 bpg 格式图片也有部分公司在试用。这方面也可以尝试下。
# 最后
文中若有不准确或错误的地方,欢迎指出,有兴趣可以的关注下Github,一起学习呀~~