Implement a web worker that manages analyses. #1571
Comments
In order to keep our code clean, easily understood and up to standards I think we need a Outside this class no message should ever be send or received. This class should implement each of the commands listed here and return a An instance of this class can be exposed globally to allow other plugins to call it's methods. In addition to that I think we should also look at supporting custom assessments and custom research using I also don't think we should support |
Discussed during the architecture standup:
|
A bit of thinking about the abstraction: API around web workerThe code that implements YoastSEO.js should not have to know about the web worker at all. To implement this we need a wrapper around the worker. In browsers that don't support web workers it should all still work. It should look a bit like this:
|
Notes from the kick-off meeting:
|
This has been implemented |
For Yoast/wordpress-seo#5393 we need to create an implementation of YoastSEO.js that works completely inside a web worker. This is a specification&roadmap about how it should work.
Why do we want to use web workers?
We want to keep the main thread free of any non-UI work. For a good primer on why we want this you can ready this great article on the subject of 120 fps. Our analysis is definitely non-UI work.
How to implement them?
Web workers are themselves fairly easy to implement. By reading the documentation about web workers on MDN you can understand how they work. I will recap this documentation shortly and highlight implementation details specific to us.
For our purposes I think we should have one 'simple' web worker. So everything about
SharedWorker
can be ignored. Shared workers are used if you want to share the same worker in multiple tabs/windows. I don't think we need that, at least for now.In YoastSEO.js we want to implement code for both the complete web worker and code for the main thread that communicates with the web worker.
What do we need to change to make it fit.
A web worker is basically an extra piece of code that runs in the background that you can communicate with. To start a worker you need a standalone script. I've done a bit of test setup in Yoast SEO on the
stories/web-worker-test
branch. This contains a standalone script that can accept messages.This means that web workers are by their nature asynchronous. You send them a message and a result is returned. Our architecture is not suited for this yet. So we need to fix that. Logic inside the worker can be synchronous, so that gives us some leeway.
The worker should contain all the logic to analyze any
Paper
object.Message format
I would like the following general format
This also makes organization natural and easy, for every message we can have a separate file in a
.../worker
folder.Available commands
To the worker: initialize
The payload should contain all the configuration that is necessary for executing the analysis. For example whether the content and keyword analyses are active. If one of them isn't active that work is not necessary.
To the worker: analyze
This command is the main command. This will analyze a given
Paper
. The payload looks like this:The configuration should be send with every message, because that way the analysis will always be correct for the given
Paper
+ configuration.To the worker: registerCustomScript
Other plugins need to be able to add custom research and assessments. Because we want all analysis to run in the worker, this can only be done by specifying the name of a script to import inside the worker. This script will be imported using
importScripts
. That script then has access to theself
scope of the worker.The
self
scope of the worker has these methods that can be used to register custom research and assessments:The payload to register a custom script looks like this:
The following methods will also be available to the custom script:
From the worker: registeredCustomScript
A simple message to let the code outside the worker know that the custom script has been registered and the all analyses including the given ID and any analysis afterwards will be run including the custom script.
From the worker: results
This will be send as the result of an
analyze
command. Theid
should match theid
passed in theanalyze
message. This way the receiving page can correlate the analysis with the result. It also makes it possible to discard results if theid
does not correspond to theid
of the last analyze request that was send to the worker.The message looks like this:
Temporary screenshot of the diagram
Todos
Gotchas
Because workers only work on the same domain as the main page, you cannot use the web pack dev server. I've included a piece of code that works around this. This should not be used in production. But it is incredibly useful to be able to test workers locally.
The text was updated successfully, but these errors were encountered: