こんにちは!
今回は「Reactで画像のアップロードと圧縮はどのタイミングで行うか」について共有したいと思います。
他にも良い方法があったり、プロダクトの目的などによっても適切な方法は変わってくると思いますので、ご了承願います。
経緯としてはstateで画像を管理しようとしたら、PCが重くて操作に支障が出てきたのでいくつか対策を考えました。
Contents
Reactで画像のアップロードと圧縮はどのタイミングで行うか
前提として、フォーム上に<input type="file">
を用意する想定で説明いたします。
方法1:inputタグから画像を選択したタイミングでバックエンドで圧縮し、S3などのストレージに保存
メモ
メリット:ブラウザ(ユーザーPC)への負荷を最小限に抑えられる。
デメリット:実装コストが大きい
手順としては、ユーザーがinputタグでファイルを選択したタイミングでonChange
イベントを発火させることができます。
onChange
イベント内で、バックエンドに画像データを送信します。
バックエンドで圧縮処理をし、S3などのストレージの一時フォルダに保存し、フロントでは画像パスを管理
フォームを送信し、バックエンドの処理が成功した後、S3上で一時フォルダから正式なフォルダにコピーします。(一時ファイルの削除も必要)
Githubやslackなど大手サービスはこのような方法を取っているかと思われます。
方法2:inputタグから画像を選択したタイミングでフロントで圧縮し、フォーム送信時に画像データも送る
メモ
メリット:一時フォルダを作成する必要がないため実装コストが小さめ、stateでの管理もブラウザへの負荷がかかる
デメリット:画像圧縮のモジュールによってはブラウザ(ユーザーPC)への負荷が大きいため要検証
手順としては、ユーザーがinputタグでファイルを選択したタイミングでonChange
イベントを発火させることができます。
onChange
イベント内で、Reactに追加した画像圧縮モジュールで圧縮する
フォームを送信時に圧縮した画像も送り、バックエンドでS3に格納
方法3:inputタグから画像を選択したタイミングでバックエンドで圧縮後フロントに返却、フォーム送信時に画像データも送る
メモ
メリット:方法2と比較してバックエンドで画像を圧縮するため、ブラウザ負荷や圧縮モジュールのブラウザ依存がない
デメリット:フロント⇔バックエンドにおける画像データの通信回数が多くなる
他にもあるかと思いますが、実用的なものを列挙しました。(他にもあるかもしれません...)
以上、お疲れさまでした〜🍵