通常,你会遇到有大量图像的网页,其中大多数都没有观看,浏览器仍然加载它们,甚至认为它们是不可见的。
有懒惰的加载,但缺点是,当图像加载时,你会看到一个不愉快的空白空间。
渐进式图像渲染
渐进式图像渲染是一种技术,用来改善懒惰加载图像的用户体验,通过在加载真实图像时开始加载非常轻的图像作为位置,以便用户在加载实际图像之前不会看到空白空间。
有几种方法来解决这个问题,几个例子:
- 使用低分辨率图像的模糊效果,就像 Medium 或 Quora 这样做
- 动画原始图像的边缘 SVG 版本。 @jmperezperez在 Render Conf 2017 的 This talk上展示了这种技术。
在这篇文章中,我们将专注于模糊效应的位置保持者。
开始使用 v-lazy 图像
v-lazy-image
是一个 Vue.js 组件,建立在文章中所示的例子之上 Lazy Image Component using the Intersection Observer API,并添加了一些功能。
<$>[注] P.S.: 组件是由你的 trully 写的 😉 <$>
首先,您需要先在 Vue.js 应用程序中安装它:
1$ npm install v-lazy-image
然后,导入组件并通过传递一个src
属性来使用它:
1<template>
2 <v-lazy-image src="http://lorempixel.com/400/200/" />
3</template>
4
5<script>
6import VLazyImage from "v-lazy-image";
7
8export default {
9 components: {
10 VLazyImage
11 }
12};
13</script>
就像这样,图像一旦成为可见,就会懒惰地加载,您可以传递任何属性,如alt
,并将它们添加到<img>
标签中。
在 v-lazy 图像上进行渐进渲染
v-lazy-image
允许通过使用 src-placeholder
属性来设置一个位置持有人:
1<v-lazy-image
2 src="https://cdn-images-1.medium.com/max/1600/1*xjGrvQSXvj72W4zD6IWzfg.jpeg"
3 src-placeholder="https://cdn-images-1.medium.com/max/80/1*xjGrvQSXvj72W4zD6IWzfg.jpeg"
4 />
此外,它还暴露了类v-lazy-image-loaded
,以便应用任何类型的CSS动画和风格。
1.v-lazy-image {
2 filter: blur(10px);
3 transition: filter 0.7s;
4}
5
6.v-lazy-image-loaded {
7 filter: blur(0);
8}
在 此演示中,您可以看到这个和其他有趣的CSS动画例子应用于v-lazy-image。
更复杂的例子
v-lazy-image
还暴露了@load
和@intersect
事件,如果您需要更多的控制。
例如,通过CSS动画模糊过滤器是相当沉重的,但我们可以使用SVG构建一个更高性能的版本:
1<template>
2 <div>
3 <svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="filter hidden">
4 <defs>
5 <filter id="blur">
6 <feGaussianBlur in="SourceGraphic" :stdDeviation="deviation" />
7 </filter>
8 </defs>
9 </svg>
10 <v-lazy-image
11 :src="src"
12 :src-placeholder="srcPlaceholder"
13 @load="animate"
14 ></v-lazy-image>
15 </div>
16</template>
17
18<script>
19export default {
20 props: {
21 src: String,
22 srcPlaceholder: String,
23 blurLevel: {
24 type: Number,
25 default: 30
26 },
27 duration: {
28 type: Number,
29 default: 1000
30 }
31 },
32 data: () => ({ rate: 1 }),
33 computed: {
34 deviation() {
35 return this.blurLevel * this.rate;
36 }
37 },
38 methods: {
39 animate() {
40 const start = Date.now() + this.duration;
41
42 const step = () => {
43 const remaining = start - Date.now();
44
45 if (remaining < 0) {
46 this.rate = 0;
47 } else {
48 this.rate = remaining / this.duration;
49 requestAnimationFrame(step);
50 }
51 };
52
53 requestAnimationFrame(step);
54 }
55 }
56};
57</script>
58
59<style scoped>
60.filter {
61 display: none;
62}
63
64.v-lazy-image {
65 width: 100%;
66 filter: url("#blur");
67}
68</style>
它确实变得更加复杂,但更具性能,你可以将其包装成像那样可重复使用的组件。
你可以看到它在 此代码和盒子中运行。
包装上
有多种创意的方式来进行渐进的图像渲染。v-lazy-image通过提供一个功能强大和可自定义的懒惰图像组件来方便这一点,所以你不必这样做。
保持冷静