New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce AoT predictive prefetching #94
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing it on gatsby right now. I added a few bikeshed comments.
type ConnectionEffectiveType = '4g' | '3g' | '2g' | 'slow-2g'; | ||
|
||
const support = (feature: string) => { | ||
if (typeof document === 'undefined') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is copied from https://github.com/GoogleChromeLabs/quicklink/blob/master/src/prefetch.mjs
Unsure if it really matters but it's a few bytes smaller. We can also drop the document check as we do it inside supportedPrefetchStrategy
const support = (feature: string) => {
const link = document.createElement('link');
return link.relList && link.relList.supports && link.relList.supports(feature);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The suggestion sounds good!
I believe the code here is the original source @addyosmani shared before I/O last year.
}; | ||
|
||
const linkPrefetchStrategy = (url: string) => { | ||
if (typeof document === 'undefined') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can drop it this as we do it in the supportedPrefetchStrategy
parentElement.appendChild(link); | ||
}; | ||
|
||
const supportedPrefetchStrategy = support('prefetch') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const supportedPrefetchStrategy = support('prefetch') | |
const supportedPrefetchStrategy = typeof document !== 'undefined' && support('prefetch') |
@@ -114,9 +115,9 @@ const getEffectiveType = (global: any): ConnectionEffectiveType => { | |||
|
|||
export const initialize = ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would it be better to move to an object as parameters so ordering doesn't matter?
} | ||
}); | ||
}; | ||
|
||
const support = (feature: string) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we copy the same changes from the aot runtime here or move the support function into a util file.
Co-Authored-By: Ward Peeters <ward@coding-tech.com>
…o/guess-aot * 'minko/guess-aot' of github.com:guess-js/guess: Update packages/guess-webpack/src/aot/guess-aot.ts
@mgechev do you happen have a small but fully functioning AoT example I can use as PoC to get buy-in from others on my team? I'm assuming there is a training step (data from Google Analytics maybe?) and during build time the prefetches are determined based on the trained model. I assume the model can be trained continually? In other words, as user behavior changes/evolves and we have a larger dataset, we can retrain it or resume its training and get the updated prefetch predictions. Or maybe I have a purely imaginary sense of how this works? |
Currently, Guess.js uses a simple probability matrix (Markov chain). Everything is static. When users' behavior change, you must rebuilt your application. Here's an example. Find |
This pull request introduces Ahead-of-Time predictive prefetching.
AoT vs. JiT prefetching
The difference is between the time when the prediction instruction is generated. Currently, Guess.js uses JiT predictive prefetching. Based on the current page the user is at, Guess.js queries the model and generate prefetching instructions for the JavaScript bundles associated with the pages that are likely to be visited next.
With AoT predictive prefetching, we query the model at build time. This has several benefits.
Advantages of the AoT model
Instead of shipping the entire model to the browser, now we just need to provide a
prefetch
function, which takes as arguments a chunk (filename) and a probability for this chunk to be needed. The function prefetches the bundle if its chance to be needed is sufficient given the user's connection speed.The prefetch function is part of the main application bundle. Each lazy-loaded chunk has a few instructions which trigger the prefetching mechanism for its neighbors.
Example
In the example above, when the user visits
/a
, they'll downloadmain.js
together witha.js
.a.js
will trigger prefetching forb.js
andc.js
. If the user's connection speed is sufficient,__GUESS__.p
will prefetch the chunks; otherwise, it'll ignore the instructions.