JavaScript
Article

How to Use Modernizr Responsibly

By Jérémy Heleine

If you like playing with new features which might not be available in all browsers, you have surely already tried Modernizr. This library allows to test whether the features you want are available or not. As Modernizr adds some CSS classes on the html element to indicate if a given feature is available, you might be tempted to directly include it in the head tag to know as soon as possible if the features you want are available or not.

This approach was what the developers of Modernizr themselves recommended at the beginning. The problem with it is that it’s not compatible with the responsible approach we all should have. That’s why Paul Irish, one of the developers of the project, shared his thoughts about how Modernizr should be included. These thoughts inspired this article. In it we will talk about why we should adopt a responsible approach when we want to use Modernizr. Then, we will see some ways to put this approach into practice when possible.

Why Caring About How Modernizr Is Included

The usefulness of a responsible approach can be resumed in one question: do you like waiting for several seconds to access a web page? Surely not, and your visitors hate that too. That’s why, if they wait for a long time for the page to be displayed, they won’t come back. And I’m pretty sure you don’t want that. We all love fancy features, but not if they slow down our website too much. The good news is that you can still keep your fancy features, even with a responsible approach. The difference is that you won’t load them the same way.

Let’s discuss a concrete example of a JavaScript file. In a lot of cases, we wait for the page to be loaded before executing the script. In these cases, including the script in the head element is useless because the script is loaded at a very early stage but it’ll wait for the page to be loaded before running. The problem is that if your script is included in the head, the browser will load it before the page itself. This means that if your script is big in size, your visitors have to wait until the script is loaded before they can see the page.

Modernizr has been developed to determine if you can use some recent features, such as CSS transitions or transformations, in a web page. Excluding some special cases, you don’t need these features in order to display something on the screen of the user. There are scripts that must be included in the head tag, but most of them don’t. Modernizr is no exception. In most cases you don’t need to include it in the head and you can include the library right before the end of the body.

Before moving forward, I want to clarify a point: if a web page using Modernizr takes a long time to load, including this library responsibly won’t be enough to improve the performance. Embracing a responsible approach means that you have to think about it each time you want to include a JavaScript file or other potentially big resources. If you optimize the way one resource is included, you won’t necessary see a big difference. However, if you optimize how you include all your resources, the difference can be huge.

As I mentioned, there are cases where you must include Modernizr in the head and other where it’s not necessary. It depends on your project and your needs which is exactly what I’ll cover next.

Define Your Needs

Defining your needs is the first thing you should do before including Modernizr. You can test a lot of different things with this library but probably your project doesn’t need all these tests. If you visit this page you will see that Modernizr gives us a way to build our own customized version of the library with just the tests needed. The generated file will be smaller in size than a complete version of the library, so it’ll take less time to be downloaded.

customized build

Often, you don’t know in advance what features will be needed once the project is published. Generating a new build every time you add a feature is not a very attractive option. A possible solution is to develop your project with the complete version and only generate your own build once you publish your project. A much better approach is to use an automation tool like grunt-modernizr that crawls your CSS and JavaScript files to find all the features you’re using. Once done, it’ll create the corresponding customized Modernizr build.

By using grunt-modernizr instead of building a custom version by yourself, you ensure that you won’t include a useless function by accident. For example, you might need a test at a given moment but then getting rid of it, without removing the test from the custom Modernizr build. Keep in mind that grunt-modernizr won’t replace you when it comes to deciding whether the test or feature you use in your project is really useful or not. So, for every possible test Modernizr you should ask yourself if do you really need that test or not.

For example, the library has a test to determine whether the CSS property text-shadow is supported by the browser. You might think that knowing this information is useful in order to not apply the property if it isn’t supported. However, if the browser doesn’t support a CSS feature, it won’t crash or break the website, the property will be simply ignored. Therefore, you should ponder if it’s a big for your website if the shadow is not shown. Maybe your shadows are there to add a cool effect and, in that case, it doesn’t really matter if a visitor can’t see it. The enhanced experience is for users who update their browsers, but your website can survive without a text shadow for sure. The conclusion is that testing if this feature is available or not might be useless.

There are some cases where you want to add a text shadow to improve the readability of a text. If that’s the case, you must have a fallback behavior for browsers which don’t support this feature, thus you need the test to be performed. But the need of this test also depends on the type of fallback you want to use. There are some fallback in CSS that don’t need a test at all. In conclusion, consider well your needs before deciding.

A similar discussion can be made for html5shiv which enables you to support HTML5 elements in older versions of Internet Explorer. Modernizr can include it for you, but should you have it? If your website doesn’t support older versions of Internet Explorer, ensuring that you can style HTML5 elements in those browsers is useless, hence you don’t need html5shiv. Personally, I think that it’s an error to not support some browsers. It’s not very difficult to have a working website for some older versions of Internet Explorer. In conclusion, you should use the html5shiv, but not necessarily through Modernizr. Following a responsible approach, we often include this shiv in an inline script tag inside the head element (see the next part for more details).

To summarize, be sure to select the tests you really need. Some tests can often be forgotten and CSS fallbacks don’t always need Modernizr to work.

Some Features Can Wait

We all learned to write our scripts in separated files, concatenate and minify them, and link to the minified file in the HTML code. The advantages are multiple, from the possibility to include the script on several pages to the browser cache that can be used to allow faster downloads on following visits. The script to include the file can be placed in any place of the HTML code, not only in the head. Even more, placing it at the bottom of the HTML code have several advantages. For instance, the file won’t be downloaded before other elements elements have been parsed. Even if your script is big, it won’t prevent your users from seeing the page. Then, your script will be downloaded and the enhanced experience will start.

Here, I’m discussing a script that can wait for the end of the page to be loaded. In the same way, most Modernizr features can wait. We create an enhanced experience, available once the basic one is available. The spirit behind a responsible approach is that the user wants to see the content of your website and they want to see it rapidly. A good environment around the content is always better, but only if the information is there. That’s why we load the script to enhance the experience at the bottom of the page.

Said that, there are still some Modernizr features that we must include in the head like html5shiv. To support HTML5 elements, older versions of Internet Explorer need this shiv to be loaded before seeing the first HTML5 element. This means that you simply can’t defer its loading, but you can still improve the way you include it. An example is that you can include the html5shiv only if the browser needs it with a conditional comment. Another example is that you can directly include (inline) this shiv into the HTML code, without an external file. The cache won’t be available but the shiv isn’t that big. The advantage to not using an external file is that you avoid an HTTP request.

To determine if you need to include Modernizr in the head, you need to think about what and how you you want to display first. For all the tests you use, you have to consider if the web page will be broken if the tests are executed after the page is displayed. We can always provide a fallback behavior and then, once the right class is added in the html tag, this behavior will be overridden by the enhanced experience. It’s crucial for you to understand if the change is a big one or not. In fact, you could lose your users if some blocks move once the page is loaded. If the change is big, maybe you should include Modernizr in the head. But, before, see if it’s possible to make the change less visible with a better fallback behavior.

What About the Efficiency?

We want to load Modernizr at the bottom of the page to improve the loading time. However, as Paul Irish says, many of Modernizr’s tests (especially the CSS ones) cause reflows. With these tests, the browser may have to recalculate some styles. Following the complexity of the DOM tree and styles already in the document, these recalculations can take more or less time. If the library is included in the head, it’ll be executed before any element of the body is processed. If the body is empty, the calculations are less complicated for the browser, so it takes less time.

At this point you have to take an important decision: can the time earned by loading Modernizr at the bottom of the page be totally lose because of the execution time? Unfortunately, it’s difficult to provide a universal answer and it all depends on your specific case. Following the complexity of your DOM tree, the tests can be fast or not, so perform some tests to see how long it takes in your case to execute Modernizr. Keep in mind that the time may vary a lot based on the browsers and the versions you’re testing.

Talking about the efficiency of Modernizr is also another occasion to mention again the custom build you can create. By only selecting the tests you need, useless tests won’t be performed and if they affect the DOM tree, it’s time saved!

Conclusions

Thanks to this article, you should have a better understanding of Modernizr and how you should include it in your pages. We’ve discussed cases in which you can include it at the bottom of your page and others where it should be in the head. Regardless of what’s the solution in your case, always try to provide a good experience for those, among your users, who have a slow Internet connection by only include the features you need.

In this article I discussed about Modernizr, but this library is not the only one which can benefit from a responsible approach. For example, considering that jQuery is used to affect the DOM tree and scripts that use jQuery are often executed when the whole document is ready, why still including it in the head tag?

Developing responsibly is not just a fashion term. It’s an approach that we should follow as much as possible. As its name suggests, it’s pretty irresponsible to force the download of useless data.

  • PVgr

    Useful article, thanks!

  • http://SalaryNet30.com willie sumrall

    l just received my second paycheck of $6395,72 workin` only few h on my Iaptop` past 5 days. My divorced’ friend with 3 kids at home, made over $10k her 1st month. It’s great makin’ this much money” when other people have to work for so much Iess. Go 2 my profiIe’ site-link to see what I do…..

    %d

  • http://keralapavilion.com/ George

    The information is very relevant. The points described here are very valid for robust web development.

  • Admiral Ackbar

    “It’s not very difficult to have a working website for some older versions of Internet Explorer” – not so sure about that

  • BlackMael

    Great article.

    What about creating two “custom” builds of modernizr? One which contains the bits which have to be in the head element, and second one which you can put in the bottom of the page. Would there be much overlap of code in each build? Can the second build be made to not have the overlapping code, perhaps just extending the code loaded from within the head?

    • http://tassedecafe.org Jérémy Heleine

      Mh, delicate question. The problem is that we have now two HTTP requests instead of one so it could be longer than using a single script in the head (of course, once again, following the cases…). Maybe by making the script in the head an inline script? In all the cases, you absolutely must limit its size.

      • Timur Manyanov

        maybe it would make sense to inline the necessary part of modernizr in the head during build time?

  • https://www.linkedin.com/in/mohammedshafeekcs Mohammed Shafeek

    This article is more useful..

Recommended

Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in JavaScript, once a week, for free.