Secret Staircase

React で loading="lazy" な <img> のロードに時間がかかる場合だけアニメーション効果をつける

loading="lazy"<img> でロードに時間がかかるときだけアニメーション効果をつける方法を検討しました。

<img> をロードするときにフェードインなどのアニメーション効果をつける場合に、キャッシュにあるなどの理由で時間がかからない場合はアニメーション効果をつけないようにすることがあります。そうしないと前のページに戻ったときにアニメーションが実行されてうるさくなってしまうんですよね。

自分の場合、これまではキャッシュ有無の判定に次のような new Image() して complete を確認する方法を使っていました。

export const isCached = (url: string): boolean =&gt; {
  const img = new Image();
  img.src = url;
  return img.complete;
};

ところが、せっかく loading="lazy" を指定しているのにこのコードがロードしてしまうので lazy の意味がなくなってしまいます。

そこで初回 render 時にタイムスタンプを保存しておいて img.onLoad 時に時間がかかっているならアニメーションを実行するようにしました。

サンプルプログラムはこちらです。 https://github.com/akr4/img-loading-lazy

この方法の課題は遅延ロードされた画像の表示時にアニメーション効果がつかないことですが、遅延ロードのしきい値は Chrome の場合は相当大きい(ブラウザによる)ので、遅いネットワークでなければ画面に表示される前にロードが完了するためおおむね問題なさそうです。

実行方法

npm run start

Chrome の開発者ツールでキャッシュを有効/無効にして試すとアニメーションがついたりつかなかったりするのが確認できます。ロードに 20 ミリ秒以上かかった場合にアニメーションを有効化しています。

※ 2019 年 6 月 11 日現在の最新バージョン Chrome 75 では chrome://flags/#enable-lazy-image-loading を有効にする必要があります