Search code examples
javascriptperformanceiconsfaviconapple-touch-icon

Loading web page icons asynchronously - a cross-browser solution?


In today's fractured web-icon landscape where (surprisingly) .svg icons have not yet achieved broad support, one might be tempted to add a huge list of elements in the head pointing to any number of

  • favicons
  • icons
  • apple-touch-icons
  • safari-pinned-tabs
  • mstiles

etc.

A comprehensive list of favicons, icons, touch-icons, tiles etc. on any page would be enormous.

This affects page initialisation and loading time, in some cases quite dramatically.

The goldilocks solution would be to be able to add as many icon <link> references as needed, without affecting page load performance.

So... is it a legitimate approach to load these elements asynchronously?

eg.

const favIcon = {'rel' : 'icon', 'href' : 'favicon.ico'};
const appleTouchIcon = {'rel' : 'apple-touch-icon', 'href' : 'apple-touch-icon.png'};

const myIcons = [favIcon, appleTouchIcon];

for (let i = 0; i < myIcons.length; i++) {

  let myIcon = document.createElement('link');
  myIcon.rel = myIcons[i].rel;
  myIcon.href = myIcons[i].href;
  document.head.appendChild(myIcon);
}

Or will loading these <link> elements asynchronously on DOMContentLoaded mean that various user-agents miss the icons they are looking for?


Solution

  • Theoretically, favicons should not impact performance nor loading speed, at least not like you are thinking. If setup correctly, most browsers will only look for the needed/supported icons, and it will be in fact an asynchronous non blocking operation.

    Additionally, favicons caching strategies are by default very conservative (they are almost always cached). If sometime you see more than one request for different formats/sizes it is because a browser could use different images (for the tabs, bookmarks, desktop shortcuts, etc).

    My advice would be to leave it all to the browser and focus on other more critical performance considerations.

    Keep in mind that if you’re testing locally using https, most browsers will disable cache.

    Finally, I don’t know how are you preparing your favicons but there are plenty of tools online that will optimize the images for you and write the correct metadata. (I remember faviconit.com, but I’m sure there was a better one, it works great though).

    • Final Note:

    If despite of everything, you still decide to take control of the situation by yourself, you’ll encounter some issues:

    1. Static analysis tools aka. crawlers/bots will most likely not see your favicons because 99% of the time they will not run javascript.

    2. Inserting each link in a sequence as you suggested may result in the browser failing/struggling to decide which asset to get (browser should wait until the end of the function, but there is not a rule for that)