本日の学び。少なくとも create-react-app で作った叩き台アプリを改造して React.JS アプリを開発していく場合、最初から Webpack が使われるよう構成されている。ここで、画像ファイルなどを扱う場合には Webpack でそれらが処理されるような作法に従っておいた方が良さそうだ。具体的には以下のような使い方をしておく。
- 画像ファイルは
src
ディレクトリ下に配置しておき:.jsx
または.tsx
では画像ファイルを import して使う、または.css
中で画像ファイルを参照する場合は相対パスを指定して使う
たとえばロゴ画像と背景画像を扱う場合、import する方法だと次のような感じに:
// App.jsx import React from 'react'; import Logo from './logo.png'; import Background from './background.png'; export default function App() { return ( ... <div className="container" style={{backgroundImage: "url(" + Background + ")"}} > ... <div className="logo"> <img src={{Logo}} width="32px" height="32px" /> </div> ... </div> ... ); }
同じことを CSS でやると次のような感じになるだろうか(img 要素の扱いが同じではないけれど):
// App.jsx import React from 'react'; import Logo from './logo.png'; import Background from './background.png'; import './App.css'; export default function App() { return ( ... <div className="container"> ... <div className="logo"></div> ... </div> ... ); }
/* App.css */ .container { background-image: url(./background.png); } .logo { background-image: url(./logo.png); width: 32px; height: 32px; }
Webpack で処理するメリットとしては、まず、その画像のサイズが小さいようなら画像データを丸ごと base64 でエンコードした文字列に変換してくれる。つまり画面を開いたブラウザーは画像の URI を参照して追加ダウンロードを行う必要が無く(そこに書いてあるデータをそのまま表示すれば良いため)、通信回数の削減ひいては表示速度の向上が期待できる。また、容量が大きな画像であった場合は base64 エンコード文字列への変換を行わない代わりに有効な相対パス(たとえば ./logo.png
が /static/media/logo.*****.png
)に変換されるため、Webpack で処理することでデメリットが発生することは無いように思う。