Halo, hello, I’m 132. You’ve been a bitch for a long time!
Recently class is really busy, little time to write code ::>_<:: today, mainly to bring you a new framework VOE
However, it is not…
Voe is an underlying applets framework
This means that it implements dual threading of applets, sandboxes the Web environment, and shields DOM capabilities
Next, I will introduce the main ideas in combination with wechat applets:
The target
Absolute control, meaning users can’t manipulate the DOM, can’t use web apis, can’t use full JSX and HTML, can’t… Nothing!
Just like the role of SM, S’s absolute control and abuse of M, M can only obey orders and be abused
That’s why I call the two-threaded architecture of applets master slave architecture.
The sandbox
The dom cannot be manipulated in applets, not because it blocks the DOM API or events, which would be impractical
Everyone is looking for a non-DOM environment to sandbox, like V8, like Worker, like Native, like WASM
The above is OK, I guess the micro channel small program is also used in a similar sandbox
Voe uses web workers as sandboxes
Why not use V8 or Native?
This is a purely personal choice, not v8 or Native, but I prefer the former. The computing power of The Web worker is superior to V8 or Native by default (the same hardware level), but V8 also has advantages, such as node can use cookies, And then you have some advanced apis
Split the frame into two different threads
The important thing is, how to arrange the framework work between the two threads?
There are a few principles:
- The user logic must run in the worker and not touch the main thread at all
- The logic of computing force should be put into worker as much as possible
As a result, it becomes the following:
Then, the difficulty is that the gap between the sandbox and the main thread comes from DOM elements and event functions, both of which cannot be passed
I racked my brains and thought of a perfect solution
Save things that cannot be delivered to your own thread and create a map, passing the index to another thread
For example, the event is passed like this:
let handlers = new WeakSet(a)if (props) {
for (const k in props) {
if (k[0= = ='o' && k[1= = ='n') {
let e = props[k]
let id = handlers.size + 1
handlers.set({ id: e })
props[k] = id
}
}
}
Copy the code
The event is stored in the map, and then the ID is passed to the main thread. When the main thread event is triggered, the ID and event parameters are returned to the worker
for (const k in props) {
if (k[0= = ='o' && k[1= = ='n') {
let id = props[k]
props[k] = event= > {
// Do not pass too many, omit the simplified operation of the event
worker.postMessage({
type: EVENT,
event,
id
})
}
}
}
Copy the code
Then in worker, the corresponding event is found and triggered according to the index mapping
Yeah, that’s right. It’s a universal method, like our diff method
Since diff can’t pass out the DOM, we pass the DOM index
if(oldVNode ==null||oldVNode.type! ==newVNode.type) { parent.insertBefore(createNode(newVNode), node) }Copy the code
For example, parent and node are DOM elements and cannot be passed. Pass their index, may be looks like this:
[[0.'insertBefore'.1]]Copy the code
Dom looks like this:
<div id="root" index="0">
<ul index="1">
<li index="2" />
<li index="3" />
</ul>
</div>
Copy the code
If we were to delete the node with index 3, the resulting structure would look like this:
[[1.'removeChild'.3]]Copy the code
We have found a way to implement a different diff algorithm
To know, wechat small programs have not found similar ideas, their diff is still the set of ancient depth traversal of Virtual-dom, multiple codes and poor performance…
In the same vein, we can also pass the main thread function parameters to the main thread in the worker
For example, if we simulate an alert method, we can do this:
function alert(text){
postMessage({
name:'alert',
text
})
}
Copy the code
The main thread then receives the parameters and executes
worker.onmessage = {data} => window[data.name](data.text)
Copy the code
Perfect, so we can optionally use main thread methods and variables in the worker
In summary, the main ideas for dual threading are described above, and they apply not only to this framework, but also to other cross-end scenarios
vue 3
Vue 3 has the same name and API as Vue 3. In fact, I did copy the core of Vue 3, including dependency collection, responsiveness, status updates, composite functions…
This is just a matter of passing, but the API is nothing compared to the core idea of voe, right
Because almost all companies, if you want to make their own small programs, can only come to reference ideas, and then API is likely to be consistent with wechat
So I think the VUE 3 API is simple enough to weaken the API
Here it is…
You can use voe as the minimum implementation of VUE 3, used to assist in reading the source code is also very OK ha!
Dual threading vs. asynchronous rendering
As an aside, you probably know about the framework FRE.js I wrote earlier, and the mechanics of asynchronous rendering such as Concurrent, suspense, etc
Now I’m working with Web workers because they have a similar mindset and the same scenario
- Time slicing makes use of macro tasks and puts low-priority tasks such as DIff into the macro task queue, thus simulating dual threading without blocking UI
- Dual-threading makes use of Web workers to put tasks with high computing power such as DIff into workers, so as not to block UI rendering of the main thread
The scenes for both are also visualizations, high frame rate animations, lots of data and calculations…
Unfortunately, the demand for this scenario is so rare that both the Preact and Vue teams are saying they don’t want it and don’t need it :>_<::
However, as far as I am concerned, I don’t care whether the framework is used or not, nor do I care about the business. I prefer technical innovation, so in this respect, as long as there is a new idea, it will always have its value
conclusion
Hu ~ finally finished, in nuggets issued a document, must be long ah
And finally on Voe’s Github:
github.com/132yse/voe
Welcome to star!
In addition, a front-end group was established for exchanging various new ideas: 813783512