Problem/Motivation
Currently we only cache the prefetched pages into the server which means that when the user clicks on a link the content still has to be downloaded from the server.
However it makes sense pushing the prefetched content to the browser and not downloading the content on click, but simply exchanging it.
Proposed resolution
HTML5 supports exchanging the browser url through JS without reloading the page with the "onpopstate" event, so we could make use of this feature and on click exchange the url and the put the prefetched content on the page. More on this - here.
Probably we should offer this feature per setting and not making it the default behavior.
Remaining tasks
User interface changes
API changes
Data model changes
Comments
Comment #2
hchonovComment #3
geaseAttaching a patch that is a proof of concept. It splits link classes into two: 'prefetch-link' for warming up server cache (as in master branch) and 'prefetch-cache' for downloading a page into an iframe.
As far as I've tested, it works, but some js still behaves differently (eg, borders calculation).
To me #3001236: Option to prefetch only assets seems the same issue.
Comment #4
geaseComment #5
hchonovI think that since #2537602: JQuery ajax GET requests result in "406 Not Acceptable" this should not be the case.
I think, that this happens because the current assets are still active and they should be disabled. I've found something about that -
https://quantumwarp.com/kb/articles/59-javascript/664-removing-or-replac...
Comment #6
hchonovThe difference is that with the current issue the user will not perceive any lag on clicking on a prefetched link. The referenced issue takes care of only caching the assets of the target resource in the browser, but not the target resource itself. I hope this clarifies the difference.
Comment #7
hchonovComment #8
geaseInstead of iframe, loading with jquery data(). This way behaviors are not attached when the page is prefetched and pulling from data is faster.
It looks better and some errors are gone, but still behaviours for admin toolbar and ckeditor do not work.
Comment #9
geaseInserting innerHTML, in contrast to normal page load, does not run scripts. And, eg, ckeditor loads stylesheets with a callback from js. An approach could be to use document.head.append and document.body.append (tutorial page), but so far I'm getting weird results.
Running attachBehaviors immediately after changing document contents results in errors, because document is not fully styled. But there is no event in js like "styling applied" Small timeout fixes the issue, but we cannot guess its value, because it should be much system dependent.
We can switch back to iframes, but it has its own quirks, The correct way, imho, would be to find a way to simulate normal page load with all the events firing, if it is at all possible.
Comment #10
kfritscheJust a quick review of the patch.
settings is not used, as far as I see, not needed to be added here anymore.
I'm missing something from the backend here or is prefetch-cache class never set anywhere?
You removed the iframe stuff, comment is outdated I think.
I also think this check can be removed, or I'm wrong? But I do not see the point not doing it in an iframe, as you changed it to not use an iframe.
href is not defined in this scope
Also as of #2847689: Introduce weights for prefetch cache links to define which links will be prefetched first this patch needs a re-roll.
Regarding the other issues, maybe try to do a
$(document.body).trigger('load');after setting the content.
Alternativly you could use jQuerys load (https://api.jquery.com/load/), maybe it already triggers everything.
Comment #11
geaseThanks for review @kfritsche, this is an intermediary patch, I have already changed a lot locally, but my main problem is how how to simulate page load.
$(document.body).trigger('load');will trigger load event, but it won't evaluate scripts on the page. And the thing is when I try to use append basically node by node from header and body, the resulting html source looks the same as under normal page load, but is rendered quite differently. Obviously, I'm missing something about page load process.