Vue performance optimization using a web worker
HTML-код
- Опубликовано: 11 сен 2020
- Optimize your vue application by offloading your heavy-duty work to a second thread using a web worker.
In this video, we are hooking a web worker into your application, into your standard vue cli webpack workflow.
Tools used in this video:
* vue cli (cli.vuejs.org/)
* worker loader for webpack (webpack.js.org/loaders/worker...)
* comlink (github.com/GoogleChromeLabs/c...)
I forgot to ask you in the video what you are going to move into your workers, please leave a comment 😁👍
Fantastic tutorial! Thank you so much for posting this.
This was helpful! Thanks for the demo
Great video, thanks!
Thanks a lot for such precise tutorial
Glad it was helpful!
❤ this tutorial.. Want more performance related tutorial
Will definitely make more videos related to performance as its one of my favorite subjects when it comes to development. Just need to sort my life out a bit first 😊
Beautiful
Useful
Sweet video! Now let's make this work with Cuda cores 😎🤪
🤪😘
thanks man, very useful! I have one question: what is the best practice, if you need to use some dependencies inside Web Worker function? E.g. I'm using Angular and need to use a function or static variables from some service class
I don't know how angular is wired up. Would it be possible to extract the thing you want to share into a plain js module and have both your service and worker import it? The part you reference will be duplicated into both bundles by your bundler.
Hi Christopher, I love your video and I have a question: How can I do if I want to put the worker result in a vue component instead of showing it in the console? What do I need to modify in worker-api.js? Thanks!
You pass the result from the worker back to the parent script via
self.postMessage(msg)
in the parent script you set up an EventListener
worker.addEventListener('message', msg => { /* do someting with msg */ })
which will capture it, thus you can do what ever you want with it in the Vue component.
@@LeoPlaw Ok, thanks. But..can I code in { /* do someting with msg */ } something like this : "this.variable = e.data.something"? this.variable is an item of vue data
1:57 (why use self if u can use 'this' instead?) it points to the same value - window, if its not assigned anywhere else.
You could do that instead I guess. I usually use this only in places where it has been bound to something where I have no other choice but to use it. I generally prefer to explicit when coding, as it makes it more clear what my expectations were at the time of writing.
I was trying to perform some S3 operations using a webworker. But I am having troubles with importing required aws libraries to the web worker as import is not defined. Do you know any workaround for this?
I'm not sure what you are trying to do, sounds like you are trying to use a package intended for nodejs in the context of the browser?
Would love to see this using Vue3
i dont think it would be any different in vue3?
'postMessage' on 'Worker': HTMLDivElement object could not be cloned.
I have a hard work, its print DOM and return in canvas, with Html2Canvas lib. but i got this error, can i solve?
You do not have the dom in the worker context, you might not be able to use a worker for this.
Excuse me? But how can i terminate 1 function on it when destroy component and active it when component work?
The idea is that the worker is always running. You just pass messages back and forth. I don't know if that answered your question. 🙃
Why i need worker? Whats the point
You probably don't. But you should know they exist incase you do. In regular gui development you usually do your work in background threads to prevent the main/ui thread from being blocked. As the js runtime is single threaded you can't do that there. That is usually no problem as the work your doing normally finish within the 16ms rendering budget you have, and your 60 fps is maintained. Or, the application your doing doesn't really care if there are frames skipped. But if you have hard work to do and maintaining 60 fps is a requirement for your app, then a worker can be a way to make it work.
How can i return value inside worker.js with setInterval?
(ex) setInterval(() => { if (value === new Date().getTime()) return {isToday: true} },1000)
Thank you!!
in a plain worker, you would have to post a message back to the "main" thread. setInterval(() => { self.postMessage({ isToday: true }) }. And in the main thread you would have to handle the response in message eventhandler.
@@lindblomdev Can i use with Comlink? If is Yes, Can you tell me how?
We use regular message passing nowadays. But I checked comlink again and it has a nice looking proxy that looks promising for what you are trying to do.
Example you can checkout here: github.com/GoogleChromeLabs/comlink/tree/main/docs/examples/02-callback-example
you dont have any heavy work there, what you called an optimization is a lie. You havent even proved your point on your environment with your "while" loops to actually measure performance what is faster (while in a promise loop or while in a worker thread). People save your 15 mins of life and dont watch it, and dont bother with webworkers.
1. Single threaded applications are always faster with optimization of code execution in mind
2. Web workers will have to copy its result to a main thread when they are done (are you trying to make your app even more memory hungry?)
3. You cant offload something to webworker (usually) and dont wait for its result. You will have to wait for this result anyway in 98% of all webapps, but actually copying and pasting from webworker will make it even longer a task
knowing the cost of a webworker, how would you ever "optimize" your app with a single task when you promisify it and wait for it anyway? This video is only usefull for showing you how webworkers work, but the title is misleading (and description also)
I don't fully remeber what I did in the video, but I do believe that I froze the browser with a loop, and then it was moved to a worker to not freeze or some thing. It was meant to simulate hard script work. And prove that you can still do this work in a worker without bogging down the ui.
Can you explain the "while in a promise loop"?
We are running most of our applications in workers where I work now. We moved all the business logic over there and only ship state needed for the ui to the main thread. We built our own data driven router and state management for this.
But you are right, as long as you don't block the event loop for 16ms or can accept some jank. A web worker probably won't help you.
You are quite mistaken. In my work we need to use workers because we have a process that takes between 10 and 30 seconds depending on the client logged in. It's a very serious problem if we leave the client's UI stuck for so long, especially because we use a lot of responsive charts on dashboard. Web Workers are extremely important
Well, in our company app we have an array with subitems which can have x amount of subitems themselves and this array is being recursively searched by a search field. These are thousands of items and even more subitems which, even with debouncing the search, slow down the UX significantly, so I will definitely try this as a solution. Quick search regarding the memory overhead shows that serializing the data in binary or some other format before copying would greatly reduce the ill effects. That being said, I welcome any counter-arguments and alternative solutions.
Getting error : SecurityError:failed to construct worker : script at '127.0.0.1:9696/js/CloclTimer.worker.js' cannot be accessed from origin '127.0.0.1'
How can i solve this