3

The following onload event doesn't fire in IE11 and Microsoft Edge 40:

<link href="https://fonts.googleapis.com/css?family=Montserrat:300" rel="preload" as="style" onload="this.rel = 'stylesheet';">

The onload does fire if you give the <link> element a valid rel="stylesheet":

<link href="https://fonts.googleapis.com/css?family=Montserrat:300" rel="stylesheet" onload="alert('this works')">

What is a working fallback solution for rel="preload" on Internet Explorer/Edge?

Paesano2000
  • 313
  • 2
  • 16
  • FWIW - preload is in development for Edge and will be released some time in the future https://developer.microsoft.com/en-us/microsoft-edge/platform/status/preload/?q=prel - it'll never come to IE, though, as IE is dead, development-wise. – TylerH Mar 06 '18 at 17:13
  • @TylerH yeah that is good news, but there has to be some kind of fallback solution to bridge the gap :( – Paesano2000 Mar 06 '18 at 18:00
  • well there was no feature for this prior to the preload attribute, so the fallback is... wait for the files. Alternatively you can use an entirely different architecture, like an ASP.NET page or something, and serve all the files you will need for various pages on a landing page that is always redirected to or something. Another alternative is to pare down your site's landing page so that stuff doesn't need to preload; slimmer sites load faster. – TylerH Mar 06 '18 at 19:48
  • @TylerH it isn't an option to just not use preload, my aim is to create the best performance while maintaining compatibility. What I would need is a polyfill for rel=preload. – Paesano2000 Mar 06 '18 at 20:28

2 Answers2

3

You can also just add another link tag underneath that will become a fallback for browsers that do not support it:

<head>
  <link rel="preload" href="style.css" as="style">
  <link rel="stylesheet" href="style.css">
</head>

Note that you wont need onload="this.rel='stylesheet'" any more since the next line uses that file as stylesheet. There will be only one network request for the specified file.

Source: Preload CSS file not supported on Firefox and Safari Mac

blah
  • 783
  • 7
  • 7
  • Is there any chance of a performance issues with two css files being parsed by the browser in browsers that support preload? – Paesano2000 Aug 10 '20 at 14:14
  • @Paesano2000 according to some people who tested this in Chrome in only loaded 1 file, see comments in https://stackoverflow.com/a/53826674/1913702 I would keep in mind that the comment confirming this was made in 2019 so things might have changed. I personally have not tested this. – blah Aug 11 '20 at 16:36
2

After some digging I found a solution that can feature detect for rel="preload" from Yoav Weiss's article:

var DOMTokenListSupports = function(tokenList, token) {
  if (!tokenList || !tokenList.supports) {
    return;
  }
  try {
    return tokenList.supports(token);
  } catch (e) {
    if (e instanceof TypeError) {
      console.log("The DOMTokenList doesn't have a supported tokens list");
    } else {
      console.error("That shouldn't have happened");
    }
  }
};

var linkSupportsPreload = DOMTokenListSupports(document.createElement("link").relList, "preload");
if (!linkSupportsPreload) {
  // Dynamically load the things that relied on preload.
}

The onload="this.rel='stylesheet'", if it had worked in IE/Edge, would have been a good fallback. Scott Jehl's loadCSS library has its own polyfill for rel=preload.

So I'm utilizing part of that solution to update the rel=preload to rel=stylesheet.

My final solution:

// `rel=preload` Polyfill for <link> elements
var DOMTokenListSupports = function (tokenList, token) {
    if (!tokenList || !tokenList.supports) {
        return;
    }
    try {
        return tokenList.supports(token);
    }
    catch (e) {
        if (e instanceof TypeError) {
            console.log("The DOMTokenList doesn't have a supported tokens list");
        }
        else {
            console.error("That shouldn't have happened");
        }
    }
};
var linkSupportsPreload = DOMTokenListSupports(document.createElement('link').relList, 'preload');
if (!linkSupportsPreload) {
    // Dynamically load the things that relied on preload.
    var links = document.getElementsByTagName('link');
    for (var i = 0; i < links.length; i++) {
        var link = links[i];
        // qualify links to those with rel=preload and as=style attrs
        if (link.rel === 'preload' && link.getAttribute('as') === 'style') {
            // prevent re-running on link
            link.setAttribute('rel', 'stylesheet');
        }
    }
}
Paesano2000
  • 313
  • 2
  • 16
  • works beautifully but for reason IE11 wouldn't stop trying to reload the css files as though it were a vicious cycle... i added `link.setAttribute('onload', '');` right above `link.setAttribute('rel', 'stylesheet');` and that seems to do it, excellent solution! – petrosmm Mar 06 '20 at 18:44