You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, it is possible for standard browser navigations and JavaScript based fetch/XHR calls to hit the same HTTP cache. This may not be true as caches are partitioned further in the future. However, there are advantages to allowing these network requests to hit the same cache, in particular for same-origin applications.
Implementation wise, this can be utilized if the website sends responses in a "polyglot response" format that is both well-formed HTML, and parseable by JavaScript to extract HTML chunks, or extract structured data to utilize with client-side rendering.
Proposal
Formalize circumstances under which the HTTP cache is shared with fetch/XHR for same-origin requests, even as further partitioning occurs. This may be automatic by convention, or may require specific parameters opting in to the behavior for fetch/XHR to utilize the HTTP cache instead of a separate cache. For example, using { mode: 'same-origin' } for fetches.
Use Cases
Use Case 1 - Browser navigation to client-side navigation
Consider a hybrid app that prerenders the initial page and sends complete HTML to the client, then loads subsequent pages using JavaScript, fetch/XHR, and the History API. Each page contains dynamic content, e.g. the results of a search query.
First, the client initiates a client-side navigation to a new page which destroys the initial page content. Next, the user hits the back button to return to the initial page. A new network request must be initiated from JavaScript to fetch the dynamic content from the server.
If the fetch/XHR request can call the initial URL, hit the HTTP cache, and extract the needed dynamic content, it can avoid this network request, server computation, and added latency. This is similar to a fully SSR experience - a back button in this scenario would hit the HTTP cache from disk without an additional network request.
While there are other solutions to this like storing the initial page content in memory or other storage like SessionStorage, these have their own downsides, and also do not help with the reverse situation:
Use Case 2 - Client-side navigation to browser navigation
Consider the same hybrid app. Now, the user navigates client-side one or more times, then clicks a link to an external site. The user then hits the back button to return to the hybrid app, and BFCache misses. In a fully SSR app, the back navigation would again instantly restore the page from disk cache without a network request. In the hybrid case, we will experience a cache miss since the URL was originally fetched via JavaScript, and is now fetched via a browser navigation.
However, if we are using the polyglot response approach and fetched/XHRed the same URL that was pushed to the history stack, it will already be in the HTTP cache and the back navigation will be performed instantaneously without an additional network request.
Even utilizing custom caching in-memory or with other storage, this case can't be solved for browser-based navigations without an additional network request.
Examples
Below are example flows performed in desktop Chrome showing how this works today.
Browser navigation to client-side navigation
In the console, execute await fetch('https://www.google.com/search?q=test+query+1', {mode: 'same-origin', cache: 'only-if-cached'}).
FWIW, I think you can accomplish what you want with service workers. It gives you the control to handle navigation and subresource caching based on your own policy.
Overview
Currently, it is possible for standard browser navigations and JavaScript based fetch/XHR calls to hit the same HTTP cache. This may not be true as caches are partitioned further in the future. However, there are advantages to allowing these network requests to hit the same cache, in particular for same-origin applications.
Implementation wise, this can be utilized if the website sends responses in a "polyglot response" format that is both well-formed HTML, and parseable by JavaScript to extract HTML chunks, or extract structured data to utilize with client-side rendering.
Proposal
Formalize circumstances under which the HTTP cache is shared with fetch/XHR for same-origin requests, even as further partitioning occurs. This may be automatic by convention, or may require specific parameters opting in to the behavior for fetch/XHR to utilize the HTTP cache instead of a separate cache. For example, using
{ mode: 'same-origin' }
for fetches.Use Cases
Use Case 1 - Browser navigation to client-side navigation
Consider a hybrid app that prerenders the initial page and sends complete HTML to the client, then loads subsequent pages using JavaScript, fetch/XHR, and the History API. Each page contains dynamic content, e.g. the results of a search query.
First, the client initiates a client-side navigation to a new page which destroys the initial page content. Next, the user hits the back button to return to the initial page. A new network request must be initiated from JavaScript to fetch the dynamic content from the server.
If the fetch/XHR request can call the initial URL, hit the HTTP cache, and extract the needed dynamic content, it can avoid this network request, server computation, and added latency. This is similar to a fully SSR experience - a back button in this scenario would hit the HTTP cache from disk without an additional network request.
While there are other solutions to this like storing the initial page content in memory or other storage like SessionStorage, these have their own downsides, and also do not help with the reverse situation:
Use Case 2 - Client-side navigation to browser navigation
Consider the same hybrid app. Now, the user navigates client-side one or more times, then clicks a link to an external site. The user then hits the back button to return to the hybrid app, and BFCache misses. In a fully SSR app, the back navigation would again instantly restore the page from disk cache without a network request. In the hybrid case, we will experience a cache miss since the URL was originally fetched via JavaScript, and is now fetched via a browser navigation.
However, if we are using the polyglot response approach and fetched/XHRed the same URL that was pushed to the history stack, it will already be in the HTTP cache and the back navigation will be performed instantaneously without an additional network request.
Even utilizing custom caching in-memory or with other storage, this case can't be solved for browser-based navigations without an additional network request.
Examples
Below are example flows performed in desktop Chrome showing how this works today.
Browser navigation to client-side navigation
await fetch('https://www.google.com/search?q=test+query+1', {mode: 'same-origin', cache: 'only-if-cached'})
.document
and has a size, meaning it downloaded from the server.await fetch('https://www.google.com/search?q=test+query+1', {mode: 'same-origin', cache: 'only-if-cached'})
.fetch
loaded from(disk cache)
.Client-side navigation to browser navigation
(disk cache)
.(disk cache)
.Empty Cache and Hard Reload
.Empty Cache and Hard Reload again
.await fetch('https://www.google.com/search?q=test+query+2')
.The text was updated successfully, but these errors were encountered: