Web Performance Calendar

The speed geek's favorite time of year
2021 Edition
ABOUT THE AUTHOR
Robert Boedigheimer

Robert Boedigheimer (@boedie) works for Schwan's Home Service providing business solutions with web technologies. He is a Microsoft MVP, a Progress Developer Expert (Fiddler), an ASPInsider, a Pluralsight author, and a 3rd degree black belt in Tae Kwon Do. Robert regularly speaks at national and international events.

The addition of the async and defer attributes for the <script> element were extremely helpful for lessening the impact of non-critical JavaScript resources on the HTML parsing process. Many vendors ask to include their JavaScript at the top of the <head>, and when challenged about potential performance impacts respond by saying just to add the async attribute and everything will be fine. Steve Souders article did a great job explaining how the attributes work, and how async JavaScript resources can still potentially impact rendering. When the goal is to shift resources later in the page processing the defer seems to be a better choice. Web sites often have another category of resources that could be deferred even later, in this case after the page onload event to ensure that they will not compete with critical resources on the page.

Impact on Critical Resources

Fiddler is a great tool that can selectively introduce delays to specific resource requests to gauge impact. For this example, there are two JavaScript resources requested, one using async and one using defer. The rule in Fiddler adds a 20 second delay to the primary image for the page

Fiddler Rule to Delay

Fiddler shows that the two JavaScript resources were both downloaded while waiting for the image to download

Javascript downloaded image waiting

The browser DevTools Console panel shows the output of each JavaScript execution which was simply a console.log() to indicate execution was complete

DevTools console output

At this point we have shown that even with async and defer the JavaScript resources were downloaded and executed which may have impacted more critical resource downloads and processing.

defer Until After onload Event

A technique I’d like to explore here takes advantage of “data-” attributes to indicate resources that should not be used until after the browser onload event fires when parsing and critical resource downloads are completed. The example uses both a JavaScript resource and an image that are deemed non-critical. By using data-deferred-aol-src rather than src attribute in both of these instances the browser will not take action on those elements. The onload event calls a function to adjust the attribute values.

Data attribute to stop browser processing

The function finds all elements that have a data-deferred-aol-src attribute and copies its value to the src attribute at which point the browser makes the requests for the non-critical resources. The alert() was in the method for testing to show that the resources were indeed delayed until after onload.

JavaScript method that copies attribute values

Fiddler showed the requested resources up until the alert message appeared. The orange marked resource was the last requested at that point. Then closing the alert message shows the two additional resource requests were made after onload for the non-critical resources as desired.

Fiddler shows resources after onload

Conclusion

This technique provides the ability to defer non-critical resources later in the page processing to ensure that those resources don’t impact critical resources needed by the page. Test that the deferred resources still work properly as some cannot function after onload (seen most often with some JavaScript resources). The important thing to consider is that these truly need to be non-critical, as a slow critical resource could keep the onload event from firing and the user may choose to leave the page before the non-critical resources have completed. Life is tradeoffs, so choose wisely!