Skip to main content
Version: 3.9.0-beta.111 (Latest)

Web Worker Implementation Guide

Overview​

Web Workers enable running computationally intensive tasks in background threads without blocking the UI. This guide explains how to implement them step by step.

Basic Setup​

1. Create Your Worker File​

First, create a worker file with your background tasks:

// myWorker.js
import { expose } from 'comlink';

const obj = {
// Simple task
basicCalculation({ data }) {
// Your computation here
return result;
},

// Task with progress updates
longRunningTask({ data }, progressCallback) {
const total = data.length;

for (let i = 0; i < total; i++) {
// Your processing logic

if (progressCallback) {
const progress = Math.round((i / total) * 100);
progressCallback(progress);
}
}

return result;
}
};

expose(obj);

2. Register the Worker​

In the main thread, can be your service, commands module, etc.

import { getWebWorkerManager } from '@cornerstonejs/core';

const workerManager = getWebWorkerManager();

// Define worker creation function
const workerFn = () => {
return new Worker(
new URL('./myWorker.js', import.meta.url),
{ name: 'my-worker' }
);
};

// Registration options
const options = {
maxWorkerInstances: 1, // Number of concurrent workers
autoTerminateOnIdle: {
enabled: true,
idleTimeThreshold: 3000, // Terminate after 3s idle
},
};

// Register the worker
workerManager.registerWorker('my-worker', workerFn, options);
info

It is recommended to register the worker in top of the commands module. So that it gets registered before any commands that need to use the worker.

3. Execute Tasks​

// Basic execution
try {
const result = await workerManager.executeTask(
'my-worker',
'basicCalculation',
{ data: myData }
);
} catch (error) {
console.error('Task failed:', error);
}

// Execution with progress callback
try {
const result = await workerManager.executeTask(
'my-worker',
'longRunningTask',
{ data: myData },
{
callbacks: [
(progress) => {
console.log(`Progress: ${progress}%`);
}
]
}
);
} catch (error) {
console.error('Task failed:', error);
}

Progress Events (Optional)​

If you want to show progress in your UI as a loading spinner, you can implement a progress event system:

1. Publish Progress Events​

// Helper to trigger progress events
const publishProgress = (eventTarget, progress, taskId) => {
triggerEvent(eventTarget, 'WEB_WORKER_PROGRESS', {
progress, // number 0-100
type: 'YOUR_TASK_TYPE', // can be any string identifier
id: taskId, // unique task identifier
});
};

// Usage in your application
async function runTaskWithProgress(data) {
// Start progress
publishProgress(eventTarget, 0, data.id);

try {
const result = await workerManager.executeTask(
'my-worker',
'longRunningTask',
{ data },
{
callbacks: [
(progress) => {
publishProgress(eventTarget, progress, data.id);
}
]
}
);

// Complete progress
publishProgress(eventTarget, 100, data.id);

return result;
} catch (error) {
console.error('Task failed:', error);
throw error;
}
}

Note: Publishing the WEB_WORKER_PROGRESS event on Cornerstone's eventTarget will automatically trigger the built-in loading spinner. This gives users visual feedback while your worker runs in the background.

Multiple Methods in One Worker​

You can define multiple related methods in a single worker file:

// complexWorker.js
import { expose } from 'comlink';

const obj = {
processingMethod1({ data }, progressCallback) {
// Implementation
},

processingMethod2({ data }, progressCallback) {
// Implementation
},

processingMethod3({ data }, progressCallback) {
// Implementation
},

// Shared helper methods
_internalHelper() {
// Helper logic
}
};

expose(obj);