See the general optimization page for basic set-up. Also see the jQuery doc page for a good way to set up your project, even if you are not using jQuery.
Using require() and define() to define script modules and dependencies is an efficient syntax for indicating related code. However, for deploying code in the browser, it may not lead to the best overall performance. To find nested dependencies, a script has to be fetched, then a require() or define() call in that script might trigger other script downloads.
The Optimization Tool allows a quick way to build all your scripts into one file, so only one script download is needed for your page.
However, if you have many pages in your web app, it may make more sense to optimize your scripts into a set of two or three optimized layers:
Ideally you could do that layering after you finish development, and tune those layers for optimal, parallel download of the files, without having to change all your scripts.
This is possible with RequireJS:
Script modules/files specified in the config's priority array will be downloaded in parallel before any other script dependencies are traced. Note: resources loaded by loader plugins (like 'text!template.html') cannot be specified in the priority array: the priority mechanism only works with regular JavaScript resources.
This example builds on the sample jQuery project to demonstrate the approach:
Assume the project has the following structure:
page1.html might look like this:
<!DOCTYPE html>
<html>
<head>
<title>Page 1</title>
<script src="scripts/require.js"></script>
<script>
require.config({
priority: ["appcommon", "page1"]
});
</script>
</head>
<body>
</body>
</html>
with appcommon.js looking like this:
define(["jquery", "object", "event", "widget", "Dialog"],
function () {
//Just an empty function, this is a place holder
//module that will be optimized to include the
//common depenendencies listed in this module's dependency array.
});
and page1.js looking like this:
define([ "jquery", "object", "event", "widget", "Dialog", "Tabs"],
function ($, object, event, widget, Dialog, Tabs) {
...
});
page2.html and page2.js would look similar, except referencing "page2" instead of "page1" and using "Slider" instead of "Tabs" in page2.js.
The build profile, app.build.js would look like this:
({
appDir: "webapp",
baseUrl: "scripts",
dir: "webapp-build",
optimize: "none",
modules: [
{
name: "appcommon"
},
{
name: "page1",
exclude: ["appcommon"]
},
{
name: "page2",
exclude: ["appcommon"]
}
]
})
Once the build is run, it will generate the contents of webapp-build that look similar to webapp, except that the contents are optimized. appcommon.js will contain the common modules, and page1.js will have all the modules page1 needs, excluding appcommon's modules and their nested dependencies.
The priority config value tells RequireJS to load appcommon.js and page1.js in parallel and wait before both are loaded before tracing dependencies. With those two files, along with require.js, all the dependencies in the page will be loaded with three requests, with the appcommon.js and page1.js scripts being loaded asynchronously and in parallel.