Using the ASP.NET Core Script TagHelper to Polyfill The Latest JavaScript Features

tl;dr

The primary use case for fallbacks in the Script Tag Helper is checking if a CDN is down and loading a local script instead.  Another use case is you can use fallbacks to make it easy to polyfill missing JavaScript features in older browsers, while not having your users using the latest browsers take a network hit.


<script asp-fallback-test="window.Promise"
asp-fallback-src="https://unpkg.com/promise-polyfill@6.0.2"&gt;
</script>
<script asp-fallback-test="window.fetch"
asp-fallback-src="https://unpkg.com/whatwg-fetch@2.0.2"&gt;
</script>


View this gist on GitHub

Background – What is a Polyfill?

A polyfill is a fallback, written in JavaScript, that fills in a new JavaScript feature that is missing in an older browser and replicates the same functionality that newer browsers provide natively.  This allows JavaScript code using the latest features only available in newer browsers to work on older browsers as well.

To polyfill the API, you simply just check if that API is available, and if not, load the polyfill that adds that API to your browser.  That way, if your user is using the latest browser, you don’t punish them by downloading something they don’t need and hurting their performance.

How a Polyfill works

This JavaScript code will polyfill the “new” fetch API for making AJAX calls, that is currently available in all of the latest major browsers (Chrome, Edge, Firefox, Safari, etc.), but not in any of the Internet Explorer family tree (not even IE11).


window.Promise || document.write('<script src="https://unpkg.com/promise-polyfill@6.0.2"></script>&#39;)
window.fetch || document.write('<script src="https://unpkg.com/whatwg-fetch@2.0.2"></script>&#39;)

First, the code looks to see if the Promise API is available, because fetch relies on Promises in order to work.  If the API is not available, it loads a script from a CDN that polyfills the Promise API.  It does the same thing for the fetch API.

The built-in Script Tag Helper – CDN fallback

The built-in Script Tag Helper in ASP.NET Core has fallback support baked in that generates code very close to this.  The original intent of their fallback support was for attempting to load a script from a CDN.  After loading from that CDN, test to see if a JavaScript API is available, and if it’s not (due to the CDN being down, blocked, or whatever) fall back to loading a local JavaScript file.  That code looks like this:


<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.2.min.js&quot;
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
asp-fallback-test="window.jQuery">
</script>

The fallback works for polyfills too!

What I haven’t seen anyone mention is to use this to conditionally polyfill if a JavaScript feature doesn’t exist.  And it works right out of the box, simply omit the src attribute, and the rest will be taken care of:


<script asp-fallback-test="window.Promise"
asp-fallback-src="https://unpkg.com/promise-polyfill@6.0.2"&gt;
</script>
<script asp-fallback-test="window.fetch"
asp-fallback-src="https://unpkg.com/whatwg-fetch@2.0.2"&gt;
</script>

The code above will generate nearly identical code to what’s in the first code sample.  As mentioned above, fetch needs Promises to work, so I’m also polyfilling that conditionally as well.  In the real world, I would likely bundle these two together (locally or using something like Polyfill.io) and make one network request, but using unpkg (an NPM CDN) was just for simplicity’s sake.

With the code above, I get the best of both worlds.  My code using fetch runs on older browsers, but my users who use the latest browsers don’t take a network hit for something they don’t need.  This same methodology will work for other ES2015 and above features and is nice for small apps that want to use some of the latest features and not have to deal with the build config of Babel or TypeScript transpiling down to ES5.

I’m not sure if this was an intended feature of the Script Tag Helper, but it’s a good use case for the fallback feature that I hadn’t seen anyone talk about, so I wanted to call attention to it.

And if you are lucky enough to only have to support Chrome at work.  I assume this is you right now reading the hoops us plebes have to go through to get our code to run on all browsers:

https://media.giphy.com/media/l3nWqD4ViFej9REAw/giphy.gif

One thought on “Using the ASP.NET Core Script TagHelper to Polyfill The Latest JavaScript Features

Leave a Reply