Saturday, December 3, 2011

Require.js Optimization

‹prev | My Chain | next›

Up today, I would like to play with require.js optimization (asset packaging). I have a small Backbone.js that I have been using the last couple of days. Let's see if I can optimize it.

Following along with the require.js optimization instructions, I install require.js via npm so that I can get access to the optimization script (r.js):
➜  backbone-requirejs-test git:(master) ✗ npm install requirejs
requirejs@1.0.2 ./node_modules/requirejs 
Let's see if I can figure out how to use it. Maybe point that script at my main.js file?
➜  backbone-requirejs-test git:(master) ./node_modules/requirejs/bin/r.js scripts/main.js 

node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
Error: Evaluating scripts/jquery-1.7.1.js as module "jquery" failed with error: ReferenceError: window is not defined
    at Function.load (/home/cstrom/src/backbone-requirejs-test/node_modules/requirejs/bin/r.js:2162:23)
    at /home/cstrom/src/backbone-requirejs-test/node_modules/requirejs/bin/r.js:1162:37
No, that does not seem to work.

From the documentation, I try the example arguments in my scripts directory:
➜  scripts git:(master) ../node_modules/requirejs/bin/r.js -o name=main out=main-built.js baseUrl=.

Tracing dependencies for: main

node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
Error: Error: Error evaluating module "undefined" at location "/home/cstrom/src/backbone-requirejs-test/scripts/jquery.js":
Error: ENOENT, No such file or directory '/home/cstrom/src/backbone-requirejs-test/scripts/jquery.js'
fileName:/home/cstrom/src/backbone-requirejs-test/scripts/jquery.js
lineNumber: undefined
http://requirejs.org/docs/errors.html#defineerror
In module tree:
    main
      my-calendar

    at Function.onError (/home/cstrom/src/backbone-requirejs-test/node_modules/requirejs/bin/r.js:7654:23)
    at execManager (/home/cstrom/src/backbone-requirejs-test/node_modules/requirejs/bin/r.js:602:28)
    at /home/cstrom/src/backbone-requirejs-test/node_modules/requirejs/bin/r.js:630:25
    at execManager (/home/cstrom/src/backbone-requirejs-test/node_modules/requirejs/bin/r.js:607:17)
OK. Now this is starting to get on my nerves.

In my main.js file to which I am pointing the optimizer, I am mapping jquery to jquery-1.7.1:
require.config({
  paths: {
    'jquery': 'jquery-1.7.1'
  }
});

require(['my-calendar'], function(calendar){
  calendar.initialize();
});
So why is the optimizer that reads this file looking for jquery.js instead of jquery-1.7.1.js? Grr...

Let's see what happens if I give it the jquery.js that it so desperately wants:
➜  scripts git:(master) ln -s jquery-1.7.1.js jquery.js       
➜  scripts git:(master) ✗ ../node_modules/requirejs/bin/r.js -o name=main out=main-built.js baseUrl=.

Tracing dependencies for: main
Uglifying file: /home/cstrom/src/backbone-requirejs-test/scripts/main-built.js

/home/cstrom/src/backbone-requirejs-test/scripts/main-built.js
----------------
/home/cstrom/src/backbone-requirejs-test/scripts/jquery.js
/home/cstrom/src/backbone-requirejs-test/scripts/underscore.js
/home/cstrom/src/backbone-requirejs-test/scripts/backbone.js
/home/cstrom/src/backbone-requirejs-test/scripts/my-calendar/views/paginator.js
/home/cstrom/src/backbone-requirejs-test/scripts/my-calendar/routers/paginator.js
/home/cstrom/src/backbone-requirejs-test/scripts/my-calendar.js
/home/cstrom/src/backbone-requirejs-test/scripts/main.js
If I load the current page, it needs 9 requests to get all of those javascript files, taking about 350ms:


To see what the optimization does, I switch the page to point to the built / optimized page:
<head>
    <title>Router Redirection</title>
    <script data-main="scripts/main-built" src="scripts/require.js"></script>
  </head>
Now, when I load the page, it only needs 3 requests (the HTML page itself, require.js and my main-built.js file):


And, instead of 350ms, it now takes less than 250ms. That is a nice little optimization.

If only I could figure out that jquery version thing. Maybe tomorrow.

Update: I did figure this out in part 2.

Day #224

3 comments:

  1. | If only I could figure out that jquery version thing. Maybe tomorrow.

    Came across the same problem, I figured 'jquery' resolves to 'jquery-1.7.1' and as RequireJS sees a dot in the filename it assumes the filename extension is '7.1' instead of 'js'.

    ReplyDelete
  2. If you're setting your paths in your main.js then you probably want to add ``mainConfigFile: "path/to/main.js"`` in your build file.

    ReplyDelete
  3. Great, but how would you include html template files loaded via !text in the optimization? Or is it included already? Thanks.

    ReplyDelete