Optimizing JavaScript™ Programming Language Performance Make it Scream TS-6053
Optimizing JavaScript™ Programming Language Performance
Make it Scream
TS-6053
2008 JavaOneSM Conference | java.sun.com/javaone | 2
Agenda
Why are we here?Performance Tuning• Startup Time• Runtime
MetricsjsLex
2008 JavaOneSM Conference | java.sun.com/javaone | 3
Why are we here?
Days of JavaScript being used only for form validation are gone.Sites are using more and more JavaScript to create highly interactive application.Even sites that have simple interaction require lots of JavaScript• Digg.com (14 script files, 2 libraries, Multiple Extensions)• Espn.com (24 JavaScript files)• Ajaxian.com (12 JavaScript files)
Use of third party libraries
2008 JavaOneSM Conference | java.sun.com/javaone | 4
That’s how I got Here?
Started the Apache eXtensible Ajax Platform Project• 700 JavaScript files• Written on top of dojo 0.4
Built commercial modules on top of the open source library Idea was to allow developers to create “Desktop” application using AjaxXML Rendering layerEveryone was a Java Developer
2008 JavaOneSM Conference | java.sun.com/javaone | 5
Results
Cross Browser Rendering 60.4%
Runtime performance 48.7%
Testing / debugging 45.0%
Security 35.8%
Interactive design / UI issues 34.1%
Finding the right framework 30.2%
2007 Ajaxian Readers Survey
Source: [Please add the source of your data here]
2008 JavaOneSM Conference | java.sun.com/javaone | 6
Startup Time
# of RequestsSize of RequestsTime of RequestsTime of initial code completion
2008 JavaOneSM Conference | java.sun.com/javaone | 7
Reducing # of Requests
Makes the biggest impact on startup performanceBrowser has limited number of connections it can use to request resourcesEven when cached the browser still makes a requestAdd the expires header stop this from happening
2008 JavaOneSM Conference | java.sun.com/javaone | 8
The process is simple…
jquery.js
mycode.js
Concatenation Process code.all.jsplugin.js
2008 JavaOneSM Conference | java.sun.com/javaone | 9
…it’s deciding how and when that’s tough
Only two choices for when to do it:• Runtime• Development
Multiple choice for how• Ant• Server code• Dojo• Command line• IDE Support?• …
2008 JavaOneSM Conference | java.sun.com/javaone | 10
Using server-side code to do the concatenation
Goal is to make one request for all the JavaScript
<head><script src=“jquery.js”></script><script src=“plugin.js”></script><script src=“mycode.js”></script>
</head>
Becomes<head> <script src=“combiner.php”></script></head>
2008 JavaOneSM Conference | java.sun.com/javaone | 11
PHP Example
//combiner.php function combineFile($file){
$handle = fopen($file, "r");if ($handle != null){
echo fread($handle, filesize($file));}
}//combine filescombineFile(“jquery.js");combineFile(“plugin.js");combineFile(“mycode.js");
2008 JavaOneSM Conference | java.sun.com/javaone | 12
Server-side Concatenation
Pluses:• Easy depending on your server tier• Easy to update code
Minuses:• Performance load on server.
• Can be mitigated with caching
• Hard to distribute code to other people• No dependency tracing
Where it could be used?• Small single projects
How uses this?• Plaxo.com
2008 JavaOneSM Conference | java.sun.com/javaone | 13
Tips to Reduce # of Requests
Development and Build Processes• Dojo• Ant• Command line scripts
2008 JavaOneSM Conference | java.sun.com/javaone | 14
Dojo Packaging Overview
What you will need:• Ant, Rhino (Custom), …
Profiles• Determines the starting files to trace dependencies.
Incorporate require and provides in your files.dojo.provide(“acme.foo.Widget");dojo.require(“dijit.form.Button");
<script>dojo.require(“acme.foo.Widget");
</script>
Learn more• http://www.dojotoolkit.org
2008 JavaOneSM Conference | java.sun.com/javaone | 15
Dojo Advantages / Disadvantages
Pluses:• Not server load issues• Easy to update code• Dependency based
Minuses:• More Complicated (Ant, Rhino, …)• Hard to distribute code to other people• Need to change files
Where it could be used:• Medium to Large projects
2008 JavaOneSM Conference | java.sun.com/javaone | 16
Concat Ant Task Overview
Problem• Not dependency based
Learn More• http://ant.apache.org/manual/CoreTasks/concat.html
Who uses this?• jQuery
2008 JavaOneSM Conference | java.sun.com/javaone | 17
Using these methods for a small project is like…
2008 JavaOneSM Conference | java.sun.com/javaone | 18
A better solution
Integrated into the IDESimple workflow to create compressed and concatenated filesBe able to rebuild the files that were createdAlso work with CSS
2008 JavaOneSM Conference | java.sun.com/javaone | 19
jsLex Compressing files in Aptanawww.rockstarapps.com
2008 JavaOneSM Conference | java.sun.com/javaone | 20
Reducing Size of Requests
How do I do that?• Remove whitespace and comments• Remove EOL characters• Shrink variable and function parameter names• GZIP
code.all.js Compression Process code.all.min.js
2008 JavaOneSM Conference | java.sun.com/javaone | 21
Compression Tools
jsMinDean Edward’s PackerDojo Shrinksafe YUI CompressorjsLex Eclipse Plugin
2008 JavaOneSM Conference | java.sun.com/javaone | 22
X=10Y=“Bob”
Be careful removing EOLs
X=10Y=“Bob”
Compression Process
2008 JavaOneSM Conference | java.sun.com/javaone | 23
Be careful removing EOLs
X=10;Y=“Bob”;X=10;Y=“Bob”;
Compression Process
2008 JavaOneSM Conference | java.sun.com/javaone | 24
Coding Style
This can help make code much smallerSingle line “if”, “for”… Do not need “{}”Combine var declarations into a single var• var x=1,y=2;
Use JS style object!…
2008 JavaOneSM Conference | java.sun.com/javaone | 25
GZIP Compression
Pluses• Dramatically reduces size of file
• 330KB to 70KB
• Simple to do• Lots of gzip tools
Minuses• Lots of browser caveats
2008 JavaOneSM Conference | java.sun.com/javaone | 26
GZIP Compression Caveats
Content-Encoding must be GZIP and Content-Type must be application/x-javascript; this requires web server configuration changes in most casesBrowser must request HTTP 1.1 and must specify that it supports gzipScript tag must be between the HEADER tags in the HTML (solves IE bug with compressed JavaScript)Some client side and/or server code will be needed to detect the user agent and request the appropriate script
2008 JavaOneSM Conference | java.sun.com/javaone | 27
Sample PHP code for dealing with GZIP
<?php$library = $_GET["library"];if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')){
header("Content-Encoding: gzip");header("Content-Type: text/plain");readAndOuputFile($library.".gz");
}else{readAndOuputFile($library);
}function readAndOuputFile($file){ $handle = fopen($file, "r"); if ($handle != null){ echo fread($handle, filesize($file)); }
}?>
2008 JavaOneSM Conference | java.sun.com/javaone | 28
Other Items
Minimize the code that is executed at startupBring back data / content once screen is completely rendered• Look at the yahoo homepage, the content not visible isn’t usually
present on the client,• Yahoo also doesn’t fetch content until user requests it• rockstarapps.com fetches data feeds after screen is rendered.
Loading images• Lets users know something is going on• Distracts the user from the time it is taking
2008 JavaOneSM Conference | java.sun.com/javaone | 29
Run-time Performance
High level• Minimize the code • use the native facilities
Lower Level• XML vs. JSON• DOM Searching• DOM Creation• If statement optimization
Even Lower Level• Look at the performance characteristics of the language and basic
code building blocks
2008 JavaOneSM Conference | java.sun.com/javaone | 30
Let’s Look at some low level JavaScript programming language
Compare low level calls between browserCompare different way of doing things• Getter/Setter vs direct property access• For loop structure• innerHTML vs appendChild
The closer in scope the variable is the better the performance.• Avoid global variables
2008 JavaOneSM Conference | java.sun.com/javaone | 31
Low level function call demonstrationwww.rockstarapps.com/samples/performance.
2008 JavaOneSM Conference | java.sun.com/javaone | 32
DOM Creation - innerHTML
Pluses• Fast• Code can be small.
document.getElementById(“myDiv”).innerHTML = “<table><tr><td>New Table</td><tr></table>”;
Minuses• Code gets messy quickly when doing
more complicate snippets of HTML• Normally will this method requires a lot of string concatenation.
2008 JavaOneSM Conference | java.sun.com/javaone | 33
How its done in YUI!
Using an array and join to optimize string concatenation
html[html.length] = "<table>";html[html.length] = "<tr>";html[html.length] = "<td>“;html[html.length] = “My cell text”;html[html.length] = "</td>“...domObject.innerHTML = html.join("\n");
I have also seen this in Google’s code to create date strings.
2008 JavaOneSM Conference | java.sun.com/javaone | 34
DOM Creation – Tail Recursion
Create DOM Objectsvar table = document.createElement(“table”);var tr = document.createElement(“tr”);var td = document.createElement(“td”);
Append in reverse ordertr.appendChild(td);table.appendChild(tr);onScreenElement.appendChild(table);
2008 JavaOneSM Conference | java.sun.com/javaone | 35
DOM Searching
Use native• getElementById()• getElementsByTagName()
Avoid complete DOM traversalstoolkits• dojo.query• Prototype• jQuery• Mootools
2008 JavaOneSM Conference | java.sun.com/javaone | 36
Every Line Matters
for (var l=0; l<ignore.length; l++){
If (attr.nodeName.toLowerCase() == ignore[l])
for (var k=0; k<attrs.length; k++){for (var j=0; j<cells.length; j++){
for(var i=0; i<rows.length; i++){
2008 JavaOneSM Conference | java.sun.com/javaone | 37
Simple optimization usually save the most amount of time
var low = attr.nodeName.toLowerCase();
If (low == ignore[l])
for (var k=0; k<attrs.length; k++){for (var j=0; j<cells.length; j++){
for(var i=0; i<rows.length; i++){
for (var l=0; l<ignore.length; l++){
2008 JavaOneSM Conference | java.sun.com/javaone | 38
Look for unique ways to save even more time
for (var k=0; k<attrs.length; k++){for (var j=0; j<cells.length; j++){
for(var i=0; i<rows.length; i++){
bIgnore = joined.indexOf( attr.nodeName.toLowerCase()) != -1;
2008 JavaOneSM Conference | java.sun.com/javaone | 39
Lessons learned
1. Give yourself time• Adding concatenation and compression process will results in
errors
2. Create a different coding standard for JavaScript• It shouldn’t look like your Java coding standard
3. Build in best practices• Going through and change all your for loops and removing
unneeded curly braces is a pain.
4. Use a light weight JavaScript API5. These things will make a big difference6. Don’t wait until the release depends on these things to
do them (See #1)
2008 JavaOneSM Conference | java.sun.com/javaone | 40
2008 JavaOneSM Conference | java.sun.com/javaone | 41
Thank You!!!
For more information go to• http://www.nexaweb.com
Home of jsLex• http://rockstarapps.com
My Blog• http://rockstarapps.com/wordpress
Register for an upcoming 2 hour Webinar on May 29th, 2008 at http://nexaweb.webex.com