アーキテクチャ

PWAとは?Service Workerとマニフェストの実装手順・ネイティブアプリとの使い分けと採用判断を解説

PWAとは?Service Workerとマニフェストの実装手順・ネイティブアプリとの使い分けと採用判断を解説

PWA(Progressive Web App)は、ブラウザで動くWebサイトを、ホーム画面に追加してオフラインでも動くアプリのように扱う技術です。読み方は「ピーダブリューエー」。専用のアプリストアを通さず、URLにアクセスするだけで配布でき、更新もサーバー側の反映で即座に届きます。この記事では、PWAを成立させるHTTPS・Web App Manifest・Service Workerの3要素と、そのまま貼って動く実装コード、iPhoneでのプッシュ通知が使える条件、ネイティブアプリと比べて何ができて何ができないのか、そして「PWAは流行らない」と言われる理由への実装者視点の採用判断まで、Webサイトのアプリ化を検討する技術選定者向けに整理します。

まとめ:PWAの構成要素と採用可否の結論

PWAは、既存のWeb技術(HTML・CSS・JavaScript)で作ったサイトに、インストール可能性とオフライン動作を後付けする仕組みです。中核はブラウザとサーバーの間で通信を仲介するService Workerと、アイコンや起動時の見た目を定義するWeb App Manifest、そして配信をHTTPSで暗号化する前提の3つ。この3点がそろうと、ブラウザのメニューから「ホーム画面に追加」でき、通信が切れても最後に見た画面を表示できるようになります。実装量は、既存サイトがあればマニフェスト1枚とService Worker1本から始められます。

採用の分岐点は明快です。iOSとAndroidの両方に届けたいがネイティブアプリを2本開発・審査する体力はない、更新を審査待ちなしで即反映したい、Web検索からの流入をそのまま継続利用へつなげたい——この条件ならPWAは投資に見合います。逆に、カメラやBluetoothを深く使う、バックグラウンドで常時動く、iOS向けの確実なプッシュ通知が事業の生命線、といった要件が中心なら、PWAは制約のほうが勝つ場面です。判断基準と、途中でネイティブへ作り直す羽目になる失敗パターンは、本文で具体的に示します。

PWAとは何か、Webをアプリのように扱うための3つの構成要素

PWAは特定のフレームワークの名前ではありません。ブラウザが備える複数のWeb標準を組み合わせ、通常のサイトに「インストールできる」「オフラインで動く」という2つの性質を与えた状態を指します。まず全体像を押さえます。

PWAの定義とProgressive Web Appという名称が指すもの

PWAという言葉は、GoogleのエンジニアAlex Russell氏らが2015年に提唱した設計の呼び名です。「Progressive(漸進的)」は、対応ブラウザなら追加機能が効き、非対応でも普通のサイトとして問題なく閲覧できる、という段階的な拡張の考え方を表します。つまりPWAは「アプリか、サイトか」の二択ではなく、同じ1つのWebページが、環境に応じてアプリ的にも振る舞う状態です。

MDNのプログレッシブウェブアプリのドキュメントでも、PWAは独立した製品ではなく「ウェブプラットフォーム技術で構築しつつ、プラットフォーム専用アプリのような使い勝手を提供するアプリ」と定義され、単一コードベース・インストール可能・オフライン動作・OS統合という性質が並べられています(2026年9月時点の記述)。フレームワークを入れ替える話ではなく、既存Webの上に薄い層を足す話だと理解すると、見積もりの粒度がぶれません。

PWAを成立させるHTTPS・マニフェスト・Service Workerの役割

PWAが成り立つには3つの土台が要ります。1つ目はHTTPSでの配信。Service Workerは通信を仲介できる強力な仕組みのため、暗号化された安全な接続でしか動きません。2つ目がWeb App Manifest、通称manifest.jsonです。アプリ名・アイコン・起動URL・画面の表示モード(display: standaloneなど)をJSONで宣言し、ブラウザはこれを読んでホーム画面のアイコンや全画面表示を用意します。書式はW3CのWeb Application Manifest仕様が一次情報で、各メンバーの型と既定値はここで確認できます。

3つ目がService Workerで、ここがPWAの心臓部です。ページとネットワークの間に常駐し、リクエストを横取りしてキャッシュから返す、通信復帰時に処理を再送する、といった制御を担当します。ライフサイクル(install・activate・fetch)の正確な定義はW3CのService Workers仕様に載っており、実装で迷ったときはブログ記事より先にこちらを引くのが解決への近道です。この3点がそろって初めて、ブラウザは「このサイトはインストールできる」と判断します。

Service Workerが担うオフライン動作とキャッシュ制御の仕組み

Service Workerは、ページとは別のスレッドで動くJavaScriptです。初回アクセス時に登録され、以降はページを閉じても待機し、次の通信要求に割り込む仕組みです。オフライン対応の肝はCache APIとの組み合わせで、必要なファイルをあらかじめ保存しておき、ネットワークが無いときはキャッシュから応答を返します。MDNのService Worker APIリファレンスには、登録・スコープ・イベントの各メソッドが列挙されています。

キャッシュの返し方には方針があります。速度優先ならキャッシュを先に返して裏で更新する、鮮度優先ならネットワークを先に試して失敗時だけキャッシュに落とす、といった戦略を画面特性ごとに設計するのが定石です。この制御をアプリ側のコードで細かく書けるのがネイティブアプリに近い挙動を生む一方、設計を誤ると「古い画面が更新されない」という不具合の温床にもなります。iOSではこのキャッシュに使えるストレージ容量がChromeより厳しく、大量のデータを前提にした設計は避ける必要があります。

作業手順:manifest.jsonとService Workerを書いて動かす

ここからは、既存のWebサイトへPWAを後付けする作業をファイル単位で並べます。やることは、マニフェストを1枚置く、Service Workerを登録する、キャッシュ戦略を書く、ブラウザで検証する、の4つだけです。フレームワークは問いません。以下のコードは静的ファイルとして配置し、HTTPSで配信すればそのまま動きます。

manifest.jsonの最小構成を書いてインストール可能にする

マニフェストはJSONファイル1枚です。拡張子は.webmanifestでも.jsonでも構いませんが、MIMEタイプはapplication/manifest+jsonで返すのが仕様の指定です。実務で外せないのはname・short_name・start_url・display・iconsの5つ。Androidのアイコン形状に合わせるため、purposeにmaskableを指定した512pxのアイコンも用意しておくと、ホーム画面で余白が崩れません。

// manifest.webmanifest
{
  "name": "Issoh Field Report",
  "short_name": "FieldReport",
  "start_url": "/app/",
  "scope": "/app/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#0b57d0",
  "icons": [
    { "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png" },
    { "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png" },
    { "src": "/icons/maskable-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
  ]
}

<!-- 各ページの head に1行足す -->
<link rel="manifest" href="/manifest.webmanifest">

scopeを絞ると、その配下だけがアプリとして扱われます。サイト全体をアプリ化せず、業務画面だけをPWAにしたい場合は、ここで境界を切る設計です。start_urlにクエリを付けておけば、アイコン起動と通常のブラウザ訪問をアクセス解析で区別できます。

Service Workerを登録してオフライン用キャッシュを作る

登録はページ側の数行で終わります。navigator.serviceWorker.registerを呼ぶ場所は、初期表示を邪魔しないようload後に置くのが無難です。Service Workerのファイルは、制御したい範囲より上の階層に置きます。ルート直下のsw.jsならサイト全体、/app/sw.jsならその配下だけが対象です。

// ページ側: 初期表示を止めないよう load 後に登録する
if ("serviceWorker" in navigator) {
  window.addEventListener("load", () => {
    navigator.serviceWorker
      .register("/sw.js", { scope: "/app/" })
      .catch((err) => console.error("SW register failed", err));
  });
}

// sw.js: install で必要なファイルを先読みしておく
const CACHE = "app-v3";
const PRECACHE = ["/app/", "/app/offline.html", "/css/main.css", "/js/app.js"];

self.addEventListener("install", (event) => {
  event.waitUntil(
    caches.open(CACHE).then((cache) => cache.addAll(PRECACHE))
  );
});

// activate で古い世代のキャッシュを捨てる
self.addEventListener("activate", (event) => {
  event.waitUntil(
    caches.keys().then((keys) =>
      Promise.all(keys.filter((k) => k !== CACHE).map((k) => caches.delete(k)))
    )
  );
});

CACHEの文字列は世代番号です。配信ファイルを差し替えたらこの値を上げ、activateで旧世代を消します。この掃除を書き忘れると、端末側に古いファイルが積み上がり、ストレージ制限の厳しいiOSで先に破綻します。

fetchイベントでキャッシュ戦略を切り替えて画面の更新事故を防ぐ

PWAの不具合報告で最も多いのが「更新したのに古い画面が出る」です。原因はほぼ、全リクエストにキャッシュ優先を掛けたことにあります。HTMLのようにサーバー側の変更を即座に届けたいものはネットワーク優先、CSSやフォントのように差し替え頻度が低いものはキャッシュ優先、と種別で分けます。以下は、ナビゲーション要求だけネットワーク優先にし、失敗時にオフラインページへ落とす書き方です。

self.addEventListener("fetch", (event) => {
  const req = event.request;
  if (req.method !== "GET") return;

  // 画面遷移はネットワーク優先。切断時だけオフライン画面を返す
  if (req.mode === "navigate") {
    event.respondWith(
      fetch(req).catch(() => caches.match("/app/offline.html"))
    );
    return;
  }

  // 静的アセットはキャッシュ優先。裏で取り直して次回に備える
  event.respondWith(
    caches.match(req).then((hit) => {
      const network = fetch(req).then((res) => {
        caches.open(CACHE).then((c) => c.put(req, res.clone()));
        return res;
      });
      return hit || network;
    })
  );
});

APIレスポンスを挟む場合は、上の分岐にパス判定を足し、鮮度が要るエンドポイントだけネットワーク優先へ回します。バックエンドを複数サービスで束ねている構成なら、境界の設計はAPIゲートウェイの役割とサービスメッシュとの違いで整理した層の切り方と合わせて考えるのが、キャッシュの責務を front と gateway のどちらに置くか判断する基準です。効果測定は体感ではなく数値で行い、TTFB・FCP・TBTなどWebパフォーマンス指標の使い分けを基準に、導入前後を同じ物差しで比べます。

DevToolsのApplicationパネルでインストール可否を検証する

実装後の確認はChrome DevToolsのApplicationパネルで行います。Manifestの項目でアイコンとstart_urlの解決結果を見て、Service Workersの項目で状態がactivated and is runningになっているかを確かめます。オフライン挙動は、Networkパネルで通信を遮断してから再読み込みし、プリキャッシュした画面が返ることが判定基準です。iPhone実機はmacOSのSafariからWebインスペクタで接続すると、同等の確認ができます。

PWAの検証は「スコアを満点にする作業」ではなくなりました。後述のとおり自動採点のカテゴリが廃止されたため、マニフェストが読めているか、Service Workerが意図したscopeで走っているか、オフラインで白画面にならないか、という3点を手で確かめる運用に置き換わっています。SPA構成でルーティングをクライアント側に寄せている場合は、SPAとはで整理したフロントエンド技術の全体像のとおり初回HTMLの扱いが特殊になるため、ナビゲーション要求の分岐を念入りに試します。

ネイティブアプリ・Webアプリとの違いとPWAが選ばれる条件

PWAの立ち位置は、ブラウザで完結する従来のWebアプリと、ストア配布のネイティブアプリの中間です。どちらの長所をどこまで取り込めるかが選定の焦点になります。まず3者を機能と配布経路で並べます。

PWA・ネイティブアプリ・Webアプリの機能と配布経路の比較

大きな差は「配布経路」と「端末機能へのアクセス」の2軸です。ネイティブアプリはストア審査と引き換えに端末機能をフルに使え、従来のWebアプリは即時配布と引き換えに機能が限られます。PWAはその中間に位置し、Web技術のまま一部のアプリ的機能を得ます。

観点 PWA ネイティブアプリ Webアプリ
配布方法 ブラウザ経由で即配布 アプリストア審査が必要 URLで即配布
インストール ホーム画面に追加 ストアからDL 不要
オフライン Service Workerで対応 標準で対応 原則不可
端末機能 一部に制限あり フルに利用可 制限が大きい
更新 サーバー反映で即時 ストア審査を経由 即時
開発コスト Web技術で一本化 OS別に個別開発 低い

表の要点は「PWAは1つのコードベースでiOSとAndroidの両方に届き、更新に審査待ちが無い」ことに集約されます。この身軽さは、ネイティブアプリを2本抱える運用負荷の軽減につながる利点です。同じ「1コードベースで両OS」を狙う手段にはFlutterやReact Nativeもあるため、ストア配布まで必要かどうかでクロスプラットフォームアプリ開発のメリットとフレームワークの選び方と突き合わせて選ぶと、比較の抜けが減ります。

iOSでのPWA対応範囲とWeb Push通知を使う前提条件

PWAの評価を最も左右するのがiOSの対応状況です。長らくiPhoneはPWAのプッシュ通知に非対応でしたが、iOS 16.4系でホーム画面に追加したPWAに限りWeb Pushへ対応しました。WebKitのWeb Push for Web Apps on iOS and iPadOSの告知(beta 1時点は2023年2月)によれば、通知の許可要求は「subscribeボタンのタップなど、ユーザーの直接操作に応答する形」でしか出せません。アイコンの未読バッジを扱うsetAppBadge・clearAppBadgeも同時に使えるようになっています。

ここには明確な条件が付きます。Safariのタブで開いたままでは通知は使えず、ユーザーが自分で「ホーム画面に追加」してアプリとして起動し、さらに通知を許可した場合にのみ届きます。この「ユーザー自身の追加操作が必須」という一手間が、iOSでのPWA通知の到達率を下げる現実的な壁です。加えてEU圏では、iOS 17.4でデジタル市場法(DMA)対応の一環としてスタンドアロン挙動が一時変更され、PWAがSafariタブで開く時期がありました。事業のユーザー層にEUが含まれる場合は、この地域差を前提に通知施策を設計する必要があります。

インストール可能性の要件とLighthouseのPWA監査廃止

ブラウザが「インストール可能」と判定する条件は、以前より緩くなりました。Chromeのインストール要件の更新に関する告知によると、メニューからのインストールについては、fetchハンドラを実装したService Workerの要件がモバイル版108・デスクトップ版112で撤廃されました。ただし同じ告知に、インストールプロンプトを出すアルゴリズム側はfetchハンドラの存在をなお要求する、と注記があります。beforeinstallpromptで独自の導線を出すなら、fetchハンドラは引き続き書いておく必要がある、と読むのが安全です。

品質確認の道具も変わりました。かつてはLighthouseにPWA専用の監査カテゴリがあり、スコアで診断できましたが、Lighthouse v12.0.0のリリースノート(2024年4月22日)に「Chromeの更新されたインストール要件に合わせてPWAカテゴリを削除した」と明記され、以降のバージョンでは採点されません。現在はChrome DevToolsのApplicationパネルでマニフェストとService Workerの状態を確認し、インストール可能性を個別に検証する運用に移りました。古い記事のスクリーンショットを見て「Lighthouse PWAスコアを満点にする」と考えると、現行環境と食い違います。

PWAで実現できる機能とネイティブアプリに及ばない制約の範囲

採用判断の前に、PWAで何が実現でき、どこで頭打ちになるかを具体的に押さえます。過大評価も過小評価も、この境界を曖昧にしたまま決めることから生まれます。

プッシュ通知・ホーム画面追加・オフライン動作を支える標準API

PWAで実務上効くのは3つの機能です。ホーム画面追加は、URL訪問者を再訪しやすいアイコン起動へ変える導線になります。プッシュ通知は、Androidと対応版iOSで再訪を促す手段です。オフライン動作は、電波の不安定な移動中でも直前の画面や主要コンテンツを表示し続け、離脱を抑えます。

これらを支えるのがブラウザ標準のAPI群です。通知はNotifications APIとPush API、オフラインはService WorkerとCache API、インストールの起点はブラウザが発火するbeforeinstallpromptイベントで制御します。プッシュはWebサーバーとブラウザベンダーのプッシュサービスの間をVAPID鍵で認証する構成になるため、送信側にも鍵管理の実装が要る点は見積もりに入れておきます。特別なSDKを入れず、Web標準の範囲で組める点が、既存サイトへ段階的に足していける理由です。

PWAが苦手とするネイティブ機能とアプリストア配布で越えられない線

一方で、PWAには越えられない線があります。NFCや高度なBluetooth制御、バックグラウンドでの常時位置取得、端末の連絡先や特定センサーへの深いアクセスは、ブラウザのAPIでは扱えないか、対応が限定的です。ゲームのような高負荷のグラフィックス処理も、ネイティブに比べれば不利が残ります。

配布経路にも限界があります。PWAはブラウザ経由が基本で、Google PlayにはTrusted Web Activity(TWA)という仕組みで包んで載せられます。TWAはDigital Asset Linksでドメインの所有を証明したうえでPWAをAndroidアプリとして起動させる方式で、ストア掲載の手数はネイティブアプリとほぼ変わりません。App Storeへの掲載は現実的な選択肢になりません。「ストアの一覧に並んでダウンロードされる」ことをマーケティングの前提にしている場合、PWA単独ではその経路を作れないと理解しておく必要があります。ここを見落とすと、公開後に「ストアに出せない」と判明して作り直しになります。

PWAは流行らないと言われる理由と実装者から見た採用可否の判断

「pwa 流行らない」は月間244回検索される実在の疑問です。技術として枯れているのに、なぜ普及の実感が薄いのか。ここは玉虫色で逃げず、実装者の視点で理由と採用可否を言い切ります。

PWAが流行らないと言われる背景にあるiOSと配布経路の事情

普及が緩やかに見える理由は主に3つあります。第一にiOSの制約の歴史です。プッシュ通知が使えるようになったのが2023年と遅く、しかもホーム画面追加が前提のため、iPhoneユーザーへの到達が構造的に弱いままでした。第二に配布経路で、App Storeに並べられないことが、ストアの集客を重視する事業では採用の壁になります。

第三が認知の問題です。ユーザーの多くは「サイトをホーム画面に追加できる」ことを知らず、開発側が明示的に追加を促さないと使われません。つまりPWAは技術的に失敗したのではなく、iOS・配布・認知という事業側の条件で採否が分かれてきた、というのが実態です。この3点が自社の要件でどれも致命傷にならないなら、PWAは十分に現役の選択肢です。

PWAを採用すべき要件と見送るべき場面の判断基準と失敗パターン

採用に踏み切ってよいのは、次の条件が重なる場合です。届けたい相手がWebから流入し、そのまま継続利用へつなげたい。iOSとAndroidの両方に出したいが、ネイティブ2本の開発と保守は予算に合わない。更新頻度が高く、審査待ちの数日が事業の足かせになる。この3つがそろうECサイトや業務ツール、メディアでは、PWAが費用対効果で勝ちます。

逆に見送るべき場面もはっきりしています。iOSユーザーへの確実なプッシュ通知が売上の柱になっている、カメラやセンサーを深く使う、App Storeでの露出そのものが集客戦略の中心——このいずれかが該当するなら、PWAは無理に選ばず素直にネイティブアプリを検討すべきです。よくある失敗は、コスト削減だけを理由にPWAで始め、後から「iOSの通知が弱い」「ストアに出せない」と判明し、結局ネイティブへ作り直す二重投資です。この判断を発注前に固めておくことが、無駄な手戻りを防ぎます。PWAで受けるかネイティブで作るかを要件の段階から詰めたい場合は、スマホアプリ開発の相談窓口で、対象画面と必要な端末機能を並べたうえで見極めるところから着手できます。なお、PWAをコンテナやCI/CDと組み合わせて継続的に配信する体制づくりは、クラウドネイティブとはで整理したモダン開発の考え方と地続きです。

よくある質問

PWAの導入検討でよく挙がる疑問に、実装と採用判断の観点から簡潔に答えます。

PWAとネイティブアプリはどちらを選ぶべきですか?

判断軸は「端末機能の深さ」と「配布経路」です。カメラやセンサーを深く使う、App Storeでの露出が集客の中心なら、ネイティブアプリが向きます。逆にWeb流入からの継続利用が中心で、iOS・Androidの両対応を1つのコードで済ませたいならPWAが有利です。両方の性質が要るなら、まずPWAで市場を確かめ、必要になった機能だけネイティブへ切り出す段階設計も現実的な選択肢になります。

iPhoneでもPWAのプッシュ通知は使えますか?

使えますが条件があります。iOS 16.4系以降で、かつユーザーがSafariのタブではなく「ホーム画面に追加」してアプリとして起動し、通知を許可した場合に限られます。許可のダイアログはボタンのタップなど直接操作に応じてしか出せない仕様で、ページを開いた瞬間に自動で出す実装は通りません。この「自分で追加する」一手間が必要なため、Androidに比べて到達率は下がる前提で施策を組むと安全です。

PWA化にはどのくらいの開発コストがかかりますか?

既存のWebサイトがあれば、マニフェストの追加とService Workerの実装が中心になり、ネイティブアプリをゼロから作るより大幅に安く済みます。ただし、オフライン時のキャッシュ戦略や通知の設計、iOSの制約への対応まで含めると、単なる「ファイルを2つ足すだけ」では終わりません。要件次第で工数は変わるため、対象画面と必要機能を絞って見積もるのが確実です。

既存のWebサイトを後からPWA化できますか?

できます。PWAは既存のWeb技術への後付けが前提の設計で、サイトを作り直す必要はありません。HTTPS配信であることを確認し、マニフェストを用意してService Workerを登録すれば、ブラウザがインストール可能と判定します。段階的に、まずインストール対応、次にオフライン、その後に通知、と機能を足していく進め方が無理のない導入手順になります。

PWAはSEOやアプリストアの集客に有利ですか?

SEOには寄与しうる一方、ストア集客は別問題です。PWAはWebページのままなので検索エンジンにインデックスされ、表示速度の改善は評価にプラスに働きます。ただしApp Storeには載せられず、Google PlayもTWAで包む一手間が要ります。ストアのランキングやダウンロード数を集客の柱にする戦略なら、PWA単独では代替できないと考えてください。

関連記事

お気に入りに入れた記事の一覧

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.10.06 テックブログ 大和証券の不正アクセスと約11万人分の口座番号:問い合わせ管理の委託先に残さない設計
  2. 2026.10.06 テックブログ 焼肉きんぐの不正アクセスと1,078万件の会員情報|全件規模の流出を防ぐAPIとログの点検
  3. 2024.06.11 コラム 個人情報漏えい件数の推移をグラフで解説|最新データと過去最多(約1.9万件)
  4. 2026.10.05 テックブログ WSL Containersとは?wslcの使い方とDocker Desktopとの使い分け【WSL 3.0.1時点】
  5. 2026.10.05 テックブログ 東京メトロ(メトポ)の不正アクセスと約5.9万件のメールアドレス|配信停止リストを残さない設計

RELATED POSTS 関連記事

目次