Chrome Extension Manifest V3 徹底解説
最近 Chrome 拡張機能のチュートリアルを検索したことがあれば、ある厄介な事実に気づいたかもしれません。見つかるガイドの半数が、もはや動作しない background page アーキテクチャを前提に書かれているのです。Manifest V2 は非推奨となり、Chrome ではデフォルトで無効化されています。現在のプラットフォームは Manifest V3 であり、そのアーキテクチャを理解することが、2026 年における拡張機能開発の唯一の実用的な出発点となります。
本記事では、何が変わったのか、なぜ変わったのか、そして主要な API がどのように組み合わさるのかを解説します。
要点まとめ
- Manifest V2 は非推奨であり、新しい Chrome 拡張機能で実用的にサポートされている唯一の選択肢は Manifest V3 である。
- 永続的な background page は、イベント駆動型の service worker に置き換えられた。service worker は DOM へのアクセスを持たず、イベント間でメモリ上の状態が保持されることに依存すべきではない。
declarativeNetRequestAPI がブロッキング型のwebRequestを置き換え、ネットワークフィルタリングは拡張機能のコードからネイティブのルール評価へと移行した。- 拡張機能の JavaScript はすべてパッケージにバンドルする必要があり、リモートホストされたコードは禁止されている。
- 統合された
chrome.actionAPI と Offscreen API が、MV2 のbrowserAction、pageAction、そして永続的な background page によって残された空白を埋める。
なぜ Chrome は Manifest V2 から離れたのか
Manifest V2 拡張機能は、永続的な background page を実行できました。これは完全な HTML ドキュメントであり、拡張機能が何もしていない時でもメモリに無期限に読み込まれたままでした。開発者にとっては便利でしたが、ユーザーにとってはコストの高いものでした。background page を持つすべてのインストール済み拡張機能が、継続的にメモリと CPU を消費していたのです。
パフォーマンス面以外にも、MV2 では拡張機能がリモート URL から JavaScript を読み込んで実行することが可能でした。つまり、拡張機能は無害なコードで Chrome ウェブストアの審査を通過した後、ひそかに外部サーバーから悪意のあるロジックに差し替えることができたのです。拡張機能が実際に何を実行しているのかを監査する実用的な手段は存在しませんでした。
この 2 つの問題、すなわちリソースの浪費と監査不可能なリモートコードこそが、Manifest V3 の真の推進力となっています。
Chrome Extension Manifest V3 における中核的なアーキテクチャ変更
Extension Service Worker が Background Page を置き換える
MV3 では、永続的な background page は廃止されました。その代わりとなるのが extension service worker です。これは、必要に応じて Chrome が起動し、アイドル時には終了する、イベント駆動型のスクリプトです。
この変更は、MV2 から移行する開発者の多くがつまずく点です。service worker は DOM アクセスを持たず、イベント間で生き続けることもありません。グローバル変数に状態を保存して、それが保持されることを期待することはできません。代わりに、イベントをまたいで存続させる必要があるものには chrome.storage を使用し、以前は background page 内の setInterval 呼び出しに含まれていたような定期的な処理のスケジュールには chrome.alarms API を使用してください。
{
"background": {
"service_worker": "background.js",
"type": "module"
}
}
declarativeNetRequest がブロッキング型 webRequest を置き換える
MV2 の webRequest API は、拡張機能があらゆるネットワークリクエストを傍受し、ブロックするか変更するかを同期的に決定することを可能にしていました。これにより拡張機能はブラウザのすべてのトラフィックを広範囲に可視化でき、これは重大なプライバシー上のリスクとなっていました。また、すべてのリクエストが拡張機能の応答を待たなければならないため、レイテンシも発生していました。
declarativeNetRequest API(DNR)は、異なる仕組みで動作します。ルールセットを JSON で定義し、Chrome がそれらをネイティブに評価することで、拡張機能はもはやリクエストをブロックまたは変更するために JavaScript で同期的に傍受する必要がなくなりました。これは設計上、より高速でプライバシーに配慮したものとなっています。
Chrome 120 以降、ルールの上限は MV3 初期の頃から大幅に拡張されています。uBlock Origin Lite のようなコンテンツブロッカーは MV3 対応版をリリースしており、MV3 が「広告ブロッカーを殺した」という主張は完全に正確ではありません。とはいえ、フィルタリングモデルは MV2 時代のアプローチよりも明らかに制限的であり、オリジナルの uBlock Origin は作者の判断により MV2 専用のままです。
Discover how at OpenReplay.com.
リモートホストされたコードの禁止
MV3 拡張機能で実行されるすべての JavaScript は、拡張機能パッケージ自体にバンドルされている必要があります。外部の CDN や API から実行可能コードを読み込むことは許可されていません。これにより、すべての拡張機能が審査時点で完全に監査可能となります。
chrome.action API と Offscreen API
MV2 の browserAction API と pageAction API は、MV3 では単一の chrome.action API に統合されました。これによりツールバーのアイコン、バッジテキスト、ポップアップを一貫したインターフェースで扱えるようになっています。
service worker では実行できない、バックグラウンドコンテキストからの DOM アクセスや音声再生が必要な場合のために、MV3 は Offscreen API を提供しています。これにより、永続的な background page のオーバーヘッドなしに、それらのタスク専用の最小限の非表示ドキュメントを作成できます。Can I Use によれば、関連する offscreen API は現在、モダンな Chromium ベースのブラウザで広くサポートされています。
最小限の MV3 マニフェストの例
{
"manifest_version": 3,
"name": "My Extension",
"version": "1.0",
"background": { "service_worker": "background.js" },
"action": { "default_popup": "popup.html" },
"permissions": ["storage", "activeTab"],
"host_permissions": ["https://example.com/*"]
}
ホスト権限が API 権限とは別に宣言されるようになっている点に注目してください。これは、拡張機能がどのサイトにアクセスできるかをユーザーがより明確に把握できるようにするための意図的な変更です。
まとめ
Manifest V3 は MV2 よりも制約の多いプラットフォームであり、その制約のいくつかは実質的なアーキテクチャ変更を必要とします。しかし、これらの制約には具体的な理由があります。メモリ消費の削減、監査不可能なリモートコードの排除、そして拡張機能プロセスに対する生のネットワークトラフィックの露出の低減です。今日から新しい拡張機能の開発を始めるなら、MV3 がサポートされている唯一の実用的な選択肢です。service worker のライフサイクルと declarativeNetRequest モデルの理解が、その作業の出発点となります。
FAQ
メモリ上で状態を保持し続けることに依存すべきではありません。service worker はアイドル時に終了するため、メモリ上の状態は失われる可能性があります。重要なものは chrome.storage.local または chrome.storage.session に永続化し、次のイベントで worker が起動した際に読み戻してください。各イベントハンドラを、worker が新たに起動したかのように扱うのがよいでしょう。
いいえ。Chrome チームは移行ドキュメントを提供していますが、background page を service worker に置き換える、ブロッキング型 webRequest を declarativeNetRequest に置き換える、リモートコードを排除するといったアーキテクチャの変化は、通常、手動での書き直しを必要とします。単純な API のみを使用していた拡張機能は迅速に移行できますが、永続的な状態やネットワーク傍受に依存していた拡張機能は大幅な再構築が必要です。
はい。マニフェストで宣言される静的ルールに加えて、chrome.declarativeNetRequest.updateDynamicRules および updateSessionRules を通じて、実行時に動的ルールおよびセッションスコープのルールを追加、削除、更新できます。Chrome は MV3 初期リリース以降、利用可能なルールクォータを大幅に拡張しており、ユーザーが設定可能なブロックリストを含む多くのモダンなフィルタリングシナリオで API が実用的になっています。
特定のウェブページの DOM とやり取りする必要がある場合は content script を使用してください。関連するタブなしで、HTML の解析、音声の再生、Clipboard API の使用といった DOM 依存の機能が必要な場合は Offscreen API を使用してください。offscreen ドキュメントは、ページ内ではなく、拡張機能自身のコンテキストで実行されます。
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.