dai-shi / react-worker-components

React Worker Components simplify using Web Workers
MIT License
337 stars 7 forks source link

Exciting! Could you explain more? #2

Open csr632 opened 3 years ago

csr632 commented 3 years ago

I haven't looked into this project closely. But I am really excited! Could you explain more?

Is this issue related to this project?

dai-shi commented 3 years ago

Seems like related, but not fully.

The idea to run react in webworkers isn't new. I guess there was a talk a couple of years ago, and then there was react-native-dom, which I got interested. But, the difficulty is handling events from DOM. It's really hard to transfer all DOM events.

I have some previous work with webworkers like react-hooks-worker and redux-in-worker. Both of these are to avoid transferring the events. But their usages are a bit limited.

I'm not super familiar with react-flight or RSC, but the idea of only transferring props clicked me. That might be a solution to bridge between main thread and worker thread.

I wasn't so sure but keeping react elements (vdom) referential identity seems to keep states. There are still some to do, but the transfer method I implemented worked so far.

I'm happy to discuss about this project with someone. So, please give follow-up questions and also take a deeper look.

csr632 commented 3 years ago

The serializer seems to be the most important part. The most difficult part is, how to resolve the limitation of serialization? Here is my understanding.

Q1: How do you serialize JSX object like props.children? My understanding: walk every React element object in the JSX tree. If React element type is native element like 'div', keep the type as string 'div'; If the React element type is user-defined component, you just replace the type with the registered name. That's why we must register every components that may present at the props of worker-components, and every components that may present at the return of worker-components, right?

Q2: How do you serialize function like props.onClick? I have no idea! I think we have to avoid event between main components and worker components. This is one of the limitation of react-worker-components, right?

Q3: It seems that react-worker-components can only shallow-render worker-components. The returned children JSX of a worker-component is further rendered within the main thread. Could it support deep-render?

dai-shi commented 3 years ago

Q3: It seems that react-worker-components can only shallow-render worker-components. The returned children JSX of a worker-component is further rendered within the main thread. Could it support deep-render?

I fixed this in v0.0.2. It will now deep-render if the component is not registered. (we may want to come up better ideas with this register mechanism.)

Q2: How do you serialize function like props.onClick? I have no idea! I think we have to avoid event between main components and worker components. This is one of the limitation of react-worker-components, right?

Correct. Non serializable JSX elements can't be transferred. Such components should be registered. See how TextBox component in the examples works. Isn't it a similar limitation in Server Components too?

In react-worker-components, props that goes between main and worker must be serializable and immutable.

Q1: How do you serialize JSX object like props.children? My understanding: walk every React element object in the JSX tree. If React element type is native element like 'div', keep the type as string 'div'; If the React element type is user-defined component, you just replace the type with the registered name. That's why we must register every components that may present at the props of worker-components, and every components that may present at the return of worker-components, right?

Yes, you get the point correctly. As noted above, currently, there are registered user-defined components and non-registered user-defined components. registered ones are replaced with string names. non-registered ones must be serializable. We must register the same component with the same name at the both ends (main / worker).

I'm not sure if this approach has any other pitfalls. There might be.

dai-shi commented 3 years ago

I wasn't so sure but keeping react elements (vdom) referential identity seems to keep states.

To keep states, element referential identity wasn't important. Maybe only element type (function).