Web Workerと、それを便利にするComlinkライブラリの紹介
りn
Web Workerと、それを便利にするComlinkライブラリの紹介
Web Workerとは
- 従来シングルスレッドのみだったWebブラウザにマルチスレッドを持ち込む仕組み
- 元々Webのスクリプト用途にはシングルスレッドで十分と考えられていた
- リッチなWebアプリやブラウザゲームなど高パフォーマンスを要求するようになった
- DOMを処理しているスレッドを妨げずに高負荷な処理を実行できる
- 基本的には一対一のメッセージチャネルを介してのみスレッド間通信を行う
欠点
- メッセージチャネルが一つあるだけなので通信が面倒
- RPC的なことをやりたい場合自分で実装しないといけない
- SharedArrayBufferで共有メモリを作れるがより複雑に
- 構造化複製可能な型しかやり取りできない
- 完全に等価ではないが、f(x) = JSON.parse(JSON.serialize(x)) において不動点であるx は転送可能だと思えばいい
Comlinkとは
- Web Workerをenjoyableにするライブラリ
- 双方のスレッドが持つオブジェクトを簡単に公開できる
- 構造化複製不可能なものもOK
- function, class, …
- Proxyで包むことによって転送可能にしている
- これらはオブジェクトの所有権を相手スレッド側に移さない
- 構造化複製不可能なものもOK
- もちろん所有権移動を伴うコピーや、大きなArrayBuffer等をコピーせずに移譲することも可能(C++で言うところのstd::move)
- TypeScript対応!(generics周りがちょっと弱め)
試してみる
$ npm install comlink
worker.js
import { expose } from 'comlink';
function add(a, b) {
return a + b;
}
expose(add);
main.js
import { wrap } from 'comlink';
const worker = new Worker(new URL('./worker.js', import.meta.url), {
type: 'module',
});
const add = wrap(worker);
const result = await add(3, 4);