Published on

Reactで画像を遅延ロードする方法(Lazy Image Load)

Authors
  • avatar
    Name
    ssu
    Twitter

Reactで画像を遅延ロードする方法(Lazy Image Load)

Reactで画像を遅延ロードする方法はすごく簡単です。 しかもかなり効果があって、実際に利用した際に80%もの帯域幅の減少をすることができました。

使うライブラリはReact lazy load image componentと呼ばれるライブラリを使います。

まずは下記のとおりにインストールします。

yarn 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

のようにやるだけでLazy loadができるようになります。

Scrollした時に逐次的に画像をダウンロードする方法

これだけでなくて、スクロールして画面が表示された時に画像をダウンロードするように することで、無駄に帯域を使わずに画像の描画をしたい時があるかと思います。

そんな時も簡単で、trackWindowScrollという高階コンポーネント(HOC)をimportしてそして、 trackWindowScroll でappをWrapして、propsにscrollPositionを渡してあげるだけで、 簡単にスクロール時に必要な画像だけを描画するようにすることができます。

下記がサンプルコードになります。下記のようにtrackWindowScrollでAppをwrapすると、 scrollPositionというpropsが渡るので、それをLazyLoadImageに渡すだけでスクロール時にのみ画像を描画するようにすることができます。

これを実行すると、スクロールした時に画像が読み込まれているのがgif動画を見るとわかると思います。 Image from Gyazo

import { LazyLoadImage, trackWindowScroll } from 'react-lazy-load-image-component'; const characterImages = [ "https://1.bp.blogspot.com/-uxIsaN0S5lQ/X-FcrvAAInI/AAAAAAABdD4/6uw_qNUh9dQrG0aUzIExybt84yTEmXOPwCNcBGAsYHQ/s200/onepiece01_luffy.png", "https://1.bp.blogspot.com/-rzRcgoXDqEg/YAOTCKoCpPI/AAAAAAABdOI/5Bl3_zhOxm07TUGzW8_83cXMOT9yy1VJwCNcBGAsYHQ/s200/onepiece02_zoro_bandana.png", "https://1.bp.blogspot.com/-2ut_UQv3iss/X-Fcs_0oAII/AAAAAAABdD8/jrCZTd_xK-Y6CP1KwOtT_LpEpjp-1nvxgCNcBGAsYHQ/s200/onepiece03_nami.png", "https://1.bp.blogspot.com/-mZpzgXC1Sxk/YAOTCAKwWTI/AAAAAAABdOM/5B4hXli0KLU5N-BySHgjVbhZscKLSE-bQCNcBGAsYHQ/s200/onepiece04_usopp_sogeking.png", "https://1.bp.blogspot.com/-HPG_x7XPky8/X-FctLTLkKI/AAAAAAABdEE/xs4T8m0FiBAFptXHGQhQ2c9ZmVWtaeQSgCNcBGAsYHQ/s200/onepiece05_sanji.png", "https://1.bp.blogspot.com/--9Rl2O4BBN0/X-Fct8K5mqI/AAAAAAABdEI/yLOziAqJO34fwn73AolVP0e42A2h-ql1QCNcBGAsYHQ/s200/onepiece06_chopper.png", "https://1.bp.blogspot.com/-JiNpsjnPn7g/X-FcuWcU37I/AAAAAAABdEQ/P5r3wBMTRegjl7njCk4zWBkdoay44-T2gCNcBGAsYHQ/s200/onepiece07_robin.png", "https://1.bp.blogspot.com/-H8YBA_SpxGs/X-Fcu75hh_I/AAAAAAABdEU/WRKUa03ypYor3TwvhziHAnSEcTN4Noq0gCNcBGAsYHQ/s200/onepiece08_franky.png", "https://1.bp.blogspot.com/-KZ0MJgiPJHo/X__CLeY-zVI/AAAAAAABdNM/HnFYqUe0VQEzCWCqyMggibpk4kBRtFCpQCNcBGAsYHQ/s200/onepiece09_brook.png", "https://1.bp.blogspot.com/-vIXZ3_KMn9g/X-FcvVKPQSI/AAAAAAABdEc/i8oJKU0UDMM2uQfzemn6oOmJLICo4VcVgCNcBGAsYHQ/s200/onepiece10_jinbe.png", "https://1.bp.blogspot.com/-CoezMuGxufk/X-FcviASGSI/AAAAAAABdEg/jy9g1AIM3XoWPoeBduRS4QIl4tr1K5kUwCNcBGAsYHQ/s200/onepiece11_arlong.png", "https://1.bp.blogspot.com/-pGLNjxN42lM/X-FcwLVGLwI/AAAAAAABdEk/_FEy4Cf-ZHElAoQeh8fFGCiMln4FDlF0QCNcBGAsYHQ/s200/onepiece12_buggy.png", "https://1.bp.blogspot.com/-LZL7jGWmL3Q/X-FcwoOnE2I/AAAAAAABdEs/qUrY1ClrQrMukkdaEnZK8-Bdob7mOdmQgCNcBGAsYHQ/s200/onepiece13_crocodile.png", "https://1.bp.blogspot.com/-WoPLgzbefuw/X-FcxFa-YjI/AAAAAAABdE0/42S9V3wWi400mGKLEiB_pQT-dqTKT28kwCNcBGAsYHQ/s200/onepiece14_enel.png", "https://1.bp.blogspot.com/-f77JyLzDMeg/X-FcxDMHWxI/AAAAAAABdEw/zSmsi1UHuHwfQTTyw3o9h4yTH_noWumdACNcBGAsYHQ/s200/onepiece15_lucci.png", "https://1.bp.blogspot.com/-jBi40QARjR0/X-FcxQme4HI/AAAAAAABdE4/5-Go7bIV6XErAq8730nH4kvXprlrupbMQCNcBGAsYHQ/s200/onepiece16_moria.png", "https://1.bp.blogspot.com/-VACf4WfKNOk/X-Fcx7DWraI/AAAAAAABdE8/KT0UudaIHrMtbFvjC02yLuPLNBZurGYpQCNcBGAsYHQ/s200/onepiece17_doflamingo.png", "https://1.bp.blogspot.com/-ybJVS9H7Kb0/X-FcyQoCjYI/AAAAAAABdFA/DTdNtWF_3aYx8eX__ebkHmbFgxnfiECTwCNcBGAsYHQ/s200-c/onepiece18_linlin_kaido.png", "https://1.bp.blogspot.com/-zI09uEfw6d0/X-Gi25YOurI/AAAAAAABdF8/cI5nH8a-ixUXp4OaalvU97kqAA8T-wHWgCNcBGAsYHQ/s200/onepiece19_kurohige_teach2.png", "https://1.bp.blogspot.com/-JWY6R_ha5Uo/X-FcyyDEQyI/AAAAAAABdFI/lYwX7qMA_9wtH4-rWP-_eJT0AGHH4xERgCNcBGAsYHQ/s200-c/onepiece20_santaisyou.png" ] const App = ({scrollPosition, trackWindowScroll}) => { return ( <div className="App"> {characterImages.map((characterImage,i) => <div style={{marginTop: "10px"}} key={i}> <LazyLoadImage height="200px" scrollPosition={scrollPosition} src={characterImage} /> </div> )} </div> ); } export default trackWindowScroll(App);