正文
在
以前的一篇文章
中,我仔细分析了Medium.com用来展示图片的技术,这种技术可以在展示图片的时候让图片从一张模糊的图片过渡到一张清晰的图片。从那以后,我找到了其他一些同样采用相似方式展示图片的网站。下面让我们来看一下Quora, Quartz 以及 Clicktorelease 是如何实现的。
快速导读
图片是网页中最大的静态资源,他们通常会占据三分之二的空间。图片优化和选择正确的图片格式是至关重要的。另外,有些网站会在图片没有加载的时候,使用小的缩略图当作占位符。这种技术通常也被称作“
blur-up
“。这种技术主要是为了提升用户感知性能,如果搭配懒加载使用,还可以达到节省流量的效果。
当然这项技术还是有其他可替代的技术的。其中一种是使用一张单独的JPEG图片,调整它的扫描脚本使得可以快速渲染出一个原始的像素化的版本,并且在后续扫描中逐步渲染出最终清晰的图片。我推荐你通读
Progressive JPEGs and green Martians
去更了解这项技术。
还有一点,如果你喜欢图片加载优化这方面的内容,可以关注
Cloudinary’s Blog
,里面有很多关于这方面话题的博文。
Quartz
Take a look at the following video, recorded when accessing
a page on QZ.com
with a throttled connection:
看一下下面的这个视频,它记录着当使用慢速的网络访问QZ.com的网页时,Quartz's 的方式按照下面的步骤实现:
-
Request a small
<img />
that will be blurred. In their case, they use 50px width images, with a 80% quality.
-
请求一个小的用于被模糊的
<img />
。在这种情况下,他们使用宽度为50px,质量为80%的图片。
-
通过CSS filter应用模糊效果。
-
请求一个大的图片。
关于Quartz的一个有趣的地方在于,他们使用响应式图片的语法去标记指定大图片。最大的不同点在于他们使用
data-srcset
属性,这样他们就可以控制何时发起请求并且防止浏览器在标记被解析之后去请求大尺寸的图片。
我发现这种方式非常优雅,因为他们尝试遵循“标准”的方式去处理图片,就是通过增加额外的字段以实现懒加载和实现过度动画。
<figure class="progressive-image featured-image size-extra-large">
<picture style="padding-bottom: 56.1875%; background-image: url(https://qzprod.files.wordpress.com/2017/01/fish.jpg?quality=80&strip=all&w=50);">
<img src="https://qzprod.files.wordpress.com/2017/01/fish.jpg?quality=80&strip=all&w=50">
<img alt="INDIA-fishermen" />
<noscript>
<img src="https://qzprod.files.wordpress.com/2017/01/fish.jpg?quality=80&strip=all&w=320" alt="INDIA-fishermen">
</noscript>
</picture>
<figcaption>...</figcaption>
</figure>
Quora
Quora也是在他们的po文里面实现了图片blur-up技术。例子详见
head to this page
。
这里我们可以看到当显示模糊占位图片的时候页面的样子。
让我们深入代码来看看到底时如何实现的。首先,让我们来看看HTML标记:
<div>
<canvas class="qtext_image_placeholder portrait qtext_image zoomable_in zoomable_in_feed"
width="499"
height="874"
data-src="data:image/PNG;base64,UklGRmgAAABXRUJQVlA4IFwAAADwAQCdASoGAAoAAUAmJYgCdEf/g…iD0z/yA/5ipcuk5xHSdrS38j8CkH7s+vKeZu9EwRy0f/KPIlo/+UifdfcpiRcJiRnXXAAAAA==">
</canvas>
<img src />
</div>
为什么同时使用
data-src
和
master-src
?
master_src
图片是当点击图片获取更大尺寸时加载的那张图片。
Quora没有使用模糊效果。他们使用
canvas.drawImage()
在canvas里渲染小的缩略图。你可以看到通过查看他们的代码发现这个方法,在捆绑在主要JS文件的
shared/lazy_load_images
模块中可以看到:
// draw the data-uri image on the canvas
function a(e) {
if (e.getAttribute("data-src")) {
var t = new Image;
t.src = e.getAttribute("data-src");
var i = e.getAttribute("width")
, n = e.getAttribute("height")
, o = e.getContext("2d");
t.addEventListener("load", function() {
o.drawImage(t, 0, 0, i, n)
}, false)
}
}
// go through all canvas on the page with a data-src
function r() {
var e = document.querySelectorAll("canvas[data-src]");
d.insertionQ("canvas[data-src]").every(function(e) {
a(e)
}),
[].forEach.call(e, a)
}
简单来说,Quora所使用的技术主要包括:
-
在canvas中渲染一个内联的非常小的png。
-
使用Webp(如果支持的话)或者其他格式请求大尺寸图片。
-
将大尺寸图片设置为
<img />
元素的资源,然后逐渐变化它的透明度并且隐藏canvas。
Clicktorelease
Clicktorelease.com
,
@thespite
,刚刚重新设计过,也为图片设置了懒加载。
这里最重要的部分是缩略图并不是要加载的图片本身,而是缩略图
DCT矩阵
的值,这使得负载非常非常小。