How to Use the Webshims Polyfill

The following is a guest post by Daniel Herken. Daniel is the author of the upcoming book The Cross Browser Handbook. He emailed me recently to share that as well as to offer to write a guest post. He was excited about Webshims Lib - kind of an "everything" polyfill. The following is that guest post, introducing that library and it's basic use.

In this post I'll be talking about the HTML5 and CSS3 feature polyfill library called Webshims Lib and how to use it correctly.

Polyfill?

In web development, we call scripts that emulate parts of the HTML5 or CSS3 specification "polyfills". A polyfill can be nearly anything - a JavaScript library that adds support for CSS3 selectors to old versions Internet Explorer (i.e. Selectivizr) or a high end Flash based solution to enable the <audio> and <video> tag all the way back to IE 6 (i.e. html5media).

Introducing Webshims

The Webshims Lib is one of the most complete polyfills out there. It is based on jQuery and Modernizr. Including this one script will enable many features across the whole range of desktop browsers.

Webshims enables HTML5 and CSS3 features like semantic tags, canvas, web storage, geolocation, forms and multimedia. Reading through this big list, the first thing that might come to mind is how huge this library must be. Meaning a huge download size and long script execution time. But here is the kicker, Webshims will automatically detect which features the users browser supports and it only loads what is necessary to simulate everything else. This way it will not slow down users who already run a modern browser like Firefox or Chrome. You can even reduce the amount of features to load if you don’t need everything.

How to Use Webshims

To use the webshims lib you need to include the dependencies jQuery and Modernizr alongside Webshims Lib.

Modern browsers will display this video correctly, but Internet Explorer 6, 7 or 8 will not.
Now we change the example to embed the Webshims Lib. You can see that it's not necessary to edit anything else.

The modern browser will display its native <video> tag player but now this functionality is also available in Internet Explorer 6+. You can try the demo here.

Conclusion

As the example has shown, it's really simple to use the Webshims Lib. There is no need to alter your code and it does not slow down users which use a modern browser. It enables everyone to enjoy all features your page provides. Head over to the Webshims homepage for the download, documentation and more demos.

Interesting! On one hand Christian Heilmann is talking about the vanilla web diet to simplify the web and on he other hand we have polyfills to support every other feature on all possible browsers available on the planet…

loading order is obviously important (since webshims is built on top of jQuery), but I don’t see anything that implies it must be done in the <head>.

The github README states that you need to wait for the document to finish loading before using any of the polyfilled features (which is good advice anyway), but also implies that you don’t need to wait to call $.webshims.polyfill().

Given that, I’d suspect that it’s perfectly safe to put everything at the bottom of the page (or in an onload event in the <head>, which accomplishes the same basic goal).

No it’s an addition to Modernizr. Modernizr is the best feature detection script on earth. Webshims builds on top of this to do the polyfills.

@traq

demo works for me in real IE6/7/8 (obviously you need flash installed).

@Ricardo

Loading order is cruical, but you can of course add jquery + webshims to the bottom of your page. But in short, I don’t think that this is always a good/best practice. There is really a lot to say about this rule and it’s just a workaround. Actually I think it is often a bad practice to put JS at the bottom. If your JS is crucial for the UI and functionality of your page, you should load it (blocking) from the head, if it’s not that important you should load it async from your head (using either async attribute or a script loader) and if it’s just adding some little extras (lightbox) you can load it async + delayed (onload/domready) from your head. You should also consider, that this rule was established in an IE6/IE7 era. In this time adding a script at the top not only blocked UI rendering, but also forced sequential downloading. This has changed since then and webshims always loads the polyfills async. (Combining async loading + delayed loading, will increase FOUCs without giving you a big speed boost).

Well, I have to say I strongly disagree with several comments you mention. But I also have some questions since you mention several interesting things:

1.- “[…] add jquery + webshims to the bottom of your page. But in short, I don’t think that this is always a good/best practice. “ – Not sure why don’t consider loading scripts at the bottom a good practice, many people do it: HTML5boilerplate, 320 And Up, etc. to name a few. If Yahoo developers recommend it, with great justifications, not sure why you’re against that practice.

I personally do it and will keep doing it because it makes sense from a technical, performance and SEO points of views.

2.- “[…] it’s just a workaround” – A workaround for what? I may be missing something then, but I don’t see anything to workaround of by placing the scripts at the bottom.

3.- “If your JS is crucial for the UI and functionality of your page, you should load it (blocking) from the head” – With today’s JavaScript features at our fingertips and the learning curve brought so far down by jQuery, I’d say that most of everyone’s JavaScript is crucial for the UI and functionality of our pages. Webshims is a clear example of this.

Yet, I don’t see going back to loading all the scripts in the <head> section any better than that we already know as a best practice to load them at the bottom of the markup.

4.-“[…] load it async from your head (using either async attribute or a script loader) […] load it async + delayed (onload/domready) “– Question: Haven’t heard of loading scripts ‘asynchronously’ or with a script loader or ‘delayed’, I’m not a JavaScript developer/guru. Can you provide any insight on this? Thanks in advance.

5.- “You should also consider, that this rule was established in an IE6/IE7 era.” – We are still in that era Alexander, the only difference is that we have more advanced browsers in the mix, but IE6 and IE7 are very much still with us.

In addition to this, Yahoo’s developers recommendation of placing scripts at the bottom of the markup has nothing to do with IE. So, not sure how your statement is justified.

6.- “In this time adding a script at the top not only blocked UI rendering, but also forced sequential downloading.” – You are correct in that adding scripts to the top (<head>) blocks UI rendering, hence, you are now starting to contradict yourself since you just said: “If your JS is crucial for the UI and functionality of your page, you should load it (blocking) from the head”.

On the other hand, sequential downloading happens no matter where you put your JavaScripts, in the <head> or at the bottom of the markup. Unless I’m unaware of something regarding loading of JavaScripts.

Not sure what “this time” means though. Sequential downloading has been here since this ‘machine’ was created.

7.- “This has changed since then and webshims always loads the polyfills async.” – What has changed “since then” if you just said “In this time…”. Another contradiction. It’s kind of hard to get your ideas…

8.- And one final contradiction: In your final statement you say that “(Combining async loading + delayed loading, will increase FOUCs without giving you a big speed boost)”, but above you actually just recommended doing it: “[…] you should load it async from your head (using either async attribute… […] you can load it async + delayed”.

As for the FOUC, I personally don’t see that as a huge deal. Yeah, it’s annoying, but that’s the nature of the beast and it’s just a matter of time before we don’t have to think about it anymore, just like we don’t think about -moz-border-radius anymore (unless you’re using a mixin that automatically includes it in your compiled CSS).

My take-away from all this is simple:

A. There’s no justification to not keep placing JavaScripts at the bottom of the markup. Of course, correct loading/stacking order is mandatory, but still, placing them at the bottom is absolutely Ok and a still a best practice.

B. We are still in the IE6/IE7 era. Can’t wait for the day I (we) don’t have to consider those characters anymore :)

C. I have no idea what async loading nor delayed loading nor a script loader are or how they work. If you or anyone has any info on that that could share, that’d be great.

D. I wish I had this conversation in person since I never get to talk at this level with anyone, not even where I work, I’m sure there’s plenty of stuff I need to learn from you and your work.

A. There’s no justification to not keep placing JavaScripts at the bottom of the markup. Of course, correct loading/stacking order is mandatory, but still, placing them at the bottom is absolutely Ok and a still a best practice.

There most certainly is. I’ve no idea what platforms and types of users you support, but 90% of the code I work on (which was not written by me) loads 95% of the Javascript in the head. So me, as a developer, if I need to concern myself with load orders, I too must load in the head or I will break things.

B. We are still in the IE6/IE7 era. Can’t wait for the day I (we) don’t have to consider those characters anymore :)

I feel bad for you. I really do. I haven’t had to worry about IE7 support in two years. IE8 issues only arise when a client specifically requests IE8 compatibility. You can’t wait for the day supporting Medieval browser ends? Then stop supporting them! By continuing to support them, you are supporting the problem. Many of us have already had that talk with bosses, clients, etc. I suggest you do the same and start giving them compelling reasons why old browsers are an incredible waste of time, resources, and ultimately, money. If they aren’t listening to you, you aren’t being compelling. If you intend to wait on enterprise users to switch to modern browsers, you will keep waiting for years.

C. I have no idea what async loading nor delayed loading nor a script loader are or how they work. If you or anyone has any info on that that could share, that’d be great.

There is plenty of info about async loading out there. I find it a bit smug that you begin to tell the author that his opinions are wrong when you yourself admit “I am not a Javascript guru”.

D. I wish I had this conversation in person since I never get to talk at this level with anyone, not even where I work, I’m sure there’s plenty of stuff I need to learn from you and your work.

But if understand it right then the polyfill gets also loaded in the browsers that do have native support for the HTML5 or CSS3 features you polyfill?
Or can, or even should, we load it with Modernizr.load yep/nope?

Not sure why don’t consider loading scripts at the bottom a good practice, many people do it: HTML5boilerplate, 320 And Up, etc. to name a few. If Yahoo developers recommend it, with great justifications, not sure why you’re against that practice.

If other people jump off a cliff, do you jump after them as well? “But other people are doing it as well” is hardly ever a valid argument.

Yahoo’s developers made this particular recommendation in a time when asynchronous script loaders did not exist, resources were still requested asychronously, the average web server and web proxy did not set proper far future expiration cache headers, etc.

We have a name for blindly following these kind of recommendations without periodic re-evaluation of their validity; it’s called cargo cult programming.

Question: Haven’t heard of loading scripts ‘asynchronously’ or with a script loader or ‘delayed’, I’m not a JavaScript developer/guru. Can you provide any insight on this? Thanks in advance.

RequireJS would be something nice to read and learn about. It’s a script loader that uses the emerging Asynchronous Module Definition (AMD) spec from CommonJS.

We are still in that era Alexander, the only difference is that we have more advanced browsers in the mix, but IE6 and IE7 are very much still with us.

No offense, but for the < 2% browser share I commonly see, I wouldn’t bother adhering to old cargo cult practices to optimize speed for gimped, underpowered browsers that are more than likely running on outdated hardware and are rapidly approaching a final death.

On the other hand, sequential downloading happens no matter where you put your JavaScripts, in the or at the bottom of the markup. Unless I’m unaware of something regarding loading of JavaScripts.

You are unaware of that fact that IE8+ and any contemporary version of the other major browsers download scripts in parallel. Only execution still happens sequentially (and you can even turn that off…)

Yes, Require.js, I’ve read a lot about it but haven’t really understood some of the concepts of it, now I have a better idea of what that is.

No offense taken Ron, you and I are in the same boat and share the same view. However, the share I commonly see is way, way higher than yours. I do have to say that I don’t do anything for IE6 anymore and certainly push as hard as I can to minimize IE7 extra-work.

Yes, I was unaware about modern browsers downloading scripts in parallel. I recently learned a quite a bit about this parallel-sequential downloading regarding CSS when using @import vs. link, but nothing about parallel-sequential download for scripts was discussed.

About async and normal loading behavior of JS. Normally browsers can load 2-8 files simultaneously per domain (old browsers like IE6/7 or FF3.0 do 2 others 4-8). And loading files parallel is obviously much faster than sequential.

The reason behind the rule “Put your JS at the bottom” is the following:

As soon as you normally add a script[src] to your HTML, it will block your browser from doing the following tasks:

So putting JS at the bottom minimized the problem, because there is no other download resource, which can be blocked and the DOM + UI is parsed/rendered to 99%.

This rule was established at a time, where all browsers blocked everything. As you can see a) and b) is only true for IE6/IE7 and only point c) is there in all browsers (and won’t change, because this is the way how browsers work). Actually not blocking the UI rendering always means, please create a FOUC. This is really important to understand. FOUCs are not a side effects of the rule “Put JS at the bottom”, they are intended. Because you as a developer say with this: My JS is not important for the UI, please do the JS stuff at the end.

async loading of scripts is a really nice technique to avoid problems of a, b and c in all browsers (even in IE6/7), while you have better control over the FOUC problem. The point here: As soon as you are using async loading, nothing is blocked, but due to the fact, that you can start your script download already in the head element, the script can be downloaded, parsed and executed much earlier and if it is inside the clients cache, you won’t produce a FOUC/FOUBC.

With delayed loading, I simply mean, that you can delay the async loading of a script (after a timeout, after domready or after onload), if this script is not important for your UI (for example lightbox), this technique might be helpfull, because although you are using non-blocking script loading techniques, loading a script consumes 1 http request, which could be used for a content image for example.

The only problem with async loading is the fact that the execution of your scripts aren’t ordered anymore and this can create race conditions. Webshims loads all async (without any blocking) and handles the race condition problem very efficiently (similiar to requirejs).

Not sure how I missed Chris’ Thinking Async post, will read it as soon as I post this reply.

Now, with yours and Ron’s explanations above, I’m sure I’m not the only one re-evaluating where/how to place the scripts in my markup since now I have new information and reasons to reconsider. Hmm… this sounds like I may be jumping off a cliff with you both, lol.

I’m sure no programmer where I work has any clue about anything we’ve discussed here regarding browsers, asynchronously and delayed loading of scripts, so I’ll be sure to let them know a few new things now.

Just curious know can we use yesNope.js to embed the our own polyfill for the feature don’t not exist in webshim lib. Else the any other way to embed just by using webshim itself. Or if I use yesNope.js how about performance.

Thanks in advance.

This comment thread is closed. If you have important information to share, please contact us.

Related

How do you stay up to date in this fast⁠-⁠moving industry?

A good start is to sign up for our weekly hand-written newsletter. We bring you the best articles and ideas from around the web, and what we think about them.

👋

CSS-Tricks* is created, written by, and maintained by Chris Coyier and a team of swell people. The tech stack for this site is fairly boring. That's a good thing! I've used WordPress since day one all the way up to v17, a decision I'm very happy with. I also leverage Jetpack for extra functionality and Local for local development.