使用 v-lazy-image 在 Vue.js 中进行渐进式图像渲染

通常,你会遇到有大量图像的网页,其中大多数都没有观看,浏览器仍然加载它们,甚至认为它们是不可见的。

有懒惰的加载,但缺点是,当图像加载时,你会看到一个不愉快的空白空间。

渐进式图像渲染

渐进式图像渲染是一种技术,用来改善懒惰加载图像的用户体验,通过在加载真实图像时开始加载非常轻的图像作为位置,以便用户在加载实际图像之前不会看到空白空间。

有几种方法来解决这个问题,几个例子:

  • 使用低分辨率图像的模糊效果,就像 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通过提供一个功能强大和可自定义的懒惰图像组件来方便这一点,所以你不必这样做。

保持冷静

Published At
Categories with 技术
Tagged with
comments powered by Disqus