Web Workers
以下の例では、Univer における Worker1(Web Worker)機能の基本的な利用方法を示します。
Sheets では、Worker は数式計算などの計算負荷が高い処理を担うためによく使用されます。数式計算を Worker プロセスで実行することで、メインスレッドの負荷を抑え、ブック内の数式が多い場合でもページのレンダリングや操作への影響を軽減できます。
プラグインモード
インストールのプラグインモード設定を基に、描画と UI のプラグインはメインスレッドに残します。既存の計算関連プラグイン 3 つの登録を次の設定に変更し、ワークブックの作成前にメインスレッド RPC プラグインを追加します。
import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula'import { UniverRPCMainThreadPlugin } from '@univerjs/rpc'import { UniverSheetsPlugin } from '@univerjs/sheets'import { UniverSheetsFormulaPlugin } from '@univerjs/sheets-formula'univer.registerPlugin(UniverRPCMainThreadPlugin, { workerURL: new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' }),})univer.registerPlugin(UniverFormulaEnginePlugin, { notExecuteFormula: true })univer.registerPlugin(UniverSheetsPlugin, { notExecuteFormula: true })univer.registerPlugin(UniverSheetsFormulaPlugin, { notExecuteFormula: true })Worker には以下のデータと計算用プラグインのみを登録します。UI や描画プラグインは登録しません。メインスレッドの notExecuteFormula: true は計算を Worker に委譲します。
import { LocaleType, Univer } from '@univerjs/core'import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula'import { UniverRPCWorkerThreadPlugin } from '@univerjs/rpc'import { UniverSheetsPlugin } from '@univerjs/sheets'import { UniverRemoteSheetsFormulaPlugin } from '@univerjs/sheets-formula'const univer = new Univer({ locale: LocaleType.JA_JP })univer.registerPlugin(UniverSheetsPlugin, { onlyRegisterFormulaRelatedMutations: true })univer.registerPlugin(UniverFormulaEnginePlugin)univer.registerPlugin(UniverRPCWorkerThreadPlugin)univer.registerPlugin(UniverRemoteSheetsFormulaPlugin)フィルターを使う場合は、両方のスレッドに @univerjs/sheets-filter の UniverSheetsFilterPlugin を登録し、SUBTOTAL などにフィルター結果を反映します。UniverSheetsFilterUIPlugin はメインスレッドのみに登録します。
ピボットテーブルでは両方に UniverLicensePlugin、UniverProFormulaEnginePlugin、UniverSheetsPivotTablePlugin も登録します。後者 2 つの notExecuteFormula をメインスレッドで true、Worker で false にします。両方にライセンスを渡し、ピボット UI はメインスレッドに置きます。カスタム数式の実装も両方の数式エンジンに登録してください。
プリセットモード
UniverSheetsCorePreset の設定における workerURL オプションを指定することで、Worker の URL を設定し、Worker モードを有効化できます。
例: sheets-core-with-worker
この例では sheets-filter プリセットパッケージをインポートしています。理由は、SUBTOTAL 関数の計算結果が sheets-filter によって非表示行の影響を受けるためです。数式計算を Worker 内で実行する場合、sheets-filter も同じく Worker 内で実行される必要があります。
import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'import UniverPresetSheetsCoreJaJP from '@univerjs/preset-sheets-core/locales/ja-JP'import { UniverSheetsFilterPreset } from '@univerjs/preset-sheets-filter'import UniverPresetSheetsFilterJaJP from '@univerjs/preset-sheets-filter/locales/ja-JP'import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'import '@univerjs/preset-sheets-core/lib/index.css'import '@univerjs/preset-sheets-filter/lib/index.css'const { univerAPI } = createUniver({ locale: LocaleType.JA_JP, locales: { [LocaleType.JA_JP]: mergeLocales( UniverPresetSheetsCoreJaJP, UniverPresetSheetsFilterJaJP, ), }, presets: [ UniverSheetsCorePreset({ workerURL: new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' }), }), UniverSheetsFilterPreset(), ],})univerAPI.createWorkbook({ name: 'Test Sheet' })import UniverPresetSheetsCoreJaJP from '@univerjs/preset-sheets-core/locales/ja-JP'import { UniverSheetsCoreWorkerPreset } from '@univerjs/preset-sheets-core/worker'import UniverPresetSheetsFilterJaJP from '@univerjs/preset-sheets-filter/locales/ja-JP'import { UniverSheetsFilterWorkerPreset } from '@univerjs/preset-sheets-filter/worker'import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'createUniver({ locale: LocaleType.JA_JP, locales: { [LocaleType.JA_JP]: mergeLocales( UniverPresetSheetsCoreJaJP, UniverPresetSheetsFilterJaJP, ), }, presets: [ UniverSheetsCoreWorkerPreset(), UniverSheetsFilterWorkerPreset(), ],})例: sheets-collaboration-with-worker
import { UniverSheetsAdvancedPreset } from '@univerjs/preset-sheets-advanced'import UniverPresetSheetsAdvancedJaJP from '@univerjs/preset-sheets-advanced/locales/ja-JP'import { UniverSheetsCollaborationPreset } from '@univerjs/preset-sheets-collaboration'import UniverPresetSheetsCollaborationJaJP from '@univerjs/preset-sheets-collaboration/locales/ja-JP'import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'import UniverPresetSheetsCoreJaJP from '@univerjs/preset-sheets-core/locales/ja-JP'import { UniverSheetsDrawingPreset } from '@univerjs/preset-sheets-drawing'import UniverPresetSheetsDrawingJaJP from '@univerjs/preset-sheets-drawing/locales/ja-JP'import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'import '@univerjs/preset-sheets-core/lib/index.css'import '@univerjs/preset-sheets-drawing/lib/index.css'import '@univerjs/preset-sheets-advanced/lib/index.css'import '@univerjs/preset-sheets-collaboration/lib/index.css'const { univerAPI } = createUniver({ locale: LocaleType.JA_JP, locales: { [LocaleType.JA_JP]: mergeLocales( UniverPresetSheetsCoreJaJP, UniverPresetSheetsDrawingJaJP, UniverPresetSheetsAdvancedJaJP, UniverPresetSheetsCollaborationJaJP, ), }, collaboration: true, presets: [ UniverSheetsCorePreset({ workerURL: new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' }), }), UniverSheetsDrawingPreset({ collaboration: true, }), UniverSheetsAdvancedPreset({ useWorker: true, license: process.env.UNIVER_CLIENT_LICENSE || 'your license.txt', }), UniverSheetsCollaborationPreset({ }), ],})import UniverPresetSheetsAdvancedJaJP from '@univerjs/preset-sheets-advanced/locales/ja-JP'import { UniverSheetsAdvancedWorkerPreset } from '@univerjs/preset-sheets-advanced/worker'import UniverPresetSheetsCoreJaJP from '@univerjs/preset-sheets-core/locales/ja-JP'import { UniverSheetsCoreWorkerPreset } from '@univerjs/preset-sheets-core/worker'import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'createUniver({ locale: LocaleType.JA_JP, locales: { [LocaleType.JA_JP]: mergeLocales( UniverPresetSheetsCoreJaJP, UniverPresetSheetsAdvancedJaJP, ), }, presets: [ UniverSheetsCoreWorkerPreset(), UniverSheetsAdvancedWorkerPreset({ license: process.env.UNIVER_CLIENT_LICENSE || 'your license.txt', }), ],})Footnotes
-
Web Worker はブラウザーのメインスレッド外で JavaScript を実行し、メッセージで通信します。ページの DOM には直接アクセスできません。計算を Worker に移しても、エディター UI は移動しません。 ↩
このガイドはいかがですか?