Move CPU-heavy work off the main thread
Problem
Sorting, compression, or data processing blocks input and rendering on the main browser thread.
Before you start
Profile a realistic input and define a serializable message contract. Browser APIs and DOM nodes cannot be passed to the worker as ordinary values.
Recipe
Point ng-worker at a worker file and bind its result:
<button
ng-worker="/workers/sort.js"
data-params="{ items: products }"
on-result="sortedProducts = $result"
on-error="sortError = error"
trigger="click"
>
Sort products
</button>
<ul>
<li ng-repeat="product in sortedProducts">{{ product.name }}</li>
</ul>
The worker receives data-params through postMessage:
self.onmessage = (event) => {
const sorted = event.data.items
.slice()
.sort((left, right) => left.name.localeCompare(right.name));
self.postMessage(sorted);
};
AngularTS assigns the reply to $result and updates the scope expression in
on-result. The directive terminates its worker when its scope is destroyed.
Use data-request with a registered shared worker when several callers need
correlated request and response messages.
Failure path
Worker startup and cloning can cost more than the task. Ignore stale replies, terminate owned workers, and keep errors visible in the owning UI.
Apply it now
Profile the interaction before adding a worker. Move work only when a measured CPU task blocks the main thread long enough to affect input or rendering. Define a small serializable request and response, test the largest realistic input, and decide how a newer request cancels or ignores an older result.
Verify
Compare the main-thread trace before and after moving the task. Confirm input stays responsive, stale replies are ignored, and the worker terminates with its scope.
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.