Sunday, September 20, 2009 12:54 AM
Hello everybody, those of you who followed up my sss.aspx posts, should note that this server control is the successor to sss.aspx.
There are many ways to speed up your website, and there are even more articles and books on how to do that. One of the Important ways is that the resources in your website like scripts, javascript and css files, have to be properly cashed so that the browser does not request them every time it visits the same page thus wasting valuable load times. Instead the first time the browser visits the website, it should download the files and not download them again until they are changed in the future. The way to achieve this is to use some headers that tells the browser the “version” of your files. The next time the browser visits the page again it asks the webserver for the same file(s) and it sends with the request header(s) the version it already has, if the file is not changed, the webserver should return 304 error to indicate “no change”. Another common and important method is to stream back the files compressed to the browser, this is something that happens at the http transport layer and the files are not actually modified in any way. The stream to send back the files is compressed usually using gzip compression and the browser when it receives them decompresses them again, this obviously saves on the amount of data transported over the Internet, saving you load times as well. Another good way to improve speed is to minimize the number of requests sent to download the files you need for the page to function, for example instead of having 6 javascript files and 2 css files to load inside your page, try to minimize them as much as you can. Minimizing the files will also speed up your page loading times since most browsers downloads 2 resources at at time (2 connections per domain), the more you have resources, the more time it takes to download them. However combining your files into fewer larger files is not good for the cleanness of your code, usually we divide our scripts into separate files for code organization purposes and combining them makes your site’s code less clean, less modular and less manageable. Another way to speed up the loading time of your website is to add the scripts at the end of the page, this way the page elements are rendered and then the scripts are processed, also speeding the load time of your page.
Web 2.0 brings a lot of change to the way we interact with the web and the websites we develop nowadays have less server side code and more client side code. A direct consequence of this is that we have much more JavaScript code than we did few years ago :) One problem that arises with lots of JavaScript code is file dependencies, if your client side code is modular and it should be, you should not have code duplication, when you come to use client side code, you have to carefully analyze the dependencies of your JavaScript files and include them in order in your web page so that the page functions correctly, this is an error prone task and sometimes you find yourself adding two copies of the same JavaScript file in the same page without paying attention, silently delaying load times more than it should. Read on to see how AdvancedScriptManager control has a smart dependency system.
AdvancedScriptManager to the rescue. AdvancedScriptManager helps you with all these problems/optimizations with minimal effort from you. Read on to know what it does.
- AdvancedScriptManager is a Server side control that has support for design time. You add it by simply dragging it from your Tools toolbar.
- For it to function properly, the control needs to add an HttpHandler to your Web.Config files. In design time, it will detect that it is missing and prompt you to add it automatically for you.
- You add one or more scripts to it by using the designer, if the file you add is not found, it will be highlighted in red. This is a typical look of the control:
- For JavaScript files, you have a the option “Delay Load” for each of the scripts. This is a very powerful feature, when you set it to on. The script will not be loaded directly with the page, instead the page will load, once it is done, the script is injected dynamically, this speeds up the site quite well for long scripts as the rendering of the page will be completely finished before the script is injected. Please note that you need to have jquery to use this feature. jquery is a very poweful, very popular JavaScript library. If you do not have it in your project, it is just one JavaScript file, download it and add it to your project. jquery-1.2.6.js is already included with the sample application.
- The script files that you add to the control will be combined at runtime and streamed back as one file only, minimizing requests. Moreover the file is sent back using GZip compression if the browser supports it.
- The combined file that is sent to the browser has the proper Response headers set to support smart cashing. It supports the ETag and the Modified-Since headers. The control will properly handle the responses with 304 errors when the files are not changed, the browser will not download the files again.
- The dependency management feature goes as follows: Each file that depends on another file, will have a comment at the beginning of the file that indicates the proper dependency. Take a look at script1.js, script2.js and script3.js in the sample provided, script3 depends on script2 and script2 depends on script1 and script1 depends on jquery. Here is how the comment would look like:
/// <AdvancedScriptManager include="/scripts/jquery-1.2.6.js"/>
Do not worry if you re-include base scripts, for example script3 depends on script2 and script1. But script2 already includes script1. If you reinclude script1 in script3 you will not have a problem. The control builds a proper dependency list based on all the comments in the script files it has and handles the order properly. Moreover, if you have more than one control on the page, say 1 in the head of the page and another in the body. If you include a script file in the first control, and you include it in the second control as well by mistake or due to dependencies, it will not be injected again, all of the controls on the same page track the injected files and will not reinject the same file again when it is already injected. I use the HttpContext.Current.Items to enable the controls on the same page to be “aware” of each other at runtime.
-
In design time, when you add scripts to the control, the control will show you the full list of the files it will inject based on the dependencies of the files, this will help you detect problems in dependencies if you included the wrong files. You also have a property in design time “ShowFullDependencies” which can be toggled on and off to show the actual files added to the control or the full list of dependency files.
-
There is another design time property “ShowInDesign” that is on by default. When it is on, you will see the control as the screen shot above. If you want to see your page design without the control interfering with the final look, set this property to off and the design time control will not be visible.
-
You can use the control for JavaScript files and CSS files as well, if you have another special type of scripts for your site, you can add the extension to the property Handler.allowedExtensions in the source code to enable the control to support it.
-
You have the ability to modify the final combined file’s contents before it is sent to the browser. This feature will enable you to have “server side” modifications of CSS files or JavaScript files. One example of its usage If you have a website that users can log into, you might give each account the ability to specify the colors of the look of the site. You can do this by creating your CSS files with certain variables in them; instead of hardcoding a certain color in the CSS file, you specify it as [COLOR1], and then before the file is sent to the user’s browser, you replace all occurrences of [COLOR1] with the color that the user has set in his control panel. Using this feature is very easy, you hook up the static event OnModifyScriptContents which will be called right before the final file is served.
-
If your project has virtual path providers, you can add support to them in this control by hooking the event OnGetFile.
Let me know if you have any comments and have fun speeding up your website :)
Download the sample application + code from here