# Web Workers

- Human documentation: [https://docs.univer.ai/ko-KR/guides/sheets/getting-started/worker](https://docs.univer.ai/ko-KR/guides/sheets/getting-started/worker)

- Agent Markdown: [https://docs.univer.ai/ko-KR/guides/sheets/getting-started/worker.md](https://docs.univer.ai/ko-KR/guides/sheets/getting-started/worker.md)

- Requested language: `ko-KR`

- Content language: `ko-KR`

- Documentation version: `1.0.4`

- Source: [sheets/getting-started/worker.ko-KR.mdx](https://github.com/dream-num/documentation/blob/dev/content/guides/sheets/getting-started/worker.ko-KR.mdx)

---

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

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

## 플러그인 모드

[설치](https://docs.univer.ai/ko-KR/guides/sheets/getting-started/installation.md)의 플러그인 모드 설정을 기준으로 렌더링과 UI 플러그인은 메인 스레드에 유지하세요. 기존 계산 관련 플러그인 세 개의 등록을 아래 설정으로 바꾸고 통합 문서를 만들기 전에 메인 스레드 RPC 플러그인을 추가하세요.

```typescript title="main.ts"
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 title="worker.ts"
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 title="main.ts"
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 title="worker.ts"
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 title="main.ts"
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 title="worker.ts"
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',
    }),
  ],
})
```

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