🐼 画像表示遅延について
作成日: 2022/01/19
5

キャッシュが無い場合のファーストビューで画像表示が遅れるのが気になり、ENJINで訊ねたところ、Reactでのimport部分ではなく画像自体の重さなどが原因で、ライブラリを入れたり、プリロードで表示タイミングを調節する必要があると助言いただいた。

早速、こちらで紹介されているreact-lazy-image-loadを入れてみたところ、気になっていた遅延問題が解消された!
https://techblg.app/articles/react-lazy-image-load/

  • Lazy-Loadとは

「Lazy Load」というJavaScriptライブラリを使うことで、サイトの表示速度の高速化を実現することができます。
Lazy Loadを活用すると、ユーザーが実際に見ている画面の外にある画像は読み込みません。下図のようなダミー画像を読み込ませておきます。スクロールして画像が画面に近づいた時点で本来の画像の読み込みを開始させます。つまり、ユーザーが見ている画面範囲に合わせて必要な分だけ画像表示させる画期的な技術なのです。

とのこと。こんなライブラリがあったとは・・・

  • 使い方
//インストール
yarn add react-lazy-load-image-component
npm add react-lazy-load-image-component
import { LazyLoadImage } from 'react-lazy-load-image-component';

const App = () => {
   return (
          <LazyLoadImage
          height="200px"
          src="https://1.bp.blogspot.com/-JWY6R_ha5Uo/X-FcyyDEQyI/AAAAAAABdFI/lYwX7qMA_9wtH4-rWP-_eJT0AGHH4xERgCNcBGAsYHQ/s200-c/onepiece20_santaisyou.png"
        />
)
}
export default App

使ってみた際、srcのパスは変数でも別コンポーネントで処理をした後でも問題なく表示できた。






jsx に描画する前に、Imageオブジェクトを予め生成します

const img = new Image()

生成した Imageオブジェクト に画像へのパスを渡す。
渡した時点で Imageオブジェクトはプリロードを始める!

const src = "public/assets/sample.jpg"
img.src = src // ここでプリロードが始まる

onload にコールバックを渡して、読み込みが終わったら描画をするようにもできます。

img.onload = () => { // 読み込み完了時に発火する関数
    this.setState({ preload: true }) // 例えばこんな風に
}

以下見本ソース

import React, { Component } from 'react';

const imgPath = 'https://images.unsplash.com/photo-1444703686981-a3abbc4d4fe3?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2550&q=80'
class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      show: false
    }
    const img = new Image()
    img.src = imgPath // プリロードする
  }

  render () {
    const { show } = this.state
    if (show) {
      return (
        <div>
          <img style={{ width: '100%', height: '100%'}} src={imgPath} alt='sample image' />
        </div>
      )
    }
    else {
      return (
        <div>
          <button type="button" onClick={() => this.setState({ show: true })} >show image</button>
        </div>
      )
    }
  }
}