Speed Up Your Javascript, Part 2: Downloadable Examples!

I’m happy people are finding thearticle on javascript optimizationuseful. But I made a giant, horrible mistake. A mistake that befalls many tutorials.

I didn’t include actual, working examples for you to play with.You can talk all you want, but until you’ve got some code, it’s just theory and listless sighs. And without seeing the code walk (or run! Get it?), it’s hard to believe that it really works. So here’s some live, working examples to show these techniques in action:

The examples are free and in the public domain. However, if you find it useful I’d appreciate you sharing it with friends ordropping me a note. I like knowing what explanation styles work so I can do more of it in the future.

And now, the guided tour of what you’ll see in the zip file.

Eliminate Tedium: Use Scripts

Automate, automate, automate! I’ve created a set of batch files (and .sh files for you Linux/UNIX gurus) to get you started:

  • makeall.bat: Runs the commands below
  • make_libraries.bat:将*.js合并为“allfiles.lib.js”,并将以“example”为前缀的文件合并为“example.lib.js”。
  • pack_js.bat: Compresses *.js and creates *.js.packed
  • add_cache_header.bat: Inserts thePHPcaching header into the .js.packed files, creating js.packed.php
  • cleanup.bat: Removes generated files, leaving you with your original .js files.

These are templates – modify them to suit your own needs. If you find yourself typing a command again and again, throw it into a script.

Compressing Javascript

I’ve includedcustom_rhino.jarwhich does the compression (more info).

There are a few javascript files for demo purposes. The first isexample_compressed.js, which has extremely long variable names in various scopes (local and global). Take a look at this sucker, it’s ripe to get crunched by Rhino:

/*这些名字是全局的,所以不会被压缩(可以在其他地方使用)*/ var LongName = 1;var OtherLongName = 2;var ReallyReallyLongName = 3;var absurdlylongnameimnotquitesurewhyanyonewouldusethisbuttitisgoodforeexamples = 3;/*这些名称是foo()本地的,并将被压缩。不是犀牛棒?*/函数foo(){var LongName = 1;var OtherLongName = 2;var ReallyReallyLongName = 3;var absurdlylongnameimnotquitesurewhyanyonewouldusethisbuttitisgoodforeexamples = 3; var LongName = 1; var OtherLongName = 2; var ReallyReallyLongName = 3; var AbsurdlyLongNameImNotQuiteSureWhyAnyoneWouldUseThisButItIsGoodForExamples = 3; (repeated...) return 0; // of course :) } log("Compressed Example Loaded!");

一个典型的“javascript压缩器”会简单地删除额外的空格和注释,这没有多大帮助。Rhino实际上会分析您的代码:当它看到全局变量时,它知道不应该更改名称,因为其他脚本可能会引用它们。

But local variables are another story. Since locals are only referencedinside of their function, they are ripe for squashing. This is your javascript on Rhino:

var LongName=1; var OtherLongName=2; var ReallyReallyLongName=3; var AbsurdlyLongNameImNotQuiteSureWhyAnyoneWouldUseThisButItIsGoodForExamples = 3; function foo(){ var _1=1; var _2=2; var _3=3; var _4=3; var _1=1; var _2=2; var _3=3; var _4=3; var _1=1; var _2=2; ... return 0; } log("Compressed Example Loaded!");

Any questions?

Rhino trampled the variable names and replaced them with the shortest identifiers it could find: _1, _2, etc. This saves a lot of space, and has the side-effect of partially obfuscating your code (if you are looking for that sort of thing).

Dynamic Import and Delayed Loading

Now here’s the fun stuff:example_imported.jsandexample_delayed.jsdon’t do anything special, except call a logging function that shows when they were loaded.

Check outsample.html

< html > <头> < !>   <脚本src="import.js"><脚本> /*简单的记录器——查找id为"log"的div。我们希望从一开始就能得到它。*/函数日志(str){var记录器= document.getElementById(“日志”);如果{记录器(logger)。innerHTML += new Date().toString() + ": ";记录器。innerHTML + = str;记录器。innerHTML += "
"; } } Put content here...

Take a look atthe result:

sample_html.png

Notice how$importacts immediately, and the delayed load happens 5 seconds later. All the scripts call thelogfunction, but it could be any callback, likeregisterLoadEvent()ordisplayHiddenFeature(). Leave that for your imagination.

Creating Library Files

It can also be helpful to combine smaller files into a larger one, especially if they don’t change often. This reduces the number of requests the browser makes and you don’t suffer the overhead for each item.

Downloading one 10k script is faster than ten 1k ones – browsers can only have a certain number of connections open at a time. Once you’ve got the connection going, you may as well cram a larger file down.

TheUNIX“cat”(或Windows“type”)命令是完美的。If you set a filter (example*.js) you can combine files with the same prefix into a library:

cat *.js > allfiles.lib.js cat example*.js > example.lib.js

And since the library ends in .js, it will get packed along with the other .js files in our packing script.

AddingPHPCache Headers

The last step is to add the cache headers to the files. There is a general “set_cache_header.php” file that is combined with the packed javascript (.js.packed) to create the js.packed.php files. Assuming your server is configured to servePHP,this will set the caching headers for 3 days (change this toany number you like).

Always Keep learning

We’re never done learning — I’d love to see what other tricks you use to speed up your javascript or automate the “build” process.

Remember that there are all sorts of interesting callbacks you can do. The scripts, once loaded, can call functions to display previously hidden features in the page: as scripts are loaded, menu items/images/text could appear. Or, you can just have one master script that$importsthe others, so you don’t need to monkey with yourHTML如果添加一个新的javascript文件(一些javascript库的行为是这样的)。可能的情况还有:使用一些、全部或不使用这些技术。尝试并学习什么对你有效。

Happy hacking.

Other Posts In This Series

  1. How To Optimize Your Site With HTTP Caching
  2. How To Optimize Your Site With GZIP Compression
  3. How To Debug Web Applications With Firefox
  4. Speed Up Your Javascript Load Time
  5. Speed Up Your Javascript, Part 2: Downloadable Examples!

Join 450k Monthly Readers

Enjoy the article? There's plenty more to help you build a lasting, intuitive understanding of math. Join the newsletter for bonus content and the latest updates.