Web Workers

다음 예제는 Univer에서 Worker를 사용하는 기본 방법을 보여 줍니다.

Sheets에서 Worker는 수식 계산과 같이 많은 연산이 필요한 작업에 주로 사용됩니다. Worker1 프로세스에서 수식 계산을 실행하면 메인 스레드의 부담을 줄일 수 있으며, 통합 문서에 수식이 많을 때도 페이지 렌더링과 상호작용의 반응성을 유지할 수 있습니다.

플러그인 모드

설치의 플러그인 모드 설정을 기준으로 렌더링과 UI 플러그인은 메인 스레드에 유지하세요. 기존 계산 관련 플러그인 세 개의 등록을 아래 설정으로 바꾸고 통합 문서를 만들기 전에 메인 스레드 RPC 플러그인을 추가하세요.

TypeScript
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에 위임합니다.

TypeScript
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.KO_KR })univer.registerPlugin(UniverSheetsPlugin, { onlyRegisterFormulaRelatedMutations: true })univer.registerPlugin(UniverFormulaEnginePlugin)univer.registerPlugin(UniverRPCWorkerThreadPlugin)univer.registerPlugin(UniverRemoteSheetsFormulaPlugin)

필터를 사용하면 양쪽에 @univerjs/sheets-filter의 UniverSheetsFilterPlugin을 등록해 SUBTOTAL 같은 수식에 필터 결과를 반영하세요. UniverSheetsFilterUIPlugin은 메인 스레드에만 등록합니다.

피벗 테이블을 사용하면 양쪽에 UniverLicensePlugin, UniverProFormulaEnginePlugin, UniverSheetsPivotTablePlugin도 등록하세요. 뒤의 두 플러그인의 notExecuteFormula를 메인 스레드에서는 true, Worker에서는 false로 설정합니다. 양쪽에 라이선스를 전달하고 피벗 UI는 메인 스레드에 유지하세요. 사용자 정의 수식 구현도 양쪽 수식 엔진에 등록해야 합니다.

프리셋 모드

UniverSheetsCorePreset 구성의 workerURL 옵션을 사용하면 Worker의 URL을 지정하고 Worker 모드를 활성화할 수 있습니다.

예제: sheets-core-with-worker

이 예제에서는 SUBTOTAL 수식 계산이 sheets-filter에서 숨긴 행의 영향을 받으므로 sheets-filter 프리셋 패키지를 가져옵니다. Worker에서 수식 계산을 실행할 때는 sheets-filter도 Worker에서 실행해야 합니다.

TypeScript
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' })
TypeScript
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(),  ],})

예제: sheets-collaboration-with-worker

TypeScript
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({    }),  ],})
TypeScript
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

  1. Web Worker는 브라우저의 메인 스레드 밖에서 JavaScript를 실행하고 메시지로 통신합니다. 페이지 DOM에 직접 접근할 수 없으며, 계산을 Worker로 옮겨도 편집기 UI가 함께 이동하지는 않습니다. ↩

이 가이드는 어떠셨나요?

© 2026 DreamNum Co., Ltd.