Web性能优化系列:借助响应式图片来改进网站图片显示

1039 查看

开始使用 <picture> 元素

响应式网页设计太棒了,它改变了我们向手机端用户呈现内容的方式,无论用户使用何种尺寸的手机,我们都能够为其提供定制化的体验。响应式网页设计使用起来很灵活,也容易上手。然而,如果没有正确使用,它会对网页性能带来负面影响。

用于在 PC 端展示的图片对于手机来说太大了。我们知道,在手机设备上大尺寸高分辨率的图片会大大降低页面加载性能。响应式设计和非固定图片(fluid image)在保证正确显示的同时,也保证大图片在页面显示的性能大大提高。Tim Kaldec 对响应式图片的研究表明,使用响应式图片策略最多可以减少图片72%的负担。72%,这是一个相当大的数量。

过去这些年里,出现了一些响应式图片解决方案,开发人员也习惯了使用这些方案来解决响应式图片问题。但都现在看来,这些方法都有一点hacky的味道。这就是 <picture> 元素被引入的原因。

<picture> 元素作为一种向不同设备输出高性能图片数据的客户端解决方案,目前已经纳入 WHATWG HTML 规范 。为了向大家展示 <picture> 元素的强大,我们一起来看一个简单的例子。

浏览器在解析上面的 HTML 语句时会根据设备的屏幕分辨率来选取大小最合适的图片。点击这个链接观看实际效果。

从上面的 HTML 代码可以看到, <picture> 元素由一组 <source> 标签组成。<source> 标签里面声明了设备的视口(viewport)宽度以及与之相应尺寸的图片。这样不同设备上的浏览器就可以根据这些信息选取最适合的图片源。这是一个出色的解决方案,因为所有的操作都是在客户端完成,开发者对展现给用户的图片具有控制权。

值得一提的是,通过设置 <img> 标签的 srcset 属性和 size 属性也可以达到相同的效果。这两个属性由 <img> 标签和 <source> 标签扩展而来,提供一系列图片资源和相应的图片大小。浏览器根据这些信息来选取最合适的图片。假如你不考虑图片的艺术美感,可以使用这种方法。

如果你还想了解更多关于 <picture> 元素的历史和起源,推荐你读这篇文章

处理图片

<picture> 元素在网页性能上效果显著,同时也给我们带来很大的便利,问题是,我们怎样去生产这些不同大小的图片呢?假如你需要多份不同的图片,怎样得到这些图片呢?庆幸的是,有一种简单的方法可以解决这个问题。

使用 Grunt 响应式图片插件可以自动处理、剪裁图片。假如你对 Grunt 任务不熟,也不知道怎样将它引用到你的工程,请参考我之前发表的这篇博文Grunt 官网也提供了非常好的教学资源帮助你立刻开始使用它。

npm install grunt-responsive-images –save-dev

配置好 Grunt ,并且保证它能在你机器上运行之后,打开你的网站,在命令行里输入以下命令来下载相应的包。

npm install grunt-responsive-images –save-dev

接下来你还需要安装 ImageMagick 或 GraphicsMagick 命令行工具,然后配置 gruntfile.js 文件。下面是一个参数配置例子,有很多配置选项,可以根据实际需求设定不同的参数。

通过上面的参数设置,图片将生成 320 像素, 630 像素和 1024 像素的图片,每种像素的图片将放在不同的目录里。

现在,可以处理图片了。在命令行中运行 Grunt 命令,这个时候,可以看到目录下会新增加三个目录,每个目录中已经存在裁剪好了的图片! Hooray !

如果还在想什么工具可以自动帮助你生成相关的 HTML 标签的话,这个 Grunt 插件能替你做这些苦差事。把这个插件和 Grunt responsive images 插件结合起来用,会给你带来更多意外惊喜。

OLDER BROWSERS

关注浏览器的新特性的同时,也要兼顾到老版本的浏览器。目前,只有 Chrome 38 和 Opera 支持 <picture> 元素。好消息是, <picture> 元素已经正式被 WHAT working group 接受,逐渐所有现代浏览器都会支持这个标签。通过 caniuse.com 可以查到,你喜欢的浏览器现在是不是支持它。

幸好,现在有一个插件可以解决大部分传统浏览器不支持 <picture> 元素的问题。 Filament Group 的团队开发出 picturefill.js 这个文件,这个插件可以使不支持 <picture> 元素的浏览器解析这个标签以及标签相关的属性。这意味着,你今天就可以开始使用 <picture> 元素了!

要使用这个插件,你需要在你的页面中添加这个 JavaScript 文件。

再补充一句,这个插件和 picture 标签的功能是一样的。点击这个链接可以看到实例效果。在 Responsive Images Community Group 网站上还有很多例子

附注

我第一次使用 picture 标签的时候,出现了这个错误:

“<source src> with a <picture> parent is invalid and therefore ignored. Please use <source srcset> instead.”

这次错误提示信息非常明确,在引用图片资源时不要使用 src 标签,使用 srcset 标签就可以了。