多くの場合、画像がたくさんあるWebページに出くわし、それらのほとんどがビューポートから外れていると、ブラウザはそれらが表示されていなくてもそれらをロードし続けます。

遅延読み込みがありますが、欠点は、画像の読み込み中に不快な空きスペースが表示されることです。 そこで、プログレッシブ画像レンダリングが役立ちます。

プログレッシブ画像レンダリング

プログレッシブ画像レンダリングは、実際の画像を読み込むときにプレースホルダーとして非常に軽量な画像の読み込みを開始することで、遅延読み込み画像のユーザーエクスペリエンスを向上させるために使用される手法です。これにより、実際の画像が読み込まれるまで、ユーザーには空きスペースが表示されません。

プレースホルダーを作成する方法はいくつかあります。 いくつかの例:

  • MediumやQuoraと同じように、低解像度の画像にぼかし効果を使用します。
  • 元の画像のエッジのあるSVGバージョンをアニメーション化します。 @jmperezperez は、RenderConf2017のこのトークでそのテクニックを示しました。
  • Google画像検索やPinterestのように、プレースホルダーに色を入力します。

この記事では、ぼかし効果のプレースホルダーに焦点を当てます。

v-lazy-image入門

v-lazy-image は、記事 Intersection Observer API を使用したレイジーイメージコンポーネントに示されている例に基づいて構築されたVue.jsコンポーネントであり、いくつかの機能が追加されています。

PS:コンポーネントはあなたの作成者によって作成されました。 😉

まず、Vue.jsアプリに最初にインストールする必要があります。

$ npm install v-lazy-image

次に、コンポーネントをインポートし、srcプロパティをコンポーネントに渡して使用します。

<template>
  <v-lazy-image src="http://lorempixel.com/400/200/" />
</template>

<script>
import VLazyImage from "v-lazy-image";

export default {
  components: {
    VLazyImage
  }
};
</script>

そのように、画像が表示されるとすぐに遅延読み込みが行われます。 altなどの任意の属性を渡すことができ、それらは<img>タグに追加されます。

v-lazy-imageでのプログレッシブレンダリング

v-lazy-imageでは、src-placeholderプロパティを使用してプレースホルダーを設定できます。

<v-lazy-image
  src="https://cdn-images-1.medium.com/max/1600/1*xjGrvQSXvj72W4zD6IWzfg.jpeg"
  src-placeholder="https://cdn-images-1.medium.com/max/80/1*xjGrvQSXvj72W4zD6IWzfg.jpeg"
  />

さらに、あらゆる種類のCSSアニメーションとスタイルを適用するために、クラスv-lazy-image-loadedを公開します。 たとえば、ぼかし効果を簡単に適用できます。

.v-lazy-image {
  filter: blur(10px);
  transition: filter 0.7s;
}

.v-lazy-image-loaded {
  filter: blur(0);
}

このデモでは、v-lazy-imageに適用されたCSSアニメーションのこのデモと他の面白い例を見ることができます。

より複雑な例

v-lazy-imageは、さらに制御が必要な場合に備えて、@loadおよび@intersectイベントも公開します。

たとえば、CSSによるブラーフィルターのアニメーション化は非常に重いですが、SVGを使用してよりパフォーマンスの高いバージョンを構築できます。

<template>
  <div>
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="filter hidden">
      <defs>
        <filter id="blur">
          <feGaussianBlur in="SourceGraphic" :stdDeviation="deviation" />
        </filter>
      </defs>
    </svg>
     <v-lazy-image
      :src="src"
      :src-placeholder="srcPlaceholder"
      @load="animate"
    ></v-lazy-image>
  </div>
</template>

<script>
export default {
  props: {
    src: String,
    srcPlaceholder: String,
    blurLevel: {
      type: Number,
      default: 30
    },
    duration: {
      type: Number,
      default: 1000
    }
  },
  data: () => ({ rate: 1 }),
  computed: {
    deviation() {
      return this.blurLevel * this.rate;
    }
  },
  methods: {
    animate() {
      const start = Date.now() + this.duration;

      const step = () => {
        const remaining = start - Date.now();

        if (remaining < 0) {
          this.rate = 0;
        } else {
          this.rate = remaining / this.duration;
          requestAnimationFrame(step);
        }
      };

      requestAnimationFrame(step);
    }
  }
};
</script>

<style scoped>
.filter {
  display: none;
}

.v-lazy-image {
  width: 100%;
  filter: url("#blur");
}
</style>

確かに複雑になりますが、パフォーマンスが向上し、そのような再利用可能なコンポーネントでラップできます。

このコードサンドボックスで実行されていることを確認できます。

まとめ

プログレッシブ画像レンダリングを行うには、複数の創造的な方法があります。 v-lazy-image は、パフォーマンスが高くカスタマイズ可能なレイジーイメージコンポーネントを提供することでこれを簡単にします。そのため、そうする必要はありません。 フィードバックをお寄せになりたい場合は、よろしくお願いいたします😉。

涼しくしてください🦄