◉GEMINI LABEN
●ARGON — gemini-4-argon が 10/13 に GA。複雑なコーディング・エージェント・数学・科学向けです●DEEP RES — deep-research-pro-preview-12-2025 は 10/23 に停止、残り6日。移行先は deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 が GA(10/06)。gemini-3.1-flash-image は非推奨で停止日は未発表です●MCP — ツール結果が 8.5万トークンに膨らんだ事例を、ADK で 310 トークンに包んで抑えた報告が出ています●FLASH — gemini-3.7-flash と 3.5-flash は新しい Flash モデルに自動で回されます(10/08)●NEW — クラッシュ報告を毎回ゼロから読ませない — 既知バグ早見表を先に grep し…●ARGON — gemini-4-argon が 10/13 に GA。複雑なコーディング・エージェント・数学・科学向けです●DEEP RES — deep-research-pro-preview-12-2025 は 10/23 に停止、残り6日。移行先は deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 が GA(10/06)。gemini-3.1-flash-image は非推奨で停止日は未発表です●MCP — ツール結果が 8.5万トークンに膨らんだ事例を、ADK で 310 トークンに包んで抑えた報告が出ています●FLASH — gemini-3.7-flash と 3.5-flash は新しい Flash モデルに自動で回されます(10/08)●NEW — クラッシュ報告を毎回ゼロから読ませない — 既知バグ早見表を先に grep し…
記事一覧/開発ツール
⟐ 開発ツール/2026-06-28上級

Gemini API × PWA実装ガイド — Service Worker・オフラインAI・Web Push通知でApp Store品質のWebアプリを作る

Gemini APIとPWAを組み合わせて、Service Workerによるオフライン対応・IndexedDBでのAIコンテキスト永続化・Web Push通知の統合まで、本番レベルのAI搭載Webアプリを実装する手順と、キャッシュヒット率からAPIコストを可視化する実装をまとめます。

gemini-api287PWAService WorkerオフラインWeb PushIndexedDBJavaScript

✦ プレミアム記事

Gemini APIを組み込んだWebアプリを作って、ユーザーに試してもらった翌日に届いたフィードバックがこれでした。「電車でトンネルに入ったら真っ白になった」。AIを中心に据えたアプリで、通信が途切れたとたんに使えなくなるのはユーザー体験として致命的です。

この経験が、Gemini APIとProgressive Web App(PWA)の組み合わせを真剣に調べるきっかけになりました。PWAにはService Workerという仕組みがあり、ネットワーク層をJavaScriptでコントロールできます。AIアプリ特有のキャッシュ戦略、オフラインフォールバック、バックグラウンド同期——これらを正しく実装すると、トンネルの中でも動くAIアプリが作れます。

ここではGemini API × PWAの実装パターンを本番レベルで解説します。公式ドキュメントには書かれていない落とし穴も含めて、実際に動くコードとともに紹介します。

PWAとGemini APIを組み合わせる理由

モバイルアプリとして配布する方法はいくつかあります。React NativeやFlutterでネイティブアプリを作る方法もありますが、PWAには独自の強みがあります。

まず、App Storeのレビューを経ずにAI機能をすぐに更新できます。Geminiの新しいモデルが公開されたとき、ネイティブアプリなら申請から審査完了まで数日かかりますが、PWAならデプロイした瞬間にユーザーに届きます。個人開発者やスタートアップにとって、この即時性は大きなアドバンテージです。

次に、インストール不要でネイティブアプリと同等の体験を提供できます。ユーザーがブラウザからアクセスし、「ホーム画面に追加」するだけでスプラッシュスクリーン付きのアプリとして動作します。AIチャットボット、画像解析ツール、音声メモアプリなど、Gemini APIを使ったプロダクトはPWAと相性が良いものが多いです。

そして、オフライン対応によるユーザー体験の差別化です。競合する他のAIWebアプリの多くは、APIが使えないとそのまま壊れます。キャッシュ戦略を丁寧に設計したPWAは、その点で明確に差別化できます。

プロジェクト構造とService Workerの登録

以下のような構造を想定します。Vite + Vanilla TypeScript構成ですが、Next.jsやSvelteKitでも考え方は同じです。

my-gemini-pwa/
├── public/
│   ├── manifest.json        # PWAマニフェスト
│   ├── sw.js               # Service Worker(ビルド後に配置)
│   └── icons/              # アプリアイコン
├── src/
│   ├── main.ts             # エントリポイント
│   ├── gemini.ts           # Gemini API クライアント
│   ├── sw-registration.ts  # SW登録処理
│   └── db.ts               # IndexedDB管理
└── vite.config.ts

Service Workerの登録は、ページの初期ロード後に行います。main.tsで次のように書きます:

// src/sw-registration.ts
export async function registerServiceWorker(): Promise<void> {
  if (!('serviceWorker' in navigator)) {
    console.warn('Service Worker はこのブラウザでサポートされていません');
    return;
  }
 
  try {
    const registration = await navigator.serviceWorker.register('/sw.js', {
      scope: '/',
      // updateViaCache: 'none' で SW ファイル自体はキャッシュしない
      updateViaCache: 'none',
    });
 
    registration.addEventListener('updatefound', () => {
      const newWorker = registration.installing;
      if (!newWorker) return;
 
      newWorker.addEventListener('statechange', () => {
        if (
          newWorker.state === 'installed' &&
          navigator.serviceWorker.controller
        ) {
          // 新しいバージョンが利用可能 → ユーザーに通知
          showUpdateBanner();
        }
      });
    });
 
    console.log('✅ Service Worker 登録成功:', registration.scope);
  } catch (error) {
    console.error('Service Worker 登録失敗:', error);
  }
}
 
function showUpdateBanner(): void {
  const banner = document.createElement('div');
  banner.innerHTML = `
    <div style="position:fixed;bottom:16px;left:16px;right:16px;background:#1a73e8;
      color:white;padding:12px 16px;border-radius:8px;display:flex;
      justify-content:space-between;align-items:center;z-index:9999;">
      <span>新しいバージョンが利用可能です</span>
      <button onclick="window.location.reload()" 
        style="background:white;color:#1a73e8;border:none;
        padding:6px 12px;border-radius:4px;cursor:pointer;font-weight:600;">
        更新する
      </button>
    </div>
  `;
  document.body.appendChild(banner);
}

重要な点として、updateViaCache: 'none'の設定があります。これがないと、ブラウザがService Workerファイル自体を積極的にキャッシュしてしまい、アップデートがユーザーに届くのが遅れます。

✦

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
✦Service Workerのヒット/ミスを計測し、回避できたGemini API呼び出しを実数で把握する実装
✦キャッシュ戦略3パターン(完全一致/正規化/意味的近傍)のヒット率とコスト削減の目安
✦オフライン対応・IndexedDB永続化・Background Syncを本番品質で積み上げる順序
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Gemini Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

⟐ 開発ツール2026-08-21
通知文の長さ指示が英語版だけ効かなかった理由と、生成後に幅で詰める実装
日英2言語のプッシュ通知を Gemini に生成させたところ、英語版だけが実機で途切れていました。原因は文字数での長さ指示です。表示幅の実測値と、生成後に詰めるフィッティング実装をまとめました。
⟐ 開発ツール2026-08-10
ヘルプが答えていない質問を、Gemini に問題を作らせて先に見つける
ヘルプやFAQに書いてあるのに問い合わせが止まらないとき、その資料から問いを生成し、資料本文だけで答えられるかを判定する二段構えの点検パイプラインを作ります。呼び出し設計と費用の見積もりまで含めた実装手順です。
⟐ 開発ツール2026-04-18
Gemini API × Tauri 2.0 でクロスプラットフォームAIデスクトップアプリを構築する
Tauri 2.0とGemini APIを組み合わせてmacOS・Windows・Linux対応のデスクトップAIアプリを構築する実践ガイド。Rustバックエンドによる安全なAPIキー管理、ストリーミング配信、ネイティブOS機能との連携を動くコードで解説します。