240個ものブラウザのタブに表示される小さなアイコンを並べて「PONG」を描画する方法とは?

ブラウザのタブには、複数のタブを開いた状態でもそれぞれ何のページなのかがわかるよう、「Favicon(ファビコン)」と呼ばれる小さなアイコンが表示されています。240個ものブラウザのタブを並べ、ファビコンを使って卓球をテーマにしたシンプルなビデオゲーム「PONG(ポン)」を描画する方法について、技術系ブログを運営するノーラン・ロイヤリティ氏が解説しています。
https://eieio.games/blog/running-pong-in-240-browser-tabs/
ロイヤリティ氏は、友人が行ったファビコンの中で横スクロールゲームの「Flappy Bird」を描画するプロジェクト「FlappyFavi」に触発され、自分も何かできないかと考えてみたそうです。ブラウザのタブに表示されるファビコンは16×16ピクセルとかなり小さいため、友人のプロジェクトでは何が起きているのかがわかりにくいという欠点がありました。そこでロイヤリティ氏は、「たくさんのタブを並べて画像を描画すればいいのではないか」と考えました。
実際にChromeでファビコンが最小になるまでタブを開きまくったところ、タブのファビコンは以下のように整列しました。

2列目以降も同じように並べるため、ロイヤリティ氏はmacOS用のスクリプト言語であるAppleScriptを使用し、30個のタブが8列並ぶようなスクリプトを作成しました。実際にロイヤリティ氏が作成したスクリプトに基づいて30個のタブが8列に並ぶ様子は、以下の動画を見るとよくわかります。
ブラウザのタブで「PONG」を描画するために30個×8列のタブを整列させる様子 - YouTube
ファビコンで動画を描画するには、ファビコンを定期的に更新する必要があります。デフォルトでは、ブラウザは既存のURLを参照するかHTMLのヘッド部分の要素を読み込んでファビコンを描画しており、Chromeでは1秒間に4回読み込みを行っているとのこと。FlappyFaviはHTMLの要素を素早く更新することで、ファビコン内でFlappy Birdが動いているように見せかけています。
しかし、Chromeではタブがバックグラウンドになるとパフォーマンス向上のためリソースが節約されてしまうため、バックグラウンドのタブとアクティブなタブでファビコンの読み込み速度が異なります。以下の動画を見ると、アクティブなタブでは1秒間に約4回ファビコンが更新されるのに対し、バックグラウンドのタブでは1秒間に1回ほどの頻度でしかファビコンが更新されないことがわかります。
Chromeのファビコン更新速度がバックグラウンドのタブとアクティブなタブで異なる様子 - YouTube
ファビコン更新速度の問題を回避するため、ロイヤリティ氏はバックグラウンドになるタブで「人には聞こえない音声」を再生する方法を試しましたが、これはうまく機能しませんでした。最終的にロイヤリティ氏は、JavaScriptの処理をバックグラウンドのタブに分散させるWeb Workerを使い、バックグラウンドタブでもファビコンの更新速度を保つことに成功しました。
また、複数のタブを協調させて描画するには、各タブがどこにあるのかを認識する必要があります。ロイヤリティ氏は、AppleScriptのスクリプトに現在のウィンドウとタブのインデックスをクエリパラメータとして渡し、X座標とY座標で示されるタブの位置を認識できるようにしました。
タブを更新するための通信チャネルにはBroadcast Channel APIを用い、タブを同期させるためにタブとウィンドウのインデックスを含むregistrationメッセージを送信して、メインタブと同期するまでバックグラウンドタブが読み込みを止める仕組みも構築したとのこと。
さらにロイヤリティ氏は、タブやその間隔のピクセルサイズを正確に測定し、よりファビコンを使った描画を滑らかにするように計算しました。

リソースを削減して高速化するために変更などを施した結果、以下のようにメインタブで再生した動画と連動するように、ファビコンを用いて滑らかな描画が実現できました。
ブラウザのタブを用いて移動する正方形が滑らかに描画される様子 - YouTube
その後ロイヤリティ氏は何を描画するか検討し、視覚的な美しさなども含めて「PONG」を描画することに決めました。すでにゲームのコードを書いた経験が豊富だったロイヤリティ氏は、簡単に描画用のAPIを作成できたとのこと。
以下の動画を見ると、実際にChromeで開いた240個ものタブのファビコンを使い、「PONG」を描画している様子が確認できます。
240個ものブラウザのタブを用いて「PONG」を描画する様子 - YouTube
ロイヤリティ氏が作成したコードは、GitHub上で公開されています。
GitHub - nolenroyalty/faviconic: what if you could run games in your tab bar?
https://github.com/nolenroyalty/faviconic
