Using Web Workers To Optimize Vue.js Components

Tram Ho


Occasionally, you will be forced to create extremely heavy components in creating and rendering, the main reason is that it must perform too complicated logic. I (the author) are no exception.

I created a site that uses StoryBlok , they have an extremely cool feature that is creating a rich-text field that content managers can use to format text such as text, list. , images, quote blocks, bold, italics …

When you get the content of rich-text from StoryBlok API, it will have its own structure. To render that data into HTML, you must call the richTextResolver.render(content) function from storyblok-js-client .

For example, if you encapsulate this function to a RichText.vue component, it basically looks like this:

The code looks pretty simple, doesn’t seem strange, but there’s something quite unexpected.

It seems that rendering is very heavy, most noticeable when rendering many components like this with a decent amount of content.

Now imagine the following scenario: You have a list of rich-text components on the page and a dropdown to filter based on which criteria. When changing on the dropdown filter, you fetch all the content again and the list will be redrawn.

This is where you notice the heavy of richTextResolver.render , the dropdown lag when closed after you select.

The reason is that by default JavaScript executes commands on the main thread, which is UI-blocking.

The problem is enlightened, So is there any cure?

Problem solving

Easy: Use Web Worker for rendering rich-text.

Web Workers run in a separate thread, more importantly, they are not UI-blocking , very suitable for our case.

Note: I didn’t go into Web Workers, you can see its documents .

Always remember that web workers have their own context, and by default we cannot access other external contexts, but we need access to storyblok-js-client module. To do this, Webpack has a worker-loader .

First, preset:

If you use Nuxt.js, we will configure it in nuxt.config.js as follows:

With this configuration, all *.worker.js files will be processed and loaded by worker-loader .

Now try to create render-html.worker.js

That is a basic way of doing worker. You need to listen to the message event – the way the worker communicates with the Vue.js app. From there you can get the data from the event, render it with storyblok-js-client and return the result self.postMessage .

Now we need to fix the RichText.vue component a bit to use the worker.


Surely you are curious about how much the performance will improve after using the worker, for sure. We will try to measure a little to performace more meaning.

In fact, you should read this post: learn and undestand how to meassure performance in Vue.js components to make sure you understand the test below.

I have mmeassure the component with medium-size (6x throttle) on my mac.

The result: The rendering time is 20.65x faster and the patch time is 1.39x faster, the figure is also impressive.

If you don’t know what render and patch mean, this article explains.

And that is today’s tip.

See you next month =))

The article has been translated from , thank you for reading the article.

Share the news now

Source : Viblo