igrigorik / resource-hints

Moved to...
https://github.com/w3c/resource-hints
32 stars 7 forks source link

Support prerendering of template driven pages #20

Closed sicking closed 10 years ago

sicking commented 10 years ago

Right now pointing a to the URL of a HTML page enables a significant improvement of navigation to that HTML page. Not only does it enable all resource to be downloaded, it also enables applying doing styling and layout of the DOM, it also enables running any JS that is needed for the page to start.

This means that navigating to the prerendered page can be incredibly fast.

However in order to take full advantage of all of this preprocessing, the user has to navigate to a URL that matches the URL of the prerendered page exactly.

For websites that are essentially a template driven frontend to some database, for example a webstore with product pages, a news website with articles, or a bugdatabase like github, we can do better.

Consider for example https://bugzilla.mozilla.org/buglist.cgi?quicksearch=prerender

As prerendering is currently defined, the above page would have to choose between:

It would be really great if we exposed enough primitives that we could enable the website to the full prerendering of a "template page". Then enable the page to intercept any navigations to any of the pages in the bug list and direct it to the prerendered template page. The template page could then take care of loading the appropriate data and render the data using the DOM.

Note that this is significantly easier than making the whole website a single-page app. You don't have to handle transitioning between different pages that have different "base templates", I.e. you don't have to handle transitioning between the bug listing page and the page rendering individual bugs. Also, you don't have to handle transitioning away from a fully loaded page, you just have to handle turning an "empty" page into a useable page.

Another point is that service workers will likely encourage developers to write pages in a similar way. This enables caching the "template page" in the SW cache, and then load data from a database of from the network. You are unlikely to use a SW to cache the separate bug pages since this would be very inefficient.

There are several ways we could expose enough primitives to allow websites to accomplish this.

One solution is to simply add a attribute. This could direct any navigations to URLs starting with the defined prefix to the prerendered page. The UA would then mutate the document.location of the prerendered page to match the URL that the user actually navigated to. The prerendered page could then listen to the visibilitychanged event, inspect its URL and then load the appropriate data.

The downside with this solution is that it's a bit "all-in-one".

Another solution would be to enable the page with the to have a postMessage-based communication channel with the prerendered page. When the user clicks a link, the page could then intercept the click, postMessage information about which link the user clicked to the prerendered page, the prerendered page could then use replaceState to mutate its own URL. Then the initial page could initiate the navigation, at which point the UA would find that the URL the user is about to navigate to matches the URL of the prerendered page, and so simply displays the prerendered page.

Such a communication channel could be useful for other things too. For example the initial page could take a guess at which 5 top bugs the user is likely to click and send information about those bugs to the prerendered page. The prerendered page could the start loading data for those 5 bugs. If the user happens to click on one of those links, the data will already have been loaded. If the user clicks something else the prerendered page can start loading the right data then.

The downside with this approach though is that it requires a postMessage roundtrip and then manually triggering the navigation. This is extra complexity (what if the user clicks another link in the meantime?) as well as potentially affects performance.

So possibly some combination of both these approaches are needed.

I'm fine with not adding this to the spec yet. We'll likely do some experimenting in this space at mozilla in order to get really high performance navigation for situations when all data is already available locally. Hopefully the outcome of that will provide useful data which can help with speccing this.