Home / AJAX

HOW TO Load a Custom Script with Dependencies

Modified on 2009/12/04 17:24 by Stephen Walther Categorized as Uncategorized
The ASP.NET Ajax Library Script Loader can be used to load Microsoft scripts, jQuery scripts and even custom scripts. By using the Script Loader you can take advantage of parallel script loading which allows pages to load more quickly and also handle script dependencies more easily. Custom scripts can be loaded using the standard <script> element or by calling Sys.loadScripts which accepts a path to the script that should be loaded. However, neither of these techniques automatically handles loading dependencies that a script may have. A common example of script dependencies can be seen with the various jQuery plug-ins that are available. Each plug-in script has a dependency on jQuery and it's important that the scripts are loaded after jQuery has been loaded. In other cases a script may define a function called Calculate that in turn calls a function located in another script. The order that these scripts are loaded in doesn't matter as long as both functions are available once the Calculate function is called by the program.

In cases where a custom script has dependencies on one or more scripts a custom metadata file can be created to define the dependencies. This metadata file can define all the scripts involved using the Script Loader's Sys.loader.defineScripts function. The metadata script defines the custom scripts to load as well as any dependencies they may have. Dependencies that a script has can be defined using the "dependencies" property or the "executionDependencies" property. Additional details about each property are shown next:

dependencies: Use this property when a dependency script must be loaded before a custom script can be loaded. Dependencies must be loaded in sequential order, one after the other, to ensure correct execution order and that each script has its dependencies when it executes. Using this property causes the Script Loader to load scripts in serial.

executionDependencies: An executionDependency must be loaded by the time the custom script is actually used in a page but does not have to be loaded first. For example, if a script contains a function that uses a function defined in another script, it only has an ‘execution dependency’ on the other script so it is acceptable to load the function before the other. This is the best approach to take whenever possible since it allows the Script Loader to load scripts in parallel which minimizes a page's load time.

An example of using the Script Loader's defineScripts method is shown next. This example loads the jQuery UI script which has a dependency on jQuery (jQuery must be loaded first):

Sys.loader.defineScripts(null, [ { name: "jQueryUI", releaseUrl: "/Content/Scripts/jquery-ui-1.7.1.custom.min.js", debugUrl: "/Content/Scripts/jquery-ui-1.7.1.custom.js", dependencies: ["jQuery"] isLoaded: !!(window.jQuery && jQuery.ui) } ]);

The name property defines how the scripts will be refenced using the Script Loader. For example, to use the jQuery UI script the following call can be made:


The releaseUrl and debugUrl properties define the path to the respective release and debug versions of the script. The version loaded depends on the value of the Sys.debug property which is false by default when using the 'start.js' script and true by default when using the 'start.debug.js' script. A debugUrl need not be provided, in which case the releaseUrl would always be used. The dependencies property defines that jQuery (which is defined in the start.js file) is a dependency that must be loaded first. Finally, the isLoaded property ensures that the jQuery UI script is only loaded once by checking for the existence of jQuery.ui in the DOM, in case it has already been included via a <script> element.

The following code demonstrates how multiple jQuery plug-ins and a custom script all with a dependency on jQuery can be defined using defineScripts. Notice that the dependencies property value is passed as the first parameter to defineScripts since each script has a requirement on jQuery. Although it can be defined on each script as shown earlier, defining it in one place reduces duplication and results in a smaller file. The first parameter is a set of default values to apply to each of the scripts you define.

Sys.loader.defineScripts({ dependencies: ["jQuery"] }, [ { name: "jQueryUI", releaseUrl: "/Scripts/jquery-ui-1.7.1.custom.min.js", debugUrl: "/Scripts/jquery-ui-1.7.1.custom.js", isLoaded: !!(window.jQuery && jQuery.ui) }, { name: "jQueryExtensions", releaseUrl: "/Scripts/jquery.extensions.js", isLoaded: !!(window.jQuery && jQuery.fn.convertNullToEmptyString) }, { name: "jQueryInputMask", releaseUrl: "/Scripts/jquery.maskedinput-1.2.2.min.js", debugUrl: "/Scripts/jquery.maskedinput-1.2.2.js", isLoaded: !!(window.jQuery && jQuery.fn.mask) }, { name: "jQueryNumeric", releaseURl: /Scripts/jquery.numeric.js", isLoaded: !!(window.jQuery && jQuery.fn.numeric) }, { name: "jQueryBlockUI", releaseUrl: "/Scripts/jquery.blockui.js", isLoaded: !!(window.jQuery && jQuery.fn.block) }, { name: "jQueryBgIFrame", releaseUrl: "/Scripts/jquery.bgiframe.min.js", debugUrl: "/Scripts/jquery.bgiframe.js", isLoaded: !!(window.jQuery && jQuery.fn.bgIframe) }, { name: "orderScript", releaseUrl: "/Scripts/Order.js", isLoaded: !!window.AttachMasks } ]);

Figure 1 shows the order in which the scripts are loaded once the metadata file is loaded by the Script Loader. Note that jQuery is loaded before all of the other scripts that require it.


Figure 1. By using a metadata file dependencies can be defined and loaded in the proper order.

In cases where a script has a dependency that doesn't need to be loaded first the executionDependencies property can be used. For example, if a script named Calculations.js has a function that calls a function located in a separate file named Rules.js the following metadata file can be created:

//AppScriptsRegister.js Sys.loader.defineScripts(null, [ { name: "Calculations", releaseUrl: "../Scripts/Calculations.js", debugUrl: "../Scripts/Calculations.debug.js", executionDependencies: ["Rules"], isLoaded: !!window.Add }, { name: "Rules", releaseUrl: "../Scripts/Rules.js", debugUrl: "../Scripts/Rules.debug.js", isLoaded: !!window.Validate } ]);

This example allows the Script Loader to load the Calculations.js and Rules.js scripts in parallel. The Calculations.js can be loaded with the Script Loader using the following code:

<script src="../Scripts/Start.js" type="text/javascript"></script>
<script src="../Scripts/AppScriptsRegister.js" type="text/javascript"></script>
<script type="text/javascript">



  Name Size
- ScriptDependencies.jpg 24.76 KB