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

[WIP] Prerendering #785

Closed
wants to merge 11 commits into from
Closed

[WIP] Prerendering #785

wants to merge 11 commits into from

Conversation

LunicLynx
Copy link
Contributor

@LunicLynx LunicLynx commented May 7, 2018

Just for the sake of it, its still working and relevant. (Original #238)

  • Rebased on latest dev branch

[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

Thanks for the proposed implementation, @LunicLynx!

It's very cool that you've been able to implement this. However it's still going to be some time before we are ready to include a feature like this in the core packages. It will introduce a lot of new concerns to people's apps (e.g., how to deal with JS interop that occurs during SSR) and we haven't yet got all the necessary designs in place.

If you want to make this usable for people in the short term, what would it take for you to be able to publish it independently as an add-on package? I see you were using [InternalsVisibleTo] on the AngleSharp package. Is that the only internal API you needed access to?

I'll close this for now because it's not something we'll be ready to take action on any time soon. But I am happy to work with you on helping you publish SSR as an independent package if you wish! Hope that's OK.

@LunicLynx
Copy link
Contributor Author

Sure its fine. Just wanted to keep this updated to dev.

I wlll have a look if it is possible to seperate this.

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