Loading Scripts Late
On the ASP.NET ScriptManager control there is a useful little property that very few people have heard of called “LoadScriptsBeforeUI”. What does it do?
Well, simply put...
· When “true” (the default) it will render <script> tags for each script you reference using the ScriptManager at the top of your HTML.
· When “false” it will render these <script> tags at the bottom of your HTML.
Oh right. Why would I bother?
Well to put it simply it is because all browsers stop parsing and rendering HTML while they are downloading and executing scripts... which means if you put your <script> tags at the top of a web page none of your page will start to render until all scripts are downloaded and dealt with. The bottom line is that while your page is downloading scripts, the page is usually blank, and your user is wondering why the page is taking so long to load.
In a development environment this may not seem particularly important – but deploy your application to somewhere bandwidth and network speed are unknown, and it can often become an issue. Users don’t like sitting waiting for your site to respond, so you could be losing users!
Let’s see it
Let’s see what this looks like in action – download the attached sample solution and view the two pages. One downloads my scripts first; and I’ve made sure one of the scripts takes 5 seconds to load, so it is obvious how slow the page is. The other page loads the script last... and you’ll notice the page renders immediately, without waiting for the script.
Have a look at the HTML source and see where the references to TestScript.js and GetScript.ashx are.
The Gotcha
I’ve just showed you how to improve the perceived performance of your web site by changing one setting from “true” to “false”! Right?
But I’m afraid there is a catch. You’ll also notice there is a button on my test web pages. This is to demonstrate something important; you need to be very aware of when the scripts are being downloaded. This leads to two opposing issues;
1. If you have scripts that execute as soon as they’re downloaded, they probably assume that the DOM has been built. In this case, they usually must be rendered last. I’d recommend using page load events instead, so that you don’t have this requirement.
My sample demonstrates this; only when TestScript.js is loaded after the UI has been rendered does the button work, because TestScript.js assumes the button exists and attaches an event handler. If I put this in pageLoad instead it wouldn’t be an issue.
2. If you have event handlers embedded in your HTML that depend upon some framework scripts you’re downloading later, the user could click the button before your scripts have downloaded and the handler would error! This approach to wiring up event handlers looks something like this;
<button onclick="callMethod()">Click Me</button>
The solution here is to attach event handlers programmatically, as I have done in TestScript, but in the pageLoad event instead. You could even consider defaulting your buttons/controls to a "disabled" state, enabling them once you've attached the event handlers. This can sit well with the principles of Unobtrusive JavaScript and progressive enhancement if your controls have default non-script behaviours, so is a good practice anyway.
The End...
I think this shows a useful technique that can really improve users’ perception of your web site... as long as you design your use of script to work correctly. Enjoy!