React.JS (Webpack)の画像ファイルのimportについて

本日の学び。少なくとも create-react-app で作った叩き台アプリを改造して React.JS アプリを開発していく場合、最初から Webpack が使われるよう構成されている。ここで、画像ファイルなどを扱う場合には Webpack でそれらが処理されるような作法に従っておいた方が良さそうだ。具体的には以下のような使い方をしておく。

  1. 画像ファイルは src ディレクトリ下に配置しておき:
    1. .jsx または .tsx では画像ファイルを import して使う、または
    2. .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 で処理することでデメリットが発生することは無いように思う。