【CSS, Shopify, Liquid】Lazy Loadとは

[How Lazy Loading can Optimize Your Shopify Theme Images(Lazy loadingはいかにShopifyテーマの画像を最適化するか](https://www.shopify.com/partners/blog/lazy-loading)の意訳・まとめです。

# Lazy Loadとは
そのオブジェクトが必要になるまで、オブジェクトの初期化を遅延する技術。
多くの場合、Webサイト上の画像の遅延読み込みをする技術。

# Lazy Loadを利用するメリット
ユーザーは、サイトが実際よりも早く読み込まれていると感じる。

# Lazy Loadの仕組み
大量の画像の読み込みが必要なサイトがあるとする。

デフォルトでは、ユーザーがWebサイトの1番上だけを見ているかどうかに関わらず、ページ上の全ての画像がフルサイズで読み込まれる。
ユーザーに見られることのない画像もあるため、全ての画像を読み込む必要はない。

商品ページに行く前に、最初の10商品だけを見たい場合、50商品それぞれの商品ページを読み込むならば、かなり時間がかかる。
ユーザーは最初の数商品だけに興味があるので、それだけの時間は無駄となる。

Lazy loadingは上記とは異なるアプローチであり、ほとんど全てのモダンWebサイトで用いられているアプローチである。

Lazy loadingを利用する最も普遍的な方法の一つは、プレースホルダーとして低画質の画像を表示することである。
ページは画像サイズが小さくなるおかげで、ずっと早く読み込まれる。

ユーザーがスクロールすると、画像は高画質に置き換わる。

さらに全てのプロセスは、ユーザーがその画像を見ていて、高画質の画像を表示する必要がある時のみ起こる。

# Lazy Loadingのライブラリ

Lazy Loadingを利用するには様々なライブラリがある。(スクラッチからコードのロジックを作る必要がない)

Shopifyのディベロパーツールのスターターテーマは、

- `responsive-image.liquid`
- `responsive-bg-image.liquid`

という２つのスニペットを含んでいる。(snippetsフォルダにある）。これらはlazy loadingを始めるのに必要なもの全てを含む。

上記2つのスニペットが動作するには、3つのdependenciesが必要となる。多くのライブラリが利用できるが、ShopifyスターターテーマではLazysizes、Responsive image as a Services、BGSetを利用している。

これらのライブラリは、 `theme.liquid` ファイルの `<head></head>` タグの間に、次のコードを追加することで読み込むことができる。

```liquid
<script src="{{ 'lazysizes.min.js' | asset_url }}" async="async"></script>
<script src="{{ 'ls.rias.min.js' | asset_url }}" async="async"></script>
<script src="{{ 'ls.bgset.min.js' | asset_url }}" async="async"></script>
```

`responsive.image.liquid` のスニペットはすでに `collection.liquid` ファイルにあり、下記のように書かれている。

```collection.liquid
{% include 'responsive-image' with
  image: product.featured_image,
  max_width: 700,
  max_height: 800
%}
```

この例は拡張することができ、画像とそのラッパーにいくつかのカスタムCSSクラスを渡すこともできる。

次の例を考えてみましょう。

```lazyloading-products-loop.liquid
{% for product in collection.products %}
  {% include 'responsive-image' with
    image: product.featured_image,
    image_class: "image",
    wrapper_class: "image-wrapper",
    max_width: 700,
    max_height: 800 %}
{% endfor %}
```

前の例との違いは、CSSのクラスを追加することで、ページのレイアウトを操作することができるようになっていることである。
例えば下記のようなCSSを使うことができる。

```lazyloading-classes.css
.image {
  display: block;
  margin: 0 auto;
  with: 100%;
}

.grid-view-item__image-wrapper .image {
  position: absolute;
  top: 0;
}

.image.lazyload {
  opacity: 0;
}

.image-wrapper {
  margin: 0 auto;
  position: relative;
  width: 100%;
}
```

`responsive-image.liquid`ファイル、特に `img` タグとそのパラメータがどのように作用するか、もう少し見てみましょう。

```lazyloading-responsive-image.liquid
<img id="Image-{{ image.id }}--{{ responsive_image_counter }}"
  class="responsive-image__image lazyload {{ image_class }}"
  src="{{ image | img_url: '300x' }}"
  data-src="{{ img_url }}"
  data-widths="[{{ image_widths }}]"
  data-aspectratio="{{ image.aspect_ratio }}"
  data-sizes="auto"
  tabindex="-1"
  alt="{{ image.alt | espcape }}"
  {{ image_attributes }}
>
```

`src` 属性はプレースホルダーとする画像を特定しています。
この画像は、元の画像が読み込まれているときに、ユーザーに表示されるものとなります。
`data-src` 属性は元の、フルサイズ画像と呼ばれるものです。
`src` パラメータ内の `img_url` フィルターを修正することで、プレースホルダー画像のサイズを変更することができます。
デフォルトの値は300xですが、これは一時的に表示される画像が300pxの解像度を持つという意味です。

```liquid
src="{{ image | img_url: '300x' }}"
```

数が小さくなればなるほど、画像ファイルは小さく(軽く)なりますが、一層ぼやけて表示されます。
速度の提供と良いユーザー体験の維持の間にはバランスがあります。
次のセクションではそれについてアイデアとストラテジーを見ていきます。

# lazy loadをデザインする

ぼやけた画像を見ることは、それがたとえ数秒でも、顧客にとって良くない体験になり得ます。
顧客はアセットがアップロードされた方法に関して何か間違えがあったのか、または圧縮が強すぎたのか、と考えてしまうかもしれません。

さらに、顧客の信頼を掴むより重要な側面の一つは、ショップのブランドに一層関わっている良いデザインを持つことです。
不完全な(オンライン)ショップに立ち寄ることは顧客がそのショップを去ってしまう決定的な要因となるかもしれません。

これらの状況は滅多にありませんが、考慮する価値があります。ショップのブランディングとスタイルを促進するユニークな体験を提供し、顧客のリテンションに集中することができるからです。
顧客の損失を避けるいくつかのアプローチを見てみましょう。

## ドミナントカラーの使用

マニュエルウィーザーによる興味深いアプローチは画像が読み込まれている時、その画像のドミナントカラーを表示することです。これを達成するプロセスは実際にかなりシンプルでエレガントです。

`responsive-image` スニペットで見たように、開発者は `src` 属性に読み込まれる画像のサイズをセットすることができます。デフォルトでは、300pxの画像を表示する300xです。

その値を300xから1xに変更することによって、画像のドミナントカラーを描画するだけの小さなサイズの画像を表示します。さらにこの利点は読み込む画像がとても小さいので、ほぼ即座に読み込むことができることです。

これは鮮明な色の商品を持つショップにとって最適です。絵画や写真を売るショップは、特にこの技術を使うメリットが得られます。

## ぼかしの使用

もう一つのアプローチは魅力的なぼかし効果の当てられた画像を使用することです。これは `Blur-Up` と呼ばれるLazysizesプラグインを使用することでとても簡単に実行できます。

この方法を実行するために、 `theme.liquid` 内のスクリプトを最初に呼ぶ必要があります。
前に追加されている他のスクリプトの下に、直ちに追加することができます。

```theme.liquid
<script src="{{ 'ls.blur-up.min.js' | asset_url }}" async="async"></script>
```

次に `responsive-image.liquid` クラス内のスニペットに `blur-up` クラスを追加します。

```responsive-image.liquid
<img id="Image-{{ image.id }}-{{ responsive_image_counter }}"
  class="blur-up responsive-image__image lazyload {{ image_class }}"
  src="{{ image | img_url: '30x' }}"
```

これはぼかし効果を使ったCSSコードの例です。

```lazyloading-blur-effect.css
.blur-up {
  -webkit-filter: blur(5px);
  filter: blur(5px);
  transition: filter 400ms, -webkit-filter 400ms;
}

.blur-up.lazyloaded {
  -webkit-filter: blur(0);
  filter: blur(0);
}
```

この技術を利用することで、スタイリッシュで視覚に訴えつつ、とても小さなサイズの画像を利用することができます。

また、上記二つの技術両方の利用、クラス内に `blur-up` を置き、 `img_url` パラメータを1xにセットすることで、ぼかし効果を持つソリッドカラーのプレースホルダーを使用することができます。このぼかしは画像にソフトタッチを加え、結果としてそれほど粗くないプレースホルダー画像になります。

異なるlazy loadのアプローチを使用することで、顧客のブランドに一貫性を持つ、計算された決定を下すことができます。

## その他のオプション

そのほかにも様々なlazy loadの技術があります。例えば、スニペットの `src` 内にはどんなURLを渡すこともできます。読み込み中の時に、回転する歯車のGIF、ショップのロゴを読み込むことができるということです。
オプションは無限にあります。全てはスニペット内の `src` 属性を変更するだけです。

```liquid
src="link_to_your_image.gif"
```

# さらに、、
ショップの読み込み速度を向上する技術に関して言えば、ショップを奇妙に見せる必要がないということを思い起こさせることは有益です。ユーザーは裏で起きていることに全く心配していませんし、サイトが早く読み込まれていることにすら気づきません。しかし、それが遅すぎる時には気づいてしまうのです。

この記事ではSlateテーマでのlazy loadingの仕組みについて注目しました。普遍的にlazy loadingについてもっと学びたいならば、 [CSS Tricks](The Complete Guide to Lazy Loading Images) の [The Complete Guide to Lazy Loading Images](https://css-tricks.com/the-complete-guide-to-lazy-loading-images/)をおすすめします。こちらでは、様々な技術やライブラリの詳細について見流ことができます。

# 参考

- [How Lazy Loading can Optimize Your Shopify Theme Images](https://www.shopify.com/partners/blog/lazy-loading)