プロジェクト技術その他

NOM!NOM!画像サーバーの秘密

Tech Team Waka2025年8月31日

Nom!Nomプラットフォームを支える画像サーバーの裏側と、その技術的な仕組みについて解説します。パフォーマンスと信頼性を両立させるための工夫とは?

Nom!Nom!画像サーバーの秘密

こんにちは。Nom!Nom!の技術担当のWakaです。

今回はNom!Nom!の使用している画像サーバーについてお話しします。

Vercelの問題

現在Nom!Nom!はvercelによるホスティングを行っています。しかし、Vercelには帯域制限があります。そのため、大量の画像を都度ユーザーに配信していてはすぐに帯域制限に達してしまう問題がありました。

また、Vercelの大きな問題点として、画像を追加・変更するたびに毎回デプロイし直す必要があることも挙げられます。これはコンテンツの更新頻度が高いサービスにとって大きな制約となります。

有料版であれば、10TB/monthまでの帯域制限があります。また、データベースとしてfirebaseを用いています。そのため、firestoreで画像ホスティングを行っても良かったのですが、それだと面白くないのでcloudflare pagesを利用することにしました。

イメージ図イメージ図

Cloudflareを使った画像サーバーの構築

Cloudflareは主に静的ホスティングサービスとして知られていますが、適切に設定することで効率的な画像サーバーとしても活用できます。以下では、私たちがどのようにCloudflare Pagesを画像サーバーとして活用しているかを説明します。

静的ホスティングを動的に活用する方法

Cloudflare Pagesは通常、静的なサイトをホスティングするためのサービスですが、私たちはGitHubリポジトリと連携させ、継続的デプロイメントパイプラインを構築しました。画像が追加されるたびに自動的にデプロイが行われるようにしています。

これにより、実質的に「動的」な画像サーバーとして機能させることに成功しました。Cloudflareの利用規約には違反せず、むしろ推奨される使用方法の範囲内で実装しています。

加えて、Vercelと連携しているFirebaseデータベースに画像のURLを埋め込むことで、アプリケーション自体を再デプロイすることなく動的に画像を変更できるようにしています。これにより、新しいメニュー画像の追加や既存画像の更新がスムーズになり、運用コストを大幅に削減できました。

画像の前処理自動化

連携先の立命館大学内のキッチンカー取りまとめ業者からアップロードされる画像は、多くの場合日本語のファイル名が付けられています。これをそのまま使用すると様々な問題が発生するため、以下のような処理フローで自動的に対応しています

python
# 疑似コード:画像処理パイプライン
function 画像処理パイプライン():
    # 1. 画像ファイルの収集
    画像リスト = ディレクトリから全画像を取得("uploads/")
    
    # 2. 各画像の処理
    for 画像パス in 画像リスト:
        # ファイル名を取得
        ファイル名 = パスからファイル名を抽出(画像パス)
        
        # 日本語をローマ字に変換
        ローマ字名 = 日本語からローマ字へ変換(ファイル名)
        
        # 特殊文字を除去して安全なファイル名に
        正規化名 = 特殊文字を除去(ローマ字名)
        
        # WebP形式に変換して保存(容量削減)
        画像オブジェクト = 画像を読み込む(画像パス)
        WebP形式で保存(画像オブジェクト, "processed/" + 正規化名 + ".webp", 品質=85)
        
        ログ記録("変換完了: " + ファイル名 + "" + 正規化名 + ".webp")

このシンプルな処理により、ファイル名の国際化対応と最大70%の容量削減を同時に実現しています。

このスクリプトにより、以下の処理が自動的に行われます:

  1. 日本語ファイル名をローマ字に変換
  2. 画像をWebP形式に変換(容量を最大70%削減)
  3. ファイル名の正規化(特殊文字の除去など)

パフォーマンスの最適化

Cloudflareの強力なCDNネットワークを活用することで、世界中どこからアクセスしても高速に画像を配信できるようになりました。また、WebP形式への変換により、元のJPEGやPNG形式と比較して大幅な容量削減を実現しています。

さらに、適切なキャッシュヘッダーを設定することで、再訪問ユーザーの読み込み時間を短縮し、Vercelの帯域制限問題を解決することができました。

もちろん、フロントエンド側でも最適化を行っており、Lazy Loading(遅延読み込み)を実装しています。ユーザーが実際にスクロールして画像が表示領域に入るまで読み込みを遅らせることで、初期ロード時間の短縮とデータ通信量の削減を実現しています。

結果と今後の展望

この画像サーバーの構築により、以下のような成果が得られました:

  • Vercelの帯域制限問題の解決
  • 画像読み込み速度の向上(特にモバイル環境で顕著)
  • 管理コストの削減(自動化による運用負荷の軽減)
  • 動的な画像更新が可能に(Firebaseとの連携による)

今後は、画像の自動リサイジングや、よりインテリジェントな圧縮アルゴリズムの導入なども検討しています。

ただ、cloudflare pagesは近年始まったばかりのサービスで、よくある開始初期は太っ腹現象がいつまで続くかわかりません。

そのため、我々はインフラ勉強会を行ったりしながら最適なサービス維持のための努力をかかさず行っています。もし、お互い教えあえるチームに入りたい!エンジニア目指したいけど作りたいものがない....という方はQurestへの参加をいつでもお待ちしております。文系理系、数学が苦手関係ありません!

Qurest採用ページ: https://qurest.vercel.app/recruit

Nom!Nom!プラットフォームを利用する店舗オーナーと利用者の両方にとって、よりスムーズな体験を提供できるよう、今後も技術的な改善を続けていきます。

Nom!Nom!技術担当 Waka

タグ

#Nom!Nom!#立命館大学#キッチンカー#プラットフォーム#技術

コメント (0)

まだコメントがありません。最初のコメントを投稿してみましょう!