Add a switch to defer rendering of components in ComponentTagHelper#40316
Add a switch to defer rendering of components in ComponentTagHelper#40316pranavkm wants to merge 1 commit into
Conversation
16e72e9 to
ebebe23
Compare
This allows the HeadOutlet component to appear earlier in the document, but for rendering to be deferred until MVC starts emitting markup.
ebebe23 to
248f457
Compare
|
|
||
| public override string ProjectType { get; } = "blazorserver"; | ||
|
|
||
| [Theory(Skip = "https://github.com/dotnet/aspnetcore/issues/30761")] |
There was a problem hiding this comment.
Will undo - I wanted to verify if the title in the templates worked correctly
| } | ||
|
|
||
| <component type="typeof(App)" render-mode="ServerPrerendered" /> | ||
| <!DOCTYPE html> |
There was a problem hiding this comment.
Merged _Host.cshtml and _Layout.cshtml together like pre-6.0 days.
|
|
||
| if (!renderTask.IsCompleted) | ||
| { | ||
| throw new InvalidOperationException("Components with deferred rendering must complete synchronously."); |
There was a problem hiding this comment.
I'll update this to use a resx.
|
This looks very promising to me. I'm definitely enthusiastic about getting rid of the weird host/layout page split and the nonobvious ordering dependency. I'm wondering though if it could be simplified further, eliminating the need for the How expensive is it to use IHtmlContent? Would it be viable for all component prerendering to go through this? Imagine if:
So if rendering Is there a fatal flaw in this? Is it cheap enough to buffer each prerendered component like this? |
|
Closing in favor of #40512 |
This allows the HeadOutlet component to appear earlier in the document, but for
rendering to be deferred until MVC starts emitting markup.
The way this is done is by introducing a new parameter to
ComponentTagHelper/RenderComponentAsyncwhich returns a IHtmlContent that defers rendering the component untilIHtmlContent.WriteTois called. In practice this looks like:This behavior takes advantage of MVC's buffered rendering mechanism. MVC builds a tree of IHtmlContent items and defers calling
WriteToon these until it's ready to go to the wire. In our case, the component tag helper renderingHeadOutletexecutes but puts a placeholder since it is deferred. The tag helper rendering App executes, and updates the SectionContent. Once MVC is ready to turn IHtmlContent to text, theHeadOutletcomponent renders and the title configured byAppis used.The only pre-req is that since rendering of
IHtmlContentis synchronous, we require deferred components to also finish rendering synchronously. This isn't an issue withHeadOutlet.Fixes #38400