首先给出第一个问题的答案:所有的图片,包括前端切图使用的图片,以及接口返回的业务图片,都应当放专门的图片oss服务器上。好处有如下一堆。
减少项目的大小
普通的toB/toC项目
如果在项目中有一堆图片文件,每次打包的时候,都会重新拷贝、拉取、上线一遍,多少会影响发版效率
小程序类项目
这个对项目包大小要求更加苛刻,小程序不分包的话,限制2M,而一个图片,很可能比一堆js+css都要大
小程序项目包的大小,直接影响了小程序启动的白屏时间
减少使用项目内图片的复杂性
如果图片是在项目内部的,使用的话要么是通过import、require引入,要么是通过相对路径去引用。
import defaultPic from '@/theme/assets/noDataImg.png';
这两种方法,都会带来一定的复杂性
- coding的时候需要注意路径的引入
- webpack等构建工具打包的时候,会多花时间来处理这些引入文件
- 而且使用不同框架的时候,会有不同的处理方式,某些比较复杂的场景,还会造成发布到线上之后,图片地址丢失的问题。
而使用了图片oss之后,图片都是返回的绝对地址,这个时候,你就可以直接在项目中一把梭了
借助oss的cdn节点能力
对于普通的toB/toC项目,前端服务器可能就是2、4、6、8台不等,基本上能到8台服务器的,已经是算不小的前端项目了。而oss服务器,都配置了基本的cdn的内容分发,全国多个节点可以加速访问,从这点来看,图片加载效率可以获得极大的提升。
基本上来说,图片oss都非常高效+稳定,图片放上去之后,可以放心的访问
图片oss设置的缓存时间
前端的项目服务器,通常也会通过Nginx来设置静态资源的缓存时间,但是为了在发版的时候能够快速更新,这个缓存的时间,也就是5分钟或者10分钟。
这个时候,图片oss的缓存就大不相同了,之前用过的两个图片oss,一个缓存时间是365天,另外一个的缓存时间略短,30天。这种按月/年级别的缓存时间,对比按分钟级别的缓存,差异很明显。
不过这里的图片oss缓存时间过长,对前端更新图片稍微带来点问题
- 如果是上传之后自动生成不同名称的图片oss,则需要前端项目中替换图片链接
- 如果是上传之后覆盖原始图片链接的那种oss,需要先将本地图片修改一下名字,然后再行上传图片,获取新的图片链接,前端进行替换
图片oss的多域名处理
大家都知道,浏览器加载同一域名的资源,会有并发的限制。因此,图片oss,通常不只一个域名;但考虑到dns解析的时间,域名也不会过多,据观察,域名大多在4-6个。
而且,网站在请求相同域名静态资源的时候,也会把cookie带上去,这种携带是多余的,会造成客户端+服务端流量的浪费,因此,图片oss的域名,是与主站不同的,减少了cookie的额外传输
。
某东的PC端首页抓包
某没落视频网站
图片oss对图片的url参数处理
图片服务器,会直接在图片url上添加参数,进行压缩、转换、降质等一系列处理,此处及其重要!!!
图片缩放
我们经常遇到这种场景,一个图片,在列表中需要缩略图(比如需要展示为80x80),点击之后需要展示原始图片(比如1280x960)。
这个时候,如果在列表中均按原始图片返回的话,性能+流量上,都会有问题。
让后端接口返回两个地址?这个倒是可行,不过比较麻烦,如果哪天你的列表缩略图尺寸修改了呢?
这个时候,如果你的图片oss支持图片缩放,那就再简单不过。
还是以某东为例,如下三张图片,分别是首页、list页、商详页里面的图片,内容完全一致,但尺寸不一样。
我们抓包看一下此三张图片地址:
https://img11.360buyimg.com/babel/s100x100_jfs/t1/119581/20/16562/153554/5f6429c1Edb18bfdd/71bcaa1e46916c14.jpg
https://img10.360buyimg.com/babel/s200x200_jfs/t1/119581/20/16562/153554/5f6429c1Edb18bfdd/71bcaa1e46916c14.jpg
https://img11.360buyimg.com/babel/jfs/t1/119581/20/16562/153554/5f6429c1Edb18bfdd/71bcaa1e46916c14.jpg
可以看到,图片名称相同,只是在地址上有处理,分别为: /s100x100_jfs/
/s200x200_jfs/
/jfs/
,意思是将同一张图片,按不同的尺寸返回,前两者是返回了对应的尺寸,第三种是直接返回了原图。
图片大小对比也很明显:8.2kb vs 21.9kb vs 154kb
格式转换
图片最近几年有一种流行的图片格式——webp,该格式质量好、压缩比高,是个性能优化的利器,后面文章也会讲到webp。
但是webp格式不像jpg、png那样普遍,需要经过转换或者处理才能是webp格式。
之前看过一些webp的实践文章,不少的文章篇幅是讲如何使用node等工具,将原来的jpg/png图片,转换成webp格式的。殊不知现在主流的图片oss,早已经支持了webp格式的参数转换。
以上面大图片为例,https://img11.360buyimg.com/babel/jfs/t1/119581/20/16562/153554/5f6429c1Edb18bfdd/71bcaa1e46916c14.jpg,如果需要转换成webp格式的话,十分简单,在url后面添加上 .webp
即可,地址为:https://img11.360buyimg.com/babel/jfs/t1/119581/20/16562/153554/5f6429c1Edb18bfdd/71bcaa1e46916c14.jpg.webp
大家可以抓包看一下图片大小的对比: jpg vs webp :154kb vs 89.8kb
,也是比较明显的对比
降低质量加载
大家都知道jpg图片是有损压缩,是以一部分图片质量的损耗来换取图片大小的降低。为此,图片oss通常也会支持jpg图片格式的降质
还是以上面大图片为例,https://img11.360buyimg.com/babel/jfs/t1/119581/20/16562/153554/5f6429c1Edb18bfdd/71bcaa1e46916c14.jpg,现在把它的质量降低为80%,在url后面添加上!q80
就可以,地址为:https://img11.360buyimg.com/babel/jfs/t1/119581/20/16562/153554/5f6429c1Edb18bfdd/71bcaa1e46916c14.jpg!q80。
图片大小的对比: 原始jpg vs 80%质量jpg :154kb vs 120kb
,压缩成果也比较明显。
不过这个是靠损失质量来达到的压缩图片目的,质量降低越多,图片会越模糊,因此不能将质量压到太低
其余url参数处理
- 图片水印
- 矩形、圆形裁剪
- 旋转
- 获取图片信息,宽高、大小、格式等
- 模糊、亮度/对比度处理等
如上的一些处理,平常业务开发可能遇到比较少,但如果真的遇到的话,相对比其余的前后端处理方式,直接通过url上挂载参数来处理图片,简直不要高效的太多!
看看大厂们的做法
目前很多大厂,都有自己的云,基本上都会自己做图片服务器,不同厂家的图片oss,基本上都实现了上面的那几个核心的图片处理。
比较知名的云服务商,对图片处理更是标配,如下图的阿里云、七牛云。
结尾
图片oss的使用,完全是好处没有坏处么?
也有,因为图片上了云端了,本地可能不会存储,因此对图片的管理、复用,比图片放在前端项目中要麻烦一些。
但是,也仅有这个问题而且,跟oss的好处相比,这点还是微不足道的。
因此,大力使用吧!