4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ZOZOAdvent Calendar 2024

Day 4

SharedWorkerを使っているのは誰だ

Last updated at Posted at 2024-12-03

SharedWorkerというWeb Workerがあります。
よく使うWeb Worker(new Worker(...))をDedicated(専用)Workerと呼ぶのに対し、SharedWorker(new SharedWorker(...))はShared(共有)Workerと呼びます。

Sから始まるWorkerでService Workerというものもありますが、これとは全くの別物です。

SharedWorkerは、複数のウィンドウやタブを開いたときでもスレッドが共有され、各ウィンドウとはメッセージで情報を共有することができます。

これを使うことで、WebSocketなどを使っている場合に各ウィンドウからコネクションを生やさずに、SharedWorker経由の1つのコネクションで済ませるという手法があります。

ところで、iOS 16.1のWebViewで利用するとクラッシュします。(ref)

SharedWorkerを使っているのは誰だ

突如、iOS16.1のみWebViewがクラッシュするとわかり、調べるとSharedWorkerが悪いとわかりました。

自身のコードの中ではSharedWorkerを使っていないのになぜでしょうか。

ほんとうにSharedWorkerを使っているか確認する

Google Chrome (Chromium)ブラウザのDeveloper ToolsのPerformanceタブを利用することで、Worker含め、どのような関数が実行されたかなどを閲覧できます。

関数からコード片を確認することもできます。

SharedWorkerを初期化しているひとを探す

実際にSharedWorkerを使っていることがわかりました。次は実際に初期化しているコードを探します。

SafariのWeb development toolsには、HTTPリクエスト/レスポンスの上書き機能があります。
Networkタブからリソースを選択、右クリックしコンテキストメニューから「リクエスト(レスポンス)のローカルオーバーライドを作成」します。

ここで最初に読み込まれるHTMLへJavaScriptを注入します。どのJavaScriptよりも早く読み込みたいのでheadの開始タグ直後などがいいでしょう。

<!DOCTYPE html>
<html lang="ja">
<head>
  <script>
    (() => {
      const Original = window.SharedWorker;
      window.SharedWorker = class Override extends SharedWorker {
        constructor(...args) {
          super(...args);
          console.trace(args);
          debugger;
        }
      }
    })();
  </script>
  <meta charset="utf-8">
  ...

これにより、 new SharedWorker('...') されるときに、そのスタックトレースを確認できるようになります。

Blob

上のコードを挿し込んでもわからなかったり、スクリプト自体がBlob URLだったりします。なのでBlobも同様にスタックトレースを確認します。

  <script>
    (() => {
      const Original = window.Blob;
      window.Blob = class Override extends Original {
        constructor(...args) {
          super(...args);
          console.trace(args);
          debugger;
        }
      }
    })();
  </script>

これでどのようなコードが誰によって埋め込まれているか確認できました。

Blob URLを使うことで、same-origin制約を無視してWorkerを初期化することができるようになります。

まとめ

  • ChromeのDeveloper Tools、PerformanceタブでWorkerなどがどのようなコード(関数)を実行しているかタイムラインで確認できる
  • SafariのWeb development tools、Networkタブでリクエストおよびレスポンスを上書きして動作確認できる
  • クラスインスタンスの初期化時に処理を挟む場合対象クラスをextendsするとよい
  • Blob URLを用いたWorkerの初期化はよくある
4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?