Summarized: the use of data URIs can delay the loading of HTML if the images are large
I created a script that replaced inline images with data URIs to decrease http requests and speed up loading times on mobile devices.
It's a viable option if the time taken to make requests is longer than downloading the images, as the browser will need to download the image data regardless (whether through a data URI or not). Embedding images as data URIs in the HTML will increase the overall size of the HTML by the combined size of all images (plus approximately 33% for data URI encoding).
For example, if establishing a new connection takes 1s, downloading each image takes 0.2s, there are 10 images, and the HTML download time is 0.5s, the calculations would be:
- 1s + 0.5s = 1.5s for HTML alone
- 10 x (1 + 0.2)s = 12s for images
If the images are encoded as data URIs:
- 1s + 0.5s + (10 x 0.2s x 1.33) = 4.2s
- (without external requests for images)
The total time taken to fetch the entire HTML source is crucial (1.5s vs 3.5s). If instant image display is vital, data URIs are beneficial. However, if loading most of the page first and then images asynchronously is acceptable, prioritizing complete HTML download may be more effective.
Additionally, encoding large images as data URIs can worsen performance. If each image takes 1 second to download:
For external images:
- 1s + 0.5s = 1.5s for HTML alone
- 10 x (1s + 1s) = 20s for images
Using data URIs:
- 1s + 0.5s + (10 x 1s x 1.33) = 14.8s until HTML completion!
Could the larger html file size (around 100kb instead of 5 kb) impact this decision?
As the browser downloads the HTML, it begins interpreting and displaying it. External resources such as images with regular URIs and (async) scripts are fetched while continuing to process the HTML.
The user sees more content gradually as the page loads, even before images or fonts are fully loaded.
However, when encountering a data URI image tag, the browser must download and parse the entire data URI string, creating a pause as it processes the large encoded image before proceeding with the HTML.
Does the browser need to finish downloading the entire document before loading linked resources within it?
Linked resources have independent loading and parsing behavior. <script>
tags are loaded synchronously, blocking HTML parsing until execution, unless marked as async
. External stylesheets load in parallel but delay rendering until complete.
This link provides further insight.
Is it better to separate CSS with data URIs into a distinct file?
- Load CSS for structure (without data URIs)
- Load CSS for background images (all in URI format)
Is a "separate cached jpg file" quicker than a "URI based image within a cached CSS file"?
Any other suggestions for utilizing data URIs effectively?
The choice depends on your optimization goals. Prioritize initial rendering speed, even if the page is incomplete, or aim for full page rendering with all images included?
There's no one-size-fits-all rule for using data URIs. Consider applying them for small images like icons. Webpack's url-loader
automates this process, utilizing data URIs for smaller files and external URLs for larger ones.