🖼️
画像アップロード機能の実装で調べたことまとめ
ワークスペースのアイコン画像をアップロードする機能を実装した際のメモです。
要件
- アイコン画像を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