Web Workers
The following examples demonstrate the basic usage of Worker1 in Univer.
In Sheets, Workers are commonly used for compute-intensive tasks such as formula calculation. Running formula calculation in a Worker process can reduce pressure on the main thread and keep page rendering and interactions responsive when a workbook contains many formulas.
Plugin Mode
Start from the Plugin Mode setup in installation. Keep the rendering and UI plugins on the main thread. Replace the existing registrations of the three calculation plugins below, then add the main-thread RPC plugin before creating the workbook.
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 })The Worker contains only the data and calculation plugins shown below; do not register UI or rendering plugins there. notExecuteFormula: true delegates main-thread calculation to the Worker.
import { LocaleType, Univer } from '@univerjs/core'import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula/worker'import { UniverRPCWorkerThreadPlugin } from '@univerjs/rpc/worker'import { UniverSheetsPlugin } from '@univerjs/sheets/worker'import { UniverRemoteSheetsFormulaPlugin } from '@univerjs/sheets-formula/worker'const univer = new Univer({ locale: LocaleType.EN_US })univer.registerPlugin(UniverSheetsPlugin, { onlyRegisterFormulaRelatedMutations: true })univer.registerPlugin(UniverFormulaEnginePlugin)univer.registerPlugin(UniverRPCWorkerThreadPlugin)univer.registerPlugin(UniverRemoteSheetsFormulaPlugin)When using filters, register UniverSheetsFilterPlugin in both threads so formulas such as SUBTOTAL see filtered rows: import it from @univerjs/sheets-filter on the main thread and @univerjs/sheets-filter/worker in the Worker. Keep UniverSheetsFilterUIPlugin on the main thread.
Use these entry points for additional calculation plugins in the Worker. The main thread uses each package’s root entry. Keep all SDK package versions aligned.
import { UniverProFormulaEnginePlugin } from '@univerjs-pro/engine-formula/worker'import { UniverSheetsPivotChartWorkerPlugin } from '@univerjs-pro/sheets-pivot-chart/worker'import { UniverSheetsPivotTablePlugin } from '@univerjs-pro/sheets-pivot/worker'import { UniverSheetsSlicerPlugin } from '@univerjs-pro/sheets-slicer/worker'import { UniverSheetsTablePlugin } from '@univerjs/sheets-table/worker'For pivot tables, replace UniverFormulaEnginePlugin with UniverProFormulaEnginePlugin in both threads, and also register UniverLicensePlugin and UniverSheetsPivotTablePlugin. Set notExecuteFormula: true on the Pro formula engine and PivotTable plugin in the main thread, and false in the Worker. Supply the license in both runtimes, keep the pivot UI on the main thread, and register custom formula implementations in both formula engines.
Preset Mode
workerURL option in UniverSheetsCorePreset configuration allows you to specify the URL of the Worker and enable Worker mode.
Example: sheets-core-with-worker
This example imports the sheets-filter preset package because the SUBTOTAL formula calculation is affected by hidden rows in sheets-filter. When formula calculations are executed in a Worker, sheets-filter also needs to be executed in the Worker.
import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'import UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US'import { UniverSheetsFilterPreset } from '@univerjs/preset-sheets-filter'import UniverPresetSheetsFilterEnUS from '@univerjs/preset-sheets-filter/locales/en-US'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.EN_US, locales: { [LocaleType.EN_US]: mergeLocales( UniverPresetSheetsCoreEnUS, UniverPresetSheetsFilterEnUS, ), }, presets: [ UniverSheetsCorePreset({ workerURL: new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' }), }), UniverSheetsFilterPreset(), ],})univerAPI.createWorkbook({ name: 'Test Sheet' })import UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US'import { UniverSheetsCoreWorkerPreset } from '@univerjs/preset-sheets-core/worker'import UniverPresetSheetsFilterEnUS from '@univerjs/preset-sheets-filter/locales/en-US'import { UniverSheetsFilterWorkerPreset } from '@univerjs/preset-sheets-filter/worker'import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'createUniver({ locale: LocaleType.EN_US, locales: { [LocaleType.EN_US]: mergeLocales( UniverPresetSheetsCoreEnUS, UniverPresetSheetsFilterEnUS, ), }, presets: [ UniverSheetsCoreWorkerPreset(), UniverSheetsFilterWorkerPreset(), ],})Example: sheets-collaboration-with-worker
import { UniverSheetsAdvancedPreset } from '@univerjs/preset-sheets-advanced'import UniverPresetSheetsAdvancedEnUS from '@univerjs/preset-sheets-advanced/locales/en-US'import { UniverSheetsCollaborationPreset } from '@univerjs/preset-sheets-collaboration'import UniverPresetSheetsCollaborationEnUS from '@univerjs/preset-sheets-collaboration/locales/en-US'import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'import UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US'import { UniverSheetsDrawingPreset } from '@univerjs/preset-sheets-drawing'import UniverPresetSheetsDrawingEnUS from '@univerjs/preset-sheets-drawing/locales/en-US'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.EN_US, locales: { [LocaleType.EN_US]: mergeLocales( UniverPresetSheetsCoreEnUS, UniverPresetSheetsDrawingEnUS, UniverPresetSheetsAdvancedEnUS, UniverPresetSheetsCollaborationEnUS, ), }, 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 UniverPresetSheetsAdvancedEnUS from '@univerjs/preset-sheets-advanced/locales/en-US'import { UniverSheetsAdvancedWorkerPreset } from '@univerjs/preset-sheets-advanced/worker'import UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US'import { UniverSheetsCoreWorkerPreset } from '@univerjs/preset-sheets-core/worker'import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'createUniver({ locale: LocaleType.EN_US, locales: { [LocaleType.EN_US]: mergeLocales( UniverPresetSheetsCoreEnUS, UniverPresetSheetsAdvancedEnUS, ), }, presets: [ UniverSheetsCoreWorkerPreset(), UniverSheetsAdvancedWorkerPreset({ license: process.env.UNIVER_CLIENT_LICENSE || 'your license.txt', }), ],})Footnotes
-
A Web Worker runs JavaScript outside the browser’s main thread and exchanges messages with it. It cannot access the page DOM directly; moving calculations into a Worker does not move the editor UI there. ↩
How is this guide?