『述べて作らず、信じて古を好む。
窃に我が老彭に比す』

論語より

【Chrome拡張】タイマー機能を実装する方法

こんにちは。

 

先日の記事、

【Chrome拡張機能】タイマーを作ってみた

でも、紹介しましたが、
最近、Chrome拡張機能を作ってます。

 

タイマーの実装にあたって、いくつかつまづいた点もあったので、記事にしてゆきます!

 

実装したソースコードがみれればいい!
って方は、

GitHubに、最新のコードがありますので、
そちらもぜひご参照ください。

▼GitHub
https://github.com/cancaodosol/tick-tock-task

この記事で扱うこと(要点)

  • Manifest V3 の準備(必要な権限・Service Worker)
  • chrome.alarms の使い方(作成・受信・削除)
  • アラームと併用する API(通知、UIとの通信)
  • よくある落とし穴と回避法

 

1. なぜ通常の setTimeout ではダメなのか

いきなりですが、地味に解決に時間がかかったポイント。

はじめ開発したときは、setTimeout / setInterval を使ってタイマー実装をしましたが、うまくいかず。

原因は、Chrome拡張(Manifest V3)ではバックグラウンド処理が Service Worker(バックグラウンドワーカー) で行われることにありました。

Service Worker は、ブラウザが非アクティブ時に自動停止されるため、長時間のタイマー処理は期待通り動作しません。

 

そのため、拡張ではブラウザ提供の恒常的なスケジューリングAPIである chrome.alarms を使います。

これにより、ブラウザ側でアラームを管理し、トリガー時に Service Worker を起動して処理を行えます。

 

「5分測りたいタイマー」=「5分後に鳴るアラーム」としてつくっていきます。

 

2. Manifest V3 の設定(必須)

まず manifest.json に必要な権限と Service Worker のエントリを用意します。

アラーム・通知・保存を使う場合の最小例は次の通りです。

{
  "manifest_version": 3,
  "name": "My Alarm Extension",
  "version": "1.0",
  "permissions": [
    "alarms",
    "notifications"
  ],
  "background": {
    "service_worker": "background.js"
  }
}
  • “alarms” 権限:chrome.alarms を使用するために必須。
  • “notifications”:ユーザーへのシステム通知を出すなら必要。

 

3. アラームの作成(ユーザー操作側)

アラームの作成によって、タイマー機能をつくります。

「5分測りたいタイマー」=「5分後に鳴るアラーム」というわけです。

 

ユーザーが何分後・何時に通知したいかを指定してアラームを作る処理は、Popup や Side Panel(UI)側で行います。

UI側から Service Worker に直接触らず、API を通じてアラームを作成します。

例:5分後にアラームを作る

// popup.js(UI側)
const minutes = 5; // ユーザー入力
chrome.alarms.create('myAlarm', { delayInMinutes: minutes });

アラームのオプションは複数あります(when, delayInMinutes, periodInMinutes)。用途に合わせて使い分けます。

 

4. アラーム受信と処理(Service Worker 側)

実行の中心は background.js(Service Worker)です。

アラーム発火時は Service Worker が起動され、chrome.alarms.onAlarm イベントが呼ばれます。

// background.js
chrome.alarms.onAlarm.addListener((alarm) => {
  if (alarm.name === 'myAlarm') {
    // 必要な処理:通知、データ更新、外部API呼び出しなど
    chrome.notifications.create({
      type: 'basic',
      iconUrl: 'icon.png',
      title: 'リマインダー',
      message: 'そろそろタスクの時間です!'
    });
  }
});

ポイント:

  • UI(popup/page)のスクリプトは直接アラームイベントを受けられない。必ず Service Worker で受ける。
  • Service Worker は短時間で終了するので、重い処理を行う場合は注意(非同期処理は Promise を返す/待つなど)。

 

5. 通知(chrome.notifications)の扱い

アラームと一緒に目に見える動作をさせるならシステム通知を出すのが簡単です。

上の例のように chrome.notifications.create() を呼べばOSの通知領域に出ます。

// 通知作成の例
chrome.notifications.create({
  type: 'basic',
  iconUrl: 'icon.png',
  title: 'タイマー完了',
  message: '5分が経過しました'
});

補足:

  • 通知クリック時の挙動は chrome.notifications.onClicked で受け取れる。
  • 通知のアイコンはテーマや環境で見え方が変わるため、適切なサイズの画像を用意する(例:128×128)。

 

6. よくある落とし穴と対処法

問題 原因 対処法
アラームがトリガーされない alarms 権限が manifest にない / Service Worker エラー manifest.json を確認、background のコンソール(chrome://extensions → Service Worker の inspect)でエラーを確認
UIでアラーム一覧が空に見える UIと storage の同期ミス / 非同期処理の見落とし メッセージングで明示的に取得する / Promise を使って順序を保証する
Service Worker が重い処理で落ちる 長時間実行の処理(ネットワークなど)を同期で行っている 軽くする、外部でキュー化する、必要ならサーバを使う

 

7. まとめ

Chrome拡張で安定してアラームを扱うには、chrome.alarms を中心に設計するのが鉄則です。Manifest V3 の Service Worker の性質を踏まえ、通知(chrome.notifications)、UIとのメッセージング(chrome.runtime.sendMessage)を組み合わせることで、堅牢で実用的なアラーム機能を実装できます。