写点什么

通过图片优化,我将网站大小减少了 62%

2019 年 3 月 11 日

通过图片优化,我将网站大小减少了62%

图片是 Web 提供的最基本的一种内容类型。人们都说一张图片胜过千言万语。但如果你一不小心,它也可能占用你好几兆带宽。


虽说 Web 图像应该尽可能清晰明快,但文件大小必须是可管理的,以便保持较快的加载速度,并且应该将数据使用保持在可接受的水平。


在我的网站上,我发现主页的大小超过了 1.1MB,其中图像占了 88%。我也意识到我提供的图片比实际需要的要大(比如分辨率)。显然,还有很大的优化空间。



我开始阅读由 Addy Osmani 撰写的“Essential Image Optimization”电子书(),并开始在我的网站上尝试他的建议。然后我又研究了一些响应式图像方面的知识,并也将其应用在我的网站上。


这样就可以将页面大小降至 445KB,减少了约 62%!



本文将介绍我如何优化主页大小,将其提升到更可管理的水平。


什么是图像压缩?

压缩图像是指在保持可接受的视觉质量水平的同时减小图像文件的大小。我使用imagemin来压缩我网站上的图像。


要使用 imagemin,请确保已安装了 Node.js,然后打开终端窗口,cd 到项目的文件夹,并运行以下命令:


npm install imagemin
复制代码


然后创建一个名为 imagemin.js 的新文件,并粘贴以下内容:


const imagemin = require('imagemin');const PNGImages = 'assets/images/*.png';const JPEGImages = 'assets/images/*.jpg';const output = 'build/images';
复制代码


你可以根据具体的项目结构随意修改 PNGImages、JPEGImages 和 output 的值。


要进行图像压缩,你需要根据要压缩的图像类型安装一些插件。


使用 MozJPEG 压缩 JPEG

为了压缩 JPEG 图像,我使用了 Mozilla 的MozJPEG,它可以通过imagemin-mozjpeg作为 imagemin 的插件使用。你可以通过运行以下命令来安装它:


npm install imagemin-mozjpeg
复制代码


然后将以下内容添加到 imagemin.js 文件中:


const imageminMozjpeg = require('imagemin-mozjpeg');const optimiseJPEGImages = () =>  imagemin([JPEGImages], output, {    plugins: [      imageminMozjpeg({        quality: 70,      }),    ]  });optimiseJPEGImages()  .catch(error => console.log(error));
复制代码


你可以在终端中输入 node imagemin.js 来运行这个脚本。这样就会处理所有的 JPEG 图像,并将优化过的图像放在 build/images 文件夹中。


我发现将质量设置为 70 可以得到足够好的图像,但是你的要求可能会不一样,所以请根据你的需要设置具体的值。


MozJPEG 默认会生成渐进式 JPEG,在加载图像时,从低分辨率逐渐加载到高分辨率,直到图像加载完毕。由于它们的编码方式不一样,所以往往会比基线 JPEG 小一些。


你可以使用这个命令行工具来检查 JPEG 图像是否是渐进式的。


Addy Osmani 已经详细介绍过使用渐进式 JPEG 的优点缺点


在我看来,它是利大于弊的,所以我使用了默认设置。


如果你更喜欢使用基线 JPEG,可以在选项对象中将 progressive 设置为 false。此外,更多的选项设置请参考imagemin-mozjpeg页面


使用 pngquant 优化 PNG 图像

pngquant 是我用来优化 PNG 图像的首选工具,你可以通过imagemin-pngquant插件来使用它:


npm install imagemin-pngquant
复制代码


然后将以下内容添加到 imagemin.js 文件中:


const imageminPngquant = require('imagemin-pngquant');const optimisePNGImages = () =>  imagemin([PNGImages], output, {    plugins: [      imageminPngquant({ quality: '65-80' })    ],  });optimiseJPEGImages()  .then(() => optimisePNGImages())  .catch(error => console.log(error));
复制代码


我发现将 quality 设置为 65 到 80 可以在文件大小和图像质量之间获得良好的折衷。


使用这些设置,我可以将网站截图从 913 KB 减到到 187 KB,而不会出现任何明显的视觉方面的质量损失。文件大小整整减少了 79%!


下面是这两个文件,可以下载下来自己去判断:


原始图像(913 KB):



  • 优化过的图像(187 KB)



使用 WebP 图像(需要浏览器支持)

WebP 是 Google 推出的一种相对较新的图像格式,旨在通过编码无损和有损格式的图像获得较小体积的图像,这让它成为 JPEG 和 PNG 的绝佳替代品。


WebP 图像的视觉质量通常与 JPEG 和 PNG 相当,但文件大小要小得多。例如,当我将上面的屏幕截图转换为 WebP 时,我得到了一个 88 KB 的文件,其质量与 913 KB 的原始图像相当。文件减小了 90%!


看看这三张图片,你能分辨出来吗?


  • 原始 PNG 图像(913 KB)



  • 优化过的 PNG 图像(187 KB)




我认为它们在视觉质量方面是差不多的,但节省的文件大小却是很可观的。


现在我们知道,在可能的情况下尽可能使用 WebP 格式,但要注意,现在它还不能完全取代 JPEG 和 PNG,因为浏览器对 WebP 的支持并不普遍。


在撰写本文时,Firefox、Safari 和 Edge 还不支持 WebP。



不过,caniuse.com 网站的数据显示,全球有超过 70%的用户在使用支持 WebP 的浏览器。这意味着你可以使用 WebP 图像为大约 70%的用户提高网页加载速度。


让我们来看看在 Web 上提供 WebP 图像的具体步骤。


将 JPEG 和 PNG 转换为 WebP

使用imagemin-webp插件将 JPEG 和 PNG 图像转换为 WebP,这个非常简单。


在终端中运行以下命令来安装它:


npm install imagemin-webp
复制代码


然后将以下内容添加到 imagemin.js 文件中:


const imageminWebp = require('imagemin-webp');const convertPNGToWebp = () =>  imagemin([PNGImages], output, {    use: [      imageminWebp({        quality: 85,      }),    ]  });const convertJPGToWebp = () =>  imagemin([JPGImages], output, {    use: [      imageminWebp({        quality: 75,      }),    ]  });optimiseJPEGImages()  .then(() => optimisePNGImages())  .then(() => convertPNGToWebp())  .then(() => convertJPGToWebp())  .catch(error => console.log(error));
复制代码


我发现,将 quality 设置为 85 可以得到与 PNG 质量相当的 WebP,但文件却要小得多。对于 JPEG,我发现将 quality 设置为 75 可以在视觉质量和文件大小之间获得适当的平衡。


说实话,我还在试验这些值,所以不把它们作为推荐值,更多信息请查看imagemin-webp页面


在 HTML 中使用 WebP 图像

在得到 WebP 图像后,可以使用下面的标签为支持 WebP 的浏览器提供 WebP 图像,同时为不支持 WebP 的浏览器提供等效(优化)的 JPEG 或 PNG 后备。


<picture>    <source srcset="sample_image.webp" type="image/webp">    <source srcset="sample_image.jpg" type="image/jpg">    <img src="sample_image.jpg" alt=""></picture>
复制代码


支持 image/webp 媒体类型的浏览器将下载 WebP 图像并显示它,而其他浏览器将下载 JPEG 图像。


不支持<picture>的浏览器将跳过所有 source,并加载底部 img 标签的 src 属性所定义的内容。可以说,我们已经对我们的页面进行了渐进式增强,可以支持各种浏览器。



请注意,不管怎样,img 标签是实际渲染在页面上的内容,因此它是语法的必需组成部分。如果省略 img 标签,就不会渲染任何图像。


<picture>标签和所有 source 都在那里,浏览器可以选择要使用的图像版本。在选择了需要使用的 source 后,URL 将被提供给 img 标签,然后相应的图像就会被显示在页面上。


这意味着你无需为<picture>或 source 设置样式,因为浏览器不会渲染这些标签。因此,你可以像以前一样继续为 img 标签设置样式。


英文原文:https://medium.freecodecamp.org/image-optimization-558d9f449e3


更多内容,请关注前端之巅。



会议推荐


2019 年 6 月,GMTC 全球大前端技术大会 2019 即将到来。小程序、Flutter、移动 AI、工程化、性能优化…大前端的下一站在哪里?点击下图了解更多详情。



2019 年 3 月 11 日 15:337599
用户头像

发布了 731 篇内容, 共 370.7 次阅读, 收获喜欢 1867 次。

关注

评论 3 条评论

发布
用户头像
有没有后端压缩图片的方案?
2019 年 09 月 07 日 12:53
回复
https://www.volcengine.cn/product/imagex 火山引擎的ImageX 专业做图像的,他们提供了自研的图像压缩算法压缩率极高
2021 年 02 月 25 日 12:37
回复
用户头像
考虑兼容性的话,可以用mozJPEG来压缩
试试https://squoosh.app/ 在线看看效果和压缩比
2019 年 03 月 12 日 10:15
回复
没有更多了
发现更多内容

数字货币交易所交易平台系统开发

系统开发咨询:I76-883I-5I52 邓森

腾讯T4架构师:刷3遍以下面试题,你也能从小公司成功跳到大厂

Java架构之路

Java 程序员 架构 面试 编程语言

规模化敏捷框架何从入手?这篇文章把SAFe讲透了!

华为云开发者社区

敏捷开发 框架 safe

转型项目经理?

escray

面经 面试经历 101次面试 七日更 十日谈

Java 细粒度锁续篇

rookiedev

Java 多线程 加锁

2020中国 .NET开发者大会精彩回顾:葡萄城高性能表格技术解读

Geek_Willie

GCExcel 中国 .NET开发者大会 表格技术

微服务架构太难了?那你可能还没掌握SpringBoot+SpringCloud+Docker+RabbitMQ

Java架构之路

Java 程序员 架构 面试 编程语言

区块链农场游戏系统开发软件定制

系统开发咨询:I76-883I-5I52 邓森

研发团队如何实现无缝协作?

万事ONES

研发管理 团队协作 研发效能 研发工具

“闭关修炼”这么久,吃透这些“微服务”笔记,足够面试涨10K

Java成神之路

Java 程序员 架构 面试 编程语言

吊!设计模式全解:6大设计原则+23种设计模式+设计模式PK+设计模式混编

Java架构之路

Java 程序员 架构 面试 编程语言

远见而明察近观若明火|Centos7.6环境基于Prometheus和Grafana结合钉钉机器人打造全时监控(预警)Docker容器服务系统

刘悦的技术博客

Docker 高可用 监控 Prometheus 预警

使用 Helmfile 解放你的 Helm Chart

郭旭东

云原生 Helm

总结近期腾讯+阿里+百度Java岗高频面试题,提问率高达98%,看到这篇文章基本offer稳了

Java成神之路

Java 程序员 架构 面试 编程语言

编写令人愉悦的API接口(一)

陈云轩

Java 程序设计 API APi设计

用了这个评估优化LiteOS镜像利器,我有点飘...

华为云开发者社区

镜像 开发 环境配置

区块链矿机系统开发现成案例

系统开发咨询:I76-883I-5I52 邓森

JVM 的运行时数据区域分布

rookiedev

Java JVM

Ribbon使用及其内核原理剖析

程序员Fox

京东三面凉凉:java+spring+jvm+kafka+微服务等一个都讲不清

Java成神之路

Java 程序员 架构 面试 编程语言

号称大厂面试官的克星,“神仙版”Java面试宝典,“真”吊打大厂面试官

Java架构之路

Java 程序员 架构 面试 编程语言

区块链矿机挖矿系统开发软件技术

系统开发咨询:I76-883I-5I52 邓森

LeetCode题解:92. 反转链表 II,迭代,JavaScript,详细注释

Lee Chen

算法 LeetCode 前端进阶训练营

成为分布式系统架构师,都要学哪些东西?该怎么学?

四猿外

Java 程序员 分布式 分布式系统 架构师

这份GitHub上价值49K的SpringBoot2+Thymeleaf企业应用实战,真香

Java成神之路

Java 程序员 架构 面试 编程语言

关于昆明市政协、市统战部、民革昆明市委赴云南坤艮盈科技有限公司(商务部CECBC区块链专委会秘书处云南办事处)调研指导工作

CECBC区块链专委会

云南发展

拼多多技术3面(Java研发):幻影读+Redis+分布式缓存+锁机制

Java成神之路

Java 程序员 架构 面试 编程语言

学习笔记丨数据结构之二叉查找树

Liuchengz.

数据结构 C/C++ 数据结构与算法 高级数据结构

区块链商城APP系统开发|区块链商城软件开发

开發I852946OIIO

系统开发

让你的简历不落窠臼,精雕细镂写一份真正的技术简历(Python向)

刘悦的技术博客

Python 面试 简历优化 简历

假冒、诈骗、隐私安全,如何应对数字人民币的风险与挑战?

CECBC区块链专委会

货币

通过图片优化,我将网站大小减少了62%-InfoQ