-
-
Notifications
You must be signed in to change notification settings - Fork 318
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SEO Compatible Rendering #578
Comments
This is an "experimental feature" and belongs in v2 -> v3 |
In order to take advantage of why users want SSR (namely SEO), IDOM might need to be modified to use HTTP instead of websockets. |
So my thinking on this is that only the initial page needs the be rendered in HTML. Subsequent updates could be communicated via websockets. Then again, React has a way to do this, so if we can do server-side rendering with a traditional React solution and communicate via sockets on localhost then that could be an option too. The latter is a bit more complicated with respect to the tooling, but less work with respect to actual implementation, so I'd probably lean towards the latter assuming it's possible. |
I did some investigation and here's what I came up with. The Ugly
Suggested Approach
Resources
|
@rmorshea I've discovered react actually has an API for this. https://beta.reactjs.org/reference/react-dom/client/hydrateRoot |
We're technically using Preact right now, so we'd probably what we'd want to pay attention to its specific hydration details. It would be interesting to see if there's anything special about pre-rendering. If not, then we could potentially just use |
I don't think we should use that pre-rendering API. If we do, then
We may want to stare at the pre-rendering source and see if anything unique is being done, which we could implement as mutations. I doubt it though, so |
I've been doing some thinking on this. I think we might need to take a "zero rehydration" policy and always double render (HTTP followed by WS render). Since the HTTP stack and websocket stack aren't always on the same process/thread, we can't store any data in-memory. Additionally, not all backends have have a built-in database framework... and we really don't want to build any database features directly into ReactPy. So, to keep things consistent it's probably best to do the following:
If we really want to, we can enable rehydration for batteries-included frameworks such as Django. But in my opinion, having a the functional difference between the rehydration/non-rehydration between frameworks isn't a good idea. Even more so when considering that it would introduce more maintenance burdens. |
Current Situation
Currently, sites built in IDOM are not SEO compatible. This is a fairly common issue with JavaScript frameworks such as ReactJS.
Prior discussion: #486
Prior Issue: reactive-python/reactpy-django#93
Proposed Actions
To resolve this, there needs to be an initial HTTP render, followed by a JavaScript re-render.
This will likely be accomplished through Preact's hydrate API.
The best way of doing this requires some form of persistent storage of all hook states, due to the fact that ASGI websockets are a completely different stack than HTTP rendering. Hook states will need to be stored server side in order to prevent spoofing. We can either use a database or determine if multiprocessing.shared_memory can be used here.
dill.pickle
) andThe database model might look like this:
This design brings up a challenge of determining when to evict old hook states (for example, if a user did the initial render but for some reason never performed a websocket connection). We don't want to store everything forever, so some configurable age-based eviction strategy might be needed. Expired entries should be culled before each fetch of
IdomHookState.hook_attributes
. Expiration should be based on last access time, which is fairly simple to do in Django like such:last_accessed = models.DateTimeField(auto_now=True)
.The text was updated successfully, but these errors were encountered: