🖼️

画像アップロード機能の実装で調べたことまとめ

に公開

ワークスペースのアイコン画像をアップロードする機能を実装した際のメモです。

要件

  • アイコン画像をDBに保存したい
  • サイズ制限が必要(256x256px、200KB以下)

リサイズ:フロントで

選択肢としてはフロントかバックエンドかの2択。

今回はフロントエンドでリサイズしてからアップロードする方式にしました。

理由:

  • アップロード前にファイルが小さくなるので転送が速い
  • サーバーの負荷が減る
  • プレビュー表示もしやすい

※大規模なプロジェクトではサーバーサイドでリサイズが多いみたいです

バックエンドでもバリデーションチェックしますが、リサイズ処理自体はフロントに寄せました。

ライブラリ vs Canvas API

フロントでのリサイズ方法として、ライブラリを使うか標準のCanvas APIを使うか検討しました。

compressorjs,browser-image-compression など見てみましたが、メンテが数年前で止まっていたり、スター数が少なかったりでどうしようかなと。

結局、Canvas APIだけで十分実装できるので、ライブラリは入れずに標準APIを使うことにしました。これらのライブラリも内部的にはCanvas APIを使っているみたいでした。

変換フォーマット:WebPではなくPNG

WebPの方がファイルサイズは小さそう(あと使ってみたい☺️)と思いましたが、PNGにしました。

理由:SafariのCanvas APIはWebP出力に対応していない

canvas.toBlob(callback, 'image/webp')について、SafariではPNGにフォールバックします。2026年現在、Safari 26.3でも未対応です。

参考: Can I use - toBlob WebP support

ブラウザによって出力形式が変わるとDBに保存される画像フォーマットが統一できず面倒なので、PNGにしました。

なんか前もSafariで何か対応した気がする…OAuthポップアップかな?

今回の実装まとめ

  • リサイズはフロントで(転送軽量、サーバー楽)
  • ライブラリより標準API(依存少なく)
  • WebPはSafari未対応、PNGが無難
  • ブラウザ対応状況は Can I use で調べられる

Discussion