Reputation: 18933
The JavaScript on my website loads several JSON to initialize itself.
I would like to preload them so, when the JavaScript will launch an Ajax request on it, they will be loaded instantaneously.
A new link
tag exists for that.
I tried to use it to load a JSON like that :
<link rel="preload" href="/test.json">
However, Chrome seems to load it twice and present a warning in the console :
The resources test.json was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it wasn't preloaded for nothing.
So it seems that preload doesn’t work for JSON. Indeed, I haven’t found reference to JSON in the specification.
Is that correct or am I doing it wrong ?
Upvotes: 20
Views: 17231
Reputation: 2329
Here is the approach that works both in Chrome and Safari.
<link rel="preload" as="fetch" href="/data.json">
fetch('/data.json', {
method: 'GET',
credentials: 'include',
mode: 'no-cors',
})
This answer contains more details and explanation why and how does it work https://stackoverflow.com/a/63814972/1387163
Upvotes: 2
Reputation: 25798
According to the Chrome bug mentioned in the comments, preload
doesn't work when you have responseType = 'blob'
.
The workaround is to set responseType = 'arraybuffer'
and then in onload
convert to blob manually using var blob = new Blob([xhr.response], {type: xhr.getResponseHeader("Content-Type")});
Upvotes: 0
Reputation: 2413
I tried so many variations on the allowed values on https://w3c.github.io/preload/#as-attribute but the only thing that worked for me to fetch JSON data properly was removing the type
and as
directives completely and relying on the browser to figure it out. Works in the latest Chrome but I guess it might change as browser behaviour changes.
Upvotes: 0
Reputation: 690
According to https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content , you have to add as="fetch"
for JSON files.
So your code becomes
<link rel="preload" href="/test.json" as="fetch">
It's supported by all modern browsers and you get a warning message if this resource is not used within a few seconds because it is counterproductive to "preload" it in a such case (delay, double load etc.)
It's different from <link rel="prefetch" ...>
which is to anticipate future navigation and not supported widely.
A Chrome illustrated article about this: https://medium.com/reloading/preload-prefetch-and-priorities-in-chrome-776165961bbf
Upvotes: 24
Reputation: 639
You have to add not only as="fetch", but (based on this comment) also crossorigin="anonymous". This should work:
<link rel="preload" href="/test.json" as="fetch" crossorigin="anonymous">
Upvotes: 9
Reputation: 1
Try as="object"
. Seems to work for me:
<link rel="preload" href="/test.json" as="object">
Upvotes: -5
Reputation: 13190
If you have the same problem as me, your response is probably being sent with Vary: Accept
, the preload request is sent with Accept: */*
, and the fetch/xhr request is being made with Accept: application/json
.
It seems like the preload Accept:
behavior can't be changed (sigh), so you'll have to either remove the Vary: Accept
, or make the fetch/xhr request with a matching Accept:
header.
Upvotes: 11
Reputation: 1232
Turns out there has been a bug in Chrome for using the fetch
API combined with rel=preload
here. I solved this by using XMLHttpRequest
instead.
Even though it seems to have been fixed in Chrome 62 it seems like I could still reproduce this on my Chrome 63.
Upvotes: 3
Reputation: 25157
Try as="xhr"
. Seems to be working for me in Chrome when I do a server push - that's not exactly the same as the HTML tag but if you are getting that resources via Ajax / XmlHttpRequest, this might fix it.
Upvotes: -3