Skip to content
This repository was archived by the owner on Feb 25, 2021. It is now read-only.

[WIP] Prerendering #238

Closed
wants to merge 8 commits into from
Closed

[WIP] Prerendering #238

wants to merge 8 commits into from

Conversation

LunicLynx
Copy link
Contributor

@LunicLynx LunicLynx commented Mar 11, 2018

[WIP] Prerendering (#24)

How does it work

When ever a request comes in that would result in returning the content of index.html, the prerendering kicks in and replaces the app tag with the prerendered content.

In detail

  1. Call app.UseBlazorPrerendering<TEntryComponent>("app", configure => {}); in the server project. TEntryComponent will be the component to get prerendered and inserted into the app tag.
  2. UseBlazorPrerendering attaches the BlazorPrerenderingMiddleware to the ISpaBuilder, to intercept requests to index.html.
  3. If a request is satisfied by index.html. The index.html is parsed with AngleSharp, and modified to contain the prerendered content. This implementation is almost 100% the same as the one in IndexHtmlFileProvider.
  4. To Prerender the content there is a new implementation of Renderer. This implementation for the most part is identical to the one in BrowserRenderer.ts. But it only supports the initial creation, since update on the serverside does not make sense. Also when encountering a Component it goes into recursion, which is different from the Browser version.

What is in this PR

Microsoft.AspNetCore.Blazor.Server.Rendering project

Contains all things related to prerendering

  • PreRenderer implementation of Renderer (needs cleanup)

PrerenderingApp sample

  • input component
  • list component (foreach)
  • input element
  • 2 bound input elements
  • FetchDataComponent using a service making a HttpRequest on the client while using the data directly when prerendering.

Current Limitations

  • After the page is returned to the browser, it is static until the browser catches up with bootstrapping and rerendering the page. It would be nice to actually have some kind of way to map the elements to components. Maybe a custom data tag containing the component id.
  • Services used for controllers and prerendering must be specified two times for DI.
  • Routing not yet tested. It probably doesn't work.
  • IUriHelper implementation PreUriHelper of method GetBaseUriPrefix harcoded to match server url.
  • Missing Tests If this is the way to go, i will write them.
  • It only works with the app tag. There should be some way to define the entry component. Also it would be nice to have different services (which also means different references) on server vs client side.
    As of now i can only imaging 3 projects.
    • One containing the Components
    • One for bootstrapping in Browser
    • One for bootstrapping in Server
  • No way to supply services to prerendering. It would be nice to be able to supply different services while prerendering. This would allow to reuse server services to prerender the content without issuing http calls on the server side.

What now?

I know the issue #24 is not yet assigned to any version. And maybe this implementation is going completely haywire. I just did what i thought might be the general idea. Either way, this was major fun.
Let me know what you think!

@SteveSandersonMS
Copy link
Member

This is interesting, @LunicLynx! Thanks for submitting it.

To be honest, this is a bit too early for the project at the moment. Although Blazor is certainly designed to allow for SSR to be added in the future, and your implementation does indeed follow many of the patterns I'd expect for this, the whole area of SSR introduces a realm of complexity that we'll only be ready for some time later.

There are various other concepts we need to think through the design for, such as how to know about skipping components that don't support SSR (e.g., because they rely on JS interop), how to render asynchronously on the server so we can wait for outstanding init tasks to complete, and probably a bunch more.

So although this is really cool, would it be OK if we come back to it a while later?

Again, I really appreciate the contribution!

@LunicLynx
Copy link
Contributor Author

I figured as much. 🙈

Sure, just let me know when things are getting clearer, would love to help out.

@LunicLynx LunicLynx closed this Mar 13, 2018
@LunicLynx LunicLynx mentioned this pull request May 7, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants