Ajax Best Practices, Performance and Frameworks
Upcoming SlideShare
Loading in...5

Ajax Best Practices, Performance and Frameworks






Total Views
Views on SlideShare
Embed Views



2 Embeds 3

http://www.slideshare.net 2
http://www.scoop.it 1



Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
Post Comment
Edit your comment

Ajax Best Practices, Performance and Frameworks Ajax Best Practices, Performance and Frameworks Presentation Transcript

  • Ajax Best Practices, Performance and Frameworks Doris Chen Ph.D. Staff Engineer/Technology Evangelist 1
  • Agenda • Optimization Strategies and Process • Best Practices • Tools • Guidelines and Rules for High Performance Web Site • Frameworks and Case Study • Summary and Resources 2
  • Optimization Strategies and Process 3
  • Four Warnings 1. Speed is not free 2. Avoid premature optimization 3. Don't guess 4
  • 1. A Balancing Act • Performance • Reliability • Scalability • End-user Usability • Maintainability • Extensibility • Code Reusability • Portability 5
  • 2. Avoid Premature Optimization • Write clean, clear, maintainable code. • Test the program under normal conditions. • If it is fast enough, then ship it. • If users find it too slow, then optimize. 6
  • 3. Don't guess. • If the program is too slow, then use benchmarks and optimization tools to determine where the bottlenecks are. • Attack problems scientifically. > Don't trust your intuition. 7
  • Development/Optimization Process 1. Analysis 4. Perf. Tests 6. Pref. Tuning - Use Cases - Single-User - Best practices - Guidelines/Rules - Frameworks 2. Design Perf No OK? - Better algorithms - Architecture - Creativity Yes 3. Coding 7. Perf. Tests 5. Use Tools - Best practices - Mutiple Users - Find bottlenecks - Rules Tests Perf No Perf OK? OK? Yes No 8. QA OK? 9. Ship it! Yes 8
  • Ajax and JavaScript Best Practices 9
  • Use JavaScript Toolkits and Ajax Frameworks as Much as Possible • JavaScript Toolkits > Wrap up ajax details in javascript libraries > jQuery, Dojo, prototype+scriptaculous, Yahoo,... • Frameworks > DWR > GWT, Wicket > jMaki 10
  • JavaScript Best Practices • Use JavaScript Programming Conventions > http://dojotoolkit.org/developer/StyleGuide • De-reference unused objects • Write reusable JavaScript • Use object literals as flexible function parameters • Consider loading JavaScript on demand • Use JSON for model data transport • Provide a clean separation of content, CSS, and JavaScript • Be Careful about DOM • Understand element.innerHTML • JavaScript Module Pattern • Bad and Good Practices 11
  • De-reference unused objects //delete objects var foo='Delete Me'; //do something with foo delete foo; // detach listeners (IE / W3C difference) someElement.removeEventListener(type, fn, false); // W3C someElement.detachEvent(type,fn); // IE // remove DOM elements someElement.parentNode.removeChild(someElement); // page onunload window.onunload= function() { /*do something*/} 12
  • Write reusable JavaScript • JavaScript should not be tied to a specific component unless absolutely necessary • Consider not hard coding data in your functions that can be parameterized // The doSearch() function in this example can be reused because it is // parameterized with the String id of the element, service URL, and the <div> // to update. This script could later be used in another page or application <script type="text/javascript"> doSearch(serviceURL, srcElement, targetDiv) { var targetElement = document.getElementById(srcElement); var targetDivElement = document.getElementById(targetDiv); } </script> <form onsubmit="return false;"> Name: <input type="input" id="ac_1" autocomplete="false" onkeyup="doSearch('nameSearch','ac_1','div_1')"> City: <input type="input" id="ac_2" autocomplete="false" onkeyup="doSearch('citySearch','ac_2','div_2')"> <input type="button" value="Submit"> </form> 13
  • Use Object Literals as Flexible Function Parameters • Object literals are objects defined using { } > contain a set of comma separated key value pairs > Example {key1: "stringValue", key2: 2, key3: ['blue','green','yellow']} > Very handy, can be used as arguments to a function function doSearch(serviceURL, srcElement, targetDiv) { // Create object literal var params = {service: serviceURL, method: "get", type: "text/xml"}; // Pass it as a parameter makeAJAXCall(params) } // This function does not need to change function makeAJAXCall(params) { var serviceURL = params.service; ...} > Should not be confused with JSON 14
  • Load JavaScript On Demand • If you have a large library or set of libraries, you don't need to load everything when a page is loaded • JavaScript may be loaded dynamically at runtime > Use json.org json2.js javascript library on client > Use json.org java library on server > www.json.org 15
  • Example: Load JavaScript On Demand // Suppose the following is captured as cart.js file function Cart () { this.items = [ ]; this.checkout = function() { // checkout logic } } --------------------------------------------------------------------- // evaluate text from cart.js and create Cart object // secure convert to json using json.org processor json.parse(rawjsonText); var cart = new Cart(); // add items to the cart cart.checkout(); 16
  • Separation of content, CSS, and JavaScript • A rich web application user interface is made up of > content (HTML/XHTML) > styles (CSS) > JavaScript • Separating the CSS styles from the JavaScript is a practice > makes your code more manageable > easier to read > easier to customize • Place CSS and JavaScript code in separate files • Optimize the bandwidth usage by having CSS and JavaScript file loaded only once 17
  • Example: Good and Bad Practices <style>#Styles</style> <script type="text/javascript"> Bad // JavaScript logic <script> <body>The quick brown fox...</body> ------------------------------------------------------------------------------------- <link rel="stylesheet" type="text/css" href="cart.css"> <script type="text/javascript" src="cart.js"> <body>The quick brown fox...</body> Good 18
  • Be Carful about DOM • If JavaScript were infinitely fast, most pages would run at about the same speed • The bottleneck tends to be the DOM interface > There is a significant cost every time you touch the DOM tree. > Each touch can result in a reflow computation, which is expensive • Touch lightly > Faster to manipulate new DOM nodes before they are attached to the tree > Touching unattached nodes avoids the reflow cost 19
  • Understand innerHTML • Setting element.innerHTML is fast > browsers are really good at it > it only touches the DOM once • Write JavaScript that generates minimal HTML • Make sure to de-register event listeners in existing innerHTML before re-setting the element.innerHTML as it can lead to memory leaks in older browers (IE) • Keep in mind that DOM elements inside the element.innerHTML are lost when you replace the content and references to those elements • innerHTML is not synchronous on all browsers 20
  • JavaScript Module Pattern • Also called yahoo module pattern • keep variables in the private/public scope // basically an anonymous function with private scope window.myobject =function(){ var privateVar = “foo”; var privateVar = “hello”; return publicVar; }(); // the () here cause the anonymous function to execute and return 21
  • Coding Efficiency • Common subexpression removal • Loop invariant removal • Most compilers in most programming languages do these optimizations for you • But not JavaScript 22
  • Bad and Good Practices var i; for (i = 0; i < divs.length; i += 1) { divs[i].style.color = "black"; divs[i].style.border = thickness + 'px solid blue'; divs[i].style.backgroundColor = "white"; } Bad ----------------------------------------------------------------------------------------------------------------------------------------------- var border = thickness + 'px solid blue'; var nrDivs = divs.length; var ds, i; for (i = 0; i < nrDivs; i += 1) { ds = divs[i].style; ds.color = "black"; ds.border = border; ds.backgroundColor = "white"; } Good 23
  • String Concatenation • Concatenation with + > Each operation allocates memory foo = a + b; • Concatenate with array.join('') > The contents of an array are concatenated into a single string foo = [a, b].join(''); 24
  • About Cookies • eliminate unnecessary cookies • keep cookie sizes low • set cookies at appropriate domain level • set Expires date appropriately > earlier date or none removes cookie sooner • http://yuiblog.com/blog/2007/03/01/performance- research-part-3 25
  • Tools 26
  • Manual Timing Method function myFunctionToTest() { var start = new Date().getTime(); ... // body of the function var totalTime = new Date().getTime() - start; } 27
  • Tool: Firebug and YSlow 28
  • YSlow • http://developer.yahoo.com/yslow • performance lint tool • scores web pages for each rule • Firefox add-on integrated with Firebug • open source license 29
  • Guidelines and Rules for High Performance Web Site 30
  • The Performance Golden Rule 80-90% of the end-user response time is spent on the frontend. Start there. • Greater potential for improvement • Simpler • Proven to work 31
  • 13 Rules Make fewer HTTP requests Use a CDN Add an Expires header Gzip components Put stylesheets at the top Move scripts to the bottom Avoid CSS expressions Make JS and CSS external Reduce DNS lookups Minify JS Avoid redirects Remove duplicate scripts Configure ETags 32
  • Rule 1: Make fewer HTTP requests (content) • Simply page design • CSS sprites • Combined scripts, combined stylesheets > combining six scripts into one eliminates five HTTP requests • Image maps > images must be contiguous in the page > defining area coordinates – tedious, errors • Inline images (not supported in IE) > data: URL scheme > avoid increasing size of HTML pages ● put inline images in cached stylesheets 33
  • CSS Sprites • Combine background images into 1 single image > size of combined image is less > http://alistapart.com/articles/sprites <span style=" background-image: url('sprites.gif'); background-position: -260px -90px;"> </span> 34
  • Rule 2: Use a CDN (Content Delivery Network) (server) • Implement geographically dispersed content > Distribute your static content before distributing your dynamic content > CDN service provider Akamai Technologies, Mirror Image Internet, or Limelight Networks • Adding your CDN(s) to YSlow > Go to about:config in Firefox > Right-click in the window and choose New and String to create a new string preference > Enter extensions.firebug.yslow.cdnHostnames for the preference name > For the string value, enter the hostname of your CDN, for example, mycdn.com > Do not use quotes. If you have multiple CDN hostnames, separate them with commas 35
  • Rule 3: Add an Expires header (server) • A web server uses the Expires header in the HTTP response to tell the client how long a component can be cached > Browsers use a cache to reduce the number and size of HTTP requests > Avoids unnecessary HTTP requests on subsequent page views > Expires headers most often used with images, but should be used for scripts, stylesheets, and Flash > For static components: implement "Never expire" policy by setting far future Expires header ● Use a far future Expires header you have to change the component’s filename whenever the file changes > For dynamic components: use an appropriate Cache- Control header to help the browser with conditional requests 36
  • How to Implement • May configure on the server conf file • Implement in a servlet or a serlvet filter > resp.setHeader("Expires", cc.getExpires()); > resp.setHeader("Cache-Control", "public,max-age=" + cc.getMaxAge()); 37
  • Rule 4: Gzip components (server) • you can affect users' download times • 90%+ of browsers support compression > Gzip compresses more than deflate > Gzip supported in more browsers • Gzip configuration > HTTP request Accept-Encoding: gzip, deflate > HTTP response Content-Encoding: gzip Vary: Accept-Encoding Need for proxies 38
  • Gzip: not just for HTML • gzip all scripts, stylesheets, XML, JSON but not images, PDF HTML Scripts Stylesheet amazon.com x some aol.com x some some cnn.com ebay.com x froogle.google.com x x x msn.com x deflate deflate myspace.com x x x wikipedia.org x x x yahoo.com x x x youtube.com x some some 39
  • Rule 5: Put stylesheets at the top (css) • Want the browser to display whatever content it has as soon as possible • CSS at the bottom: > prohibits progressive rendering in many browsers, including Internet Explorer > browsers block rendering to avoid having to redraw elements of the page if their styles change. > user is stuck viewing a blank white page • Solution: put stylesheets in HEAD (http spec) > allows the page to render progressively • Avoids Flash of Unstyled Content 40
  • Rule 6: Move scripts to the bottom (javascript) • Scripts block parallel downloads across all hostnames • Scripts block rendering of everything below them in the page • Script defer attribute is not a solution > blocks rendering and downloads in FF > slight blocking in IE 41
  • Rule 7: Avoid CSS expressions (css) • Used to set CSS properties dynamically in IE width: expression( document.body.clientWidth < 600 ?“600px” :“auto” ); • Problem: expressions execute many times > mouse move, key press, resize, scroll, etc. • Alternatives: > one-time expressions: expression overwrites itself <style> P {background-color: expression(altBgcolor(this)); } </style> > event handlers:tie behavior to (fewer) specific events window.onresize = setMinWidth; function setMinWidth() {...} 42
  • Rule 8: Make JS and CSS external (css) • external: more HTTP requests, but cached by browser > generally produces faster pages • inline: HTML document is bigger • variables to decide using external > multiple page views per user per session > many of pages re-use the same scripts and stylesheets > empty vs. primed cache stats • inline: post-onload download, dynamic inlining 43
  • Post-Onload Download • inline JavaScript and CSS in the front page • dynamically download external files after onload window.onload = downloadComponents; function downloadComponents() { var elem = document.createElement("script"); elem.src = "http://.../file1.js"; document.body.appendChild(elem); ... } • Speed up: subsequent pages would reference the external files that already cached in browsers 44
  • Dynamic Inlining • start with post-onload download • set cookie (short lived) after components downloaded • server-side: > if cookie, use external > else, do inline with post-onload download • cookie expiration date is key • speeds up all pages 45
  • Rule 9: Reduce DNS lookups (content) • DNS cost: typically 20-120 ms • block parallel downloads • OS and browser both have DNS caches in addition to User's ISP • Adding DNS Lookups > Increasing parallel downloads is worth an extra DNS lookup • Reducing DNS Lookups > fewer hostnames – 2-4 > keep-alive 46
  • Rule 10: Minify JavaScript (javascript, css) • Minification is the practice of removing unnecessary characters to reduce its size thereby improving load times > all comments are removed, as well as unneeded white space characters (space, newline, and tab) • Two popular tools for minifying JavaScript code > JSMin http://crockford.com/javascript/jsmin > YUI Compressor: can also minify CSS http://developer.yahoo.com/yui/compressor/ • minify is safer than Obfuscator • Minifying both external and inlined scripts and styles minify you gzipscripts, too size by 5% or more even > minifying will still reduce the after inline 47
  • Rule 11: Avoid redirects (content) • 3xx status codes – mostly 301 and 302 HTTP/1.1 301 Moved Permanently Location: http://stevesouders.com/newuri //no “/”, other will redirect • Not cached unless add Expires headers to cache redirects • Redirects slow down the user experience > Inserting a redirect between the user and the HTML document delays everything ● nothing in the page can be rendered ● no components can start being downloaded until the HTML document has arrived 48
  • Rule 12: Remove duplicate scripts (javascript) • hurts performance > unnecessary HTTP requests (IE only) > wasted javascript executions • atypical? > 2 of 10 top sites contain duplicate scripts • team size, # of scripts • Solution: implement a script management module in your templating system > include a script is to use the SCRIPT tag in your HTML page 49
  • Script Insertion Functions <?php function insertScript($jsfile) { if ( alreadyInserted($jsfile) ) { return; } pushInserted($jsfile); if ( hasDependencies($jsfile) ) { $dependencies = getDependencies($jsfile); for ( $i = 0; $i < count($dependencies); $i++ ) { insertScript($dependencies[$i]); } } echo '<script type="text/javascript" src="' . getVersion($jsfile) . '"></script>"; } ?> 50
  • Rule 13: Configure Etags (Entity Tags) (server) • Etags: validate entities, unique identifier returned in response ETag: "10c24bc-4ab-457e1c1f" //md5 hash of content Last-Modified: Tue, 12 Dec 2008 03:03:59 GMT • Used in conditional GET requests GET /i/yahoo.gif HTTP/1.1 Host: us.yimg.com If-Modified-Since: Tue, 12 Dec 2008 03:03:59 GMT If-None-Match: "10c24bc-4ab-457e1c1f" HTTP/1.1 304 Not Modified • If ETag doesn't match, can't send 304 51
  • Next Rules • Split static content across multiple domains • Reduce the size of cookies • Host static content on a different domain • Minify CSS • Avoid IFrames 52
  • Frameworks and Case Study 53
  • Proto Rabbit (on going) • A CSS based templating and Ajax optimization framework • Out of the box uses the BluePrint CSS framework > You can easily substitute for extend the underlying framework • Defined in JSON format > HTML based template that has properties that can be substituted with strings or the contents of a file > specify the underlying HTML template, cache time for the template, scripts, CSS links, properties > may extend any number of other templates with the child properties 54
  • Proto Rabbit (cont.) • Proto Rabbit Engine will sets > correct headers, combines CSS and JavaScript assets (if specified) > gzips those resources as the page is rendered > surrounding final pages are also cached and gzipped for as long as you specify in your template > Different templates may override the cache times of their parents or just inherit them • http://github.com/gmurray/protorabbit/tree/master 55
  • Performance Data • More widgets, more performance gain • Up to 30% reduce in component upload • Your mileage will be different 56
  • Summary and Resources 57
  • Doris Chen Ph.D. Staff Engineer/Technology Evangelist 58