5

网站优化技巧之图片容量优化

 3 years ago
source link: https://blog.dteam.top/posts/2020-09/optimize-website-image-size.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

图片一直是网站中容量占比最大的部分,合理优化图片容量将会大大提高用户的体验。同时,优化图片容量也会大大减少网站流量的消耗,达到节约流量费用的目的。本文将会从图片格式、图片压缩、图片格式转换三个角度分享优化图片容量的经验。

图片格式选择

图片格式繁多,不同的浏览器对图片支持也略有不同,概览表格可以参见MDN 图像文件类型与格式指南

为了最大限度的通用性,网站通常只考虑以下三种图片: png, jpg, gif(未来如果 webp 能大一统基本不做考虑了)

关于这几种图片的使用场景,我简单总结一下:

  • 优点:无损压缩,质量最好,支持透明背景
  • 缺点:对于色彩丰富的图片容量压缩效果差
  • 推荐场景:有透明背景、颜色简单、对细节质量要求较高的场景。如结构图(架构图、流程图、思维导图等等)、Logo、桌面截图、二维码、条码等等。这些场景绝大多数情况下用 png 会比 jpg 容量更小。
  • 优点:采用有损压缩算法,压缩率较高,支持渐进式加载
  • 缺点:图像细节损失,对于文字可能边缘模糊看不清,不支持透明背景
  • 推荐场景:照片、背景图等总体分辨率较大,对细节要求不高,只关注总体风貌的图片
  • 优点:采用伪色,容量最小,加载最快,这三种格式中唯一支持动图
  • 缺点:色彩细节丢失严重
  • 推荐场景:网站 Logo 图,动图等

注意: gif 不适合存放长时间的动画,容量太大,并且不支持渐进式加载。对于时间长、分辨率较高的动图场景,应该考虑直接用<video>

我们的实践

我们的网站(blog.dteam.top)的文章图片主要有两种,照片和桌面截屏。对于照片采用 jpg,对于截屏采用 png。

对于网页图片用户往往并不在乎太高的质量,更关心的是加载速度,因此合理化压缩图片可以带来更好的用户体验。

在线压缩推荐 tinypng(https://tinypng.com/) ,同时支持 png 和 jpg 图片,使用简单,压缩质量好,建议图片放到版本库之前都先用 tinypng 压缩一遍。

如果本地需要批量压缩可以使用命令行工具,这里推荐下pngquant(只支持 png)和imgopt(同时支持 png 和 jpg),他们都可以很方便的在脚本中进行调用,进行快速批量化的图片压缩,注意合理设置一下量化质量,可以达到更好的压缩效果。

图片格式转换

使用图片格式转换可以选择更优的图片格式进行容量优化,如 png 照片转换成 jpg 可以节省几十倍的容量。

如果目标浏览器支持webp更好(如微信端、Chrome 浏览器等),几乎不作任何选择,一律使用 webp 即可,更好的压缩比,支持动图,几乎成了未来图片格式的不二之选,然而直到今天 webp 也没有实现全平台支持。

关于 webp 的浏览器兼容性可以参见: https://caniuse.com/webp

利用阿里云 CDN 边缘脚本实现自适应转换 webp

脚本部分参考自: https://www.duotela.com/1868.html

在云服务盛行的今天,合理利用云服务带来的便利性可以帮我们解决很多棘手问题。

理论上完全可以在浏览器端添加一个 js,自动判断浏览器是否支持 webp,决定访问 webp 图片或者原图。不过这样在本地的工作量就太大了,每次添加图片还得多转换一个 webp 图片,本地的工作量太大了。我们可以利用阿里云 OSS 的图片转换功能,以及 CDN 的边缘脚本实现浏览器自动使用 webp 图片的功能,本地不作任何处理,不影响原来的开发流程。

我们需要在 OSS 上添加一个 webp 的格式转换,以我们的网站(blog.dteam.top)为例,设置的样式如图:

OSS图片样式入口
OSS样式设置

然后在 CDN 的边缘脚本处新增脚本:

CDN边缘脚本

脚本内容如下:

m1 = and($http_accept, match_re($http_accept, '.*image\/webp.*'))
m2 = match_re($uri, '.+(.JPEG|.jpeg|.JPG|.jpg|.PNG|.png)$')
uri_is_posts = match_re($uri, '^/posts')

if and(m1, m2) {
    if uri_is_posts {
        rewrite(concat($uri, '!webp_watermark'), 'break')
    } else {
        rewrite(concat($uri, '!webp'), 'break')
    }
}

: 这里我使用了rewrite的方案,而不是像参考文章那样使用的redirect,是遵循了雅虎前端最佳实践中的Avoid Redirects这一条,即尽可能避免跳转,以便减少浏览器的请求,加快页面访问速度。通过 Chrome 浏览器的 F12 工具可以看到访问图片链接的时候返回依旧是200,但是content-type却是image/webp,而不是返回301302之后再跳转到真实的图片 URL 上去。

这样就完成了。大家可以试试分别用 Chrome 和 IE(或其他不支持 webp 的浏览器,如 Safari)打开本页,看看 F12 工具返回的图片,同时对比下容量看看。

为了帮助我们优化网站,推荐使用 lighthouse 检测(当前已经集成到 Chrome/Chromium/Edge 浏览器的 F12 工具,不用单独装,也可以使用Insights在线检测),有目的性的优化。

如我们的网站(blog.dteam.top)经过本文内容优化后,当前在 Insights/Lighthouse 的图片容量优化检测已经通过了:

insights图片容量检测

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK