Closed josevalim closed 1 year ago
@josevalim Would love to work on this. Is it still relevant and do you still think it's a good approach?
If so could you give me some pointers to get started?
Hi @ismaelga! This is definitely relevant but this is a complex task because it touches on several parts of the tag engine, the diff rendering mechanism, and the JS client.
Good news is that it is on my todo list for the coming days, so we should have some progress on it soon.
I tried this and unfortunately this optimization wouldn't trigger as frequently as we thought it would. :(
Would it be possible to mark parts of a component as something that should not be sent over the wire on every render? My usecase for this is that I have a dynamic form that has a block builder that's built from an embeds_many field. This will send huge updates on every change, even when I try to pull the whole field out with phx-update="ignore". The embeds_many field won't change track (I think?) so I'm back to thinking that my use case maybe is the wrong fit for live view?
If your whole template is dynamic, there isn’t much we can do. At best you can try to isolate the dynamic parts, so you send less things when only one part changes.
actually would be nice to have some kind of guide on how to design component structure to optimize rendering performance
We do talk about best practices when it comes to using assigns in templates. All other optimizations, both on client and server happen automatically, you don’t have to do anything. If that changes, we will document it.
Today, when rendering a large page, all of the static components of the page will be parsed and diffed by morphdom on every patch. This is an proposal to optimize rendering by relying on the HEEx engine to skip large parts of the tree. This will bring performance benefits similar to those found in Svelte.
Imagine this template:
Where
<tag
is any element with optional attrs and aLARGE
amount of content and no dynamic content.Today, it will be sent over the wire like this:
Our proposal is to convert the static into a list of three elements, containing:
So we would get this:
Now, on the initial render, will we render convert it back to these statics:
Where
phx-magic-id
is a unique client ID (it can be a client-based counter). Immediately after rendering it, we will have:Notice that we were able to remove all
attrs
and theLARGE
contents of the tag. We will instruct morphdom to first consider phx-magic-id and then the DOM id when comparing elements, reducing the amount of parsed and diffed content. This will also reduce the amount of data stored on the page.Tasks
Implementing this feature is not necessarily complex. The trickiest part is changing the engine to identify the largest single-element subtree according to a threshold. Furthermore, part of the initial work in scrubbing and skip tags can already be implemented for components and then shared in the future.