Closed Bug 988562 Opened 10 years ago Closed 9 years ago

Consider using data URIs for icons on homepage/category landing pages

Categories

(Marketplace Graveyard :: Consumer Pages, defect, P3)

defect

Tracking

(Not tracked)

RESOLVED WONTFIX

People

(Reporter: cvan, Unassigned)

References

()

Details

(Keywords: perf)

I proxied the featured homepage API response (which also contains the popular apps) for the Marketplace, saved it to disk, and created two test cases: one with all image URLs and one with all data URIs.

(I started doing it for screenshots too, but I thought I'd start small since the homepage is really what we care about the most right now - and screenshots are hidden by default in search and rendered most of the time only when a user loads an app detail page.)

Caveat #1: These times do not take into account the awesome and significant perf gain we get from Kevin's clever image lazy-loading.
Caveat #2: In both test cases, I removed all 16px-, 32px-, and 128px-sized icons since Fireplace uses only 64px-sized icons. We can discuss whether we want to make this change later, but yeah.
Caveat #3: In the screenshots he 34 fewer requests we make when we use data URIs is significant, but don't let the 162 vs. 128 requests fool you. This is running locally when we don't concatenate and minify our asset bundles. (So in production, that would be 59 vs. 25 requests)

So here are my assessments when viewing the Marketplace at a mobile width on an EDGE connection (64k) using the program "Speed Limit" for Mac OS X:

1) URLs: 42 seconds for every asset on the homepage to be loaded and rendered:
http://cl.ly/image/2j3333452U0K

2) Data URIs: 5 seconds for every asset on the homepage to be loaded and rendered:
http://cl.ly/image/470Z3k3K0O0r

When gzip'd, the difference in filesize is surprisingly negligible (18122 bytes w/ data URI vs. 18119 bytes w/ URLs).

On a super-fast connection it's still quicker to load the data URIs than it is to fetch the images from the network and render the binary images:

1) URLs: 5.1 seconds for every asset on the homepage to be loaded and rendered:
http://cl.ly/image/0w003U01000B

2) Data URIs: 3.8 seconds for every asset on the homepage to be loaded and rendered:
http://cl.ly/image/293B3F3i0L2A

We're dealing with high-latency connections on mobile, and maybe SPDY will help this tremendously - I don't know. But the benefit of using data URIs (fewer HTTP requests) seems obvious. But I've found some literature on the Web that seems to contradict my findings, for example: http://www.mobify.com/blog/data-uris-are-slow-on-mobile/

Once a new icon is cached in the browser, we're good (for 10 years). But for new icons (or changed icons), we'll always incur network requests. Considering that we're probably not getting SPDY support any time soon, this could be a nice perf gain.
I was playing with metering my network speed to EDGE (64K).

Even with `Cache-Control`/`Expires` headers (like the ones we're setting for 10 years on CDN assets), all resources need to  and won't load offline.

And until Service Workers arrive in Firefox (there's a polyfill but it's for Chrome Canary only), appcache is our only solution. Appcache has a huge limitation where any change to the manifest causes an invalidation of all the resource listed. I was thinking of a hacky workaround where we could iframe pages that can conditionally add resources to our appcache (assuming they're on the same origin and not on the CDN):


# /index.html

<html>
  ...
</html>


# /media/js/include.js

function addToAppcache(resourceURL) {
  var iframe = document.createElement('iframe');
  iframe.src = '/manifest.appcache?resource_url=' + resourceURL;
  iframe.style.display = 'none';
  document.body.appendChild(iframe);
}

or

function addToAppcache(resourceURL) {
  new Image().src = '/manifest.appcache?resource_url=' + resourceURL;
}


# /manifest.appcache?resource_url=/resource.css

CACHE MANIFEST


# hash-of-resources-content-goes-here

/resource.css


We should not necessarily do this because (a) the CDN is on another origin and we shouldn't get in the business of serving images from our origin, (b) we could instead just add these to our packaged app (which isn't a great idea because of updates), and (c) the cached content is not actually downloaded (0 bytes); it just requires an Internet connection to check with the server and return the 304 NOT MODIFIED.

To summarise: on EDGE connections, even if they're in the browser cache, the icons will always take a while to render. If we use a data URI, we can show the icons regardless of a network connection and the network speed.
No longer blocks: tarako-marketplace
Blocks: 992365
Priority: -- → P3
Let's discuss this more before we go down this road.  I think it may be a short-term win but a long-term loss (which is what the papers on this method talk about).
No longer blocks: 992365
We're going to experiment with HTTP2 instead. We can revisit this if we need to.
Status: NEW → RESOLVED
Closed: 9 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.