Web workers vs Service workers vs Worklets

source: https://tech.ovoenergy.com/web-workers-vs-service-workers/

A worker is a script that runs in a thread separate from the main thread in the browser. This means you can run code without blocking (and avoid that nasty jumping cursor during heavy computation). Workers are not meant for UI updates and do not have access to the DOM.

Web Workers

Web Workers have been around for a quite a while now. They don’t have all the fancy capabilities of Service Workers, but when you need to offload heavy work to a separate thread they are the way to go.

Service Workers

Service Workers offer a lot more functionality for creating Progressive Web Apps which give a great experience for offline users or users with slow internet connections. The Service Worker can be used as a proxy for network events, allowing us to cache resources for offline use.

The basic steps are as follows:
Register and install the Service Worker.
On a network request, check the cache.
If there is a hit, return the cached content.

In conclusion

Use a Web Worker for heavy computation on the client. Use a Service Worker for offline capabilities like intercepting network requests, as well as other fun stuff like push notifications and synchronization of content in the background.


Web workers, service workers, and worklets. All of these are what I would call “Javascript Workers”, and although they do have some similarities in how they work, they have very little overlap in what they are used for.

Broadly speaking, a worker is a script that runs on a thread separate to the browser’s main thread. If you think about your typical Javascript file that is included in your HTML document via a <script> tag, that runs on the main thread. If there is too much activity on the main thread, it can slow down the site, making interactions jittery and unresponsive.

Web workers, service workers, and worklets are all scripts that run on a separate thread. So what are the differences between these three types of workers?

Web workers

Web workers are the most general purpose type of worker. Unlike service workers and worklets as we will see below, they do not have a specific use case, other than the feature of being run separately to the main thread. As a result, web workers can be used to offload pretty much any heavy processing from the main thread.

Web workers are created using the Web Workers API. After creating a dedicated Javascript file for our worker, we can add it as a new Worker.

/* main.js */ const myWorker = new Worker('worker.js');

This will start to run whatever code we have in the worker.js file. As I mentioned, this can be almost anything, but web workers are most useful for offloading processes that might take a long time or are run in parallel to other processes. A great example is the image processing web application, Squoosh, which uses web workers to handle image manipulation tasks, leaving the main thread available for the user to interact with the application without interruption.

Like all workers, web workers do not have access to the DOM, which means that any information needed will have to be passed between the worker and the main script using window.postMessage().

/* main.js */

// Create worker
const myWorker = new Worker('worker.js');

// Send message to worker

// Receive message from worker
myWorker.onmessage = function(e) {

In our worker script, we can listen for messages from the main script, and return a response.

/* worker.js */

// Receive message from main file
self.onmessage = function(e) {

// Send message to main file

Service workers

Service workers are a type of worker that serve the explicit purpose of being a proxy between the browser and the network and/or cache.

Like web workers, service workers are registered in the main javascript file, referencing a dedicated service worker file.

/* main.js */


Unlike regular web workers, service workers have some extra features that allow them to fulfil their proxy purpose. Once they are installed and activated, service workers are able to intercept any network requests made from the main document.

/* service-worker.js */

// Install
self.addEventListener('install', function(event) {
// ...

// Activate
self.addEventListener('activate', function(event) {
// ...

// Listen for network requests from the main document
self.addEventListener('fetch', function(event) {
// ...

Once intercepted, a service worker can, for example, respond by returning a document from the cache instead of going to the network, thereby allowing web applications to function offline!

/* service-worker.js */

self.addEventListener('fetch', function(event) {
// Return data from cache


Worklets are a very lightweight, highly specific, worker. They enable us as developers to hook into various parts of the browser’s rendering process.

When a web page is being rendered, the browser goes through a number of steps. I cover this in more detail in my article on Understanding the Critical Rendering Path, but there are four steps we need to worry about here — Style, Layout, Paint, & Composite.

Image credit: Rendering Performance, by Paul Lewis

Let’s take the Paint stage. This is where the browser applies the styles to each element. The worklet that hooks into this stage of rendering is the Paint Worklet.

The Paint Worklet allows us to create custom images that can be applied anywhere CSS expects an image, for example as a value to the background-image property.

To create a worklet, as with all workers, we register it in our main javascript file, referencing the dedicated worklet file.

/* main.js */


In our worklet file, we can create the custom image. The paint method works very similarly to the Canvas API. Here's an example of a simple black-to-white gradient.

/* myWorklet.js */

registerPaint('myGradient', class {
paint(ctx, size, properties) {
var gradient = ctx.createLinearGradient(0, 0, 0, size.height / 3);

gradient.addColorStop(0, "black");
gradient.addColorStop(0.7, "rgb(210, 210, 210)");
gradient.addColorStop(0.8, "rgb(230, 230, 230)");
gradient.addColorStop(1, "white");

ctx.fillStyle = gradient;
ctx.fillRect(0, 0, size.width, size.height / 3);

Finally, we can use this new worklet in our CSS, and the custom image we created will be applied like any other background image.

div { 
background-image: paint(myGradient);

In addition to the Paint Worklet, there are other worklets that hook into other stages of the rendering process. The Animation Worklet hooks into the Composite stage, and the Layout Worklet hooks in to the Layout stage.


To recap, web workers, service workers, and worklets are all scripts that run on a separate thread to the browser’s main thread. Where they differ is in where they are used and what features they have to enable these use cases.

Worklets are hooks into the browser’s rendering pipeline, enabling us to have low-level access to the browser’s rendering processes such as styling and layout.

Service workers are a proxy between the browser and the network. By intercepting requests made by the document, service workers can redirect requests to a cache, enabling offline access.

Web workers are general-purpose scripts that enable us to offload processor-intensive work from the main thread.

Experience with Front-end Technologies and MERN / MEAN Stack. Working on all Major UI Frameworks like React, Angular.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store