I am facing an issue where I have an img-tag with a data-image base64 URI as the source. Browsers tend to cache this source, which is causing problems for me. If it were a normal URL, I could easily prevent caching by adding a random query-parameter value.
How can I prevent the caching of this data-image base64 URI source?
Here's an example of an img tag with a data-image base64 URI:
<img src="data:image/svg+xml;base64,PD94bWw==">
And here's an example of an img tag with a normal URL source along with a query param to avoid caching:
<img src="https://foo?1234RandomString">
In my case, since the original image is SVG, I could use a data-image SVG URI and add a custom attribute to the SVG to prevent caching, which works. I could also deploy the SVG as a file and use a URL with a query param, but I find both solutions quite unsightly.
PS: Why do I need it? I have a long list of img-tags and I want to implement lazy loading to generate the actual source URL lazily in vue3.
Consider this code snippet. Initially, the src is set to the data-image URI. When the image is lazily loaded, the actual source is created and set.
Issue: Lazy loading fails in Chrome if the initialSrc is cached for the first image, preventing the mechanism from working for subsequent images.
<img :src="mySource" loading="lazy" @load="onLoad">
const initialSrc = "data:image/svg+xml;base64,PD94bWw=="
const imageSrc = ref()
const onLoad = async () => {
if (!imageSrc.value) {
imageSrc.value = await createRealSrc();
}
};
const mySource = computed(() => imageSrc.value ?? initialSrc)
There are some doubts in comments that data URIs are actually loaded via a request. edit: Trigger warning. More nuanced than it seems. Take a look further down and in the comments. They are:
Screenshot of network tab that shows a GET request to a data URI
Some more clarifications:
Let's say you have two img-tags in your document:
<img src="http://image.png" loading="lazy">
<img src="http://image.png" loading="lazy">
In this scenario, the first img-tag will be loaded lazily, while the second will be immediately loaded after the first one because its src can be fetched from cache.
<img src="http://image.png" loading="lazy">
<img src="http://image.png?abc" loading="lazy">
In this scenario, both images will be loaded lazily as the URLs are different and cannot be taken from cache.
<img src="data:image/svg+xml;base64,PD94bWw==" loading="lazy">
<img src="data:image/svg+xml;base64,PD94bWw==" loading="lazy">
Here, the first img-tag will be loaded lazily, but the second will not be loaded lazily as it will be promptly loaded once the first one is loaded due to cache retrieval.
<img src="data:image/svg+xml;base64,PD94bWw==" loading="lazy">
<img src="data:image/svg+xml;base64,sdfsdfs==" loading="lazy">
In this last scenario, both images will load lazily since the URIs are unique and cannot be retrieved from cache.
Why does the img-tag load immediately instead of lazily when the image can be fetched from cache? The behavior I observe in Chrome leads me to believe that it may be an implementation detail or part of the current Chrome specification. It makes sense though - why trigger a lazy load when the data is already available in cache. However, I still require lazy-loading for my purpose as I intend to utilize it for performing expensive operations lazily.
Does using a data URI as a source really result in a GET request being made? According to the Chrome network tab, yes. Is it considered a real HTTP transaction? That remains uncertain. Edit: To clarify, there is no backend involved, so there is no TCP communication happening. Thus, it might not strictly adhere to real HTTP standards. However, internally Chrome treats it like a GET-request, recording a request/response in accordance with HTTP protocols. Real HTTP or not? Likely not purely authentic.
Is the data URI stored in cache? As per the Chrome network tab, it appears to be cached. My understanding suggests that image data gets stored in cache regardless of whether it originates from a file or a data URI.
Is the source loaded along with the image (and not beforehand) even when using a data URI? In my experience, I would affirmatively say yes. While I suspect it's part of the HTML spec, I lack concrete evidence to support this claim.