Ajax Best Practices, Performance and Frameworks
Post on 07-May-2015
1745 Views
Preview:
Transcript
1
Doris Chen Ph.D.Staff Engineer/Technology Evangelist
Ajax Best Practices, Performance and Frameworks
2
Agenda
• Optimization Strategies and Process• Best Practices• Tools• Guidelines and Rules for High Performance Web
Site• Frameworks and Case Study• Summary and Resources
3
Optimization Strategies and Process
4
Four Warnings
1. Speed is not free
2. Avoid premature optimization
3. Don't guess
5
1. A Balancing Act
• Performance• Scalability
• Reliability• End-user Usability• Maintainability• Extensibility• Code Reusability• Portability
6
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.
7
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.
8
Development/Optimization Process
9. Ship it!8. QA
2. Design- Architecture
Perf OK?
3. Coding- Best practicesBest practices-- RulesRules
Yes
No
No
No
Yes
Yes
6. Pref. Tuning- Best practicesBest practices-- Guidelines/RulesGuidelines/Rules-- FrameworksFrameworks- Better algorithms- Creativity
1. Analysis- Use Cases
4. Perf. Tests- Single-User
7. Perf. Tests- Mutiple Users Tests
Perf OK?
Perf OK?
OK?
5. Use Tools- Find bottlenecks
9
Ajax and JavaScript Best Practices
10
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
11
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
12
De-reference unused objects //delete objects
var foo='Delete Me'; //do something with foodelete foo;
// detach listeners (IE / W3C difference)someElement.removeEventListener(type, fn, false); // W3CsomeElement.detachEvent(type,fn); // IE
// remove DOM elementssomeElement.parentNode.removeChild(someElement);
// page onunload window.onunload= function() { /*do something*/}
13
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>
14
• 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 functionfunction 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 changefunction makeAJAXCall(params) { var serviceURL = params.service; ...}
Use Object Literals as Flexible Function Parameters
> Should not be confused with JSON
15
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
16
Example: Load JavaScript On Demand
// Suppose the following is captured as cart.js filefunction Cart () { this.items = [ ];
this.checkout = function() { // checkout logic } }
--------------------------------------------------------------------- // evaluate text from cart.js and create Cart object // secure convert to json using json.org processorjson.parse(rawjsonText);var cart = new Cart();
// add items to the cart cart.checkout();
17
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
18
Example: Good and Bad Practices<style>#Styles</style>
<script type="text/javascript">// 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>
BadBad
GoodGood
19
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
20
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
21
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
22
Coding Efficiency• Common subexpression removal• Loop invariant removal• Most compilers in most programming
languages do these optimizations for you• But not JavaScript
23
Bad and Good Practicesvar 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"; } -----------------------------------------------------------------------------------------------------------------------------------------------
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"; } GoodGood
BadBad
24
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('');
25
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
26
Tools
27
Manual Timing Method
function myFunctionToTest() {
var start = new Date().getTime();
... // body of the function
var totalTime = new Date().getTime() - start;
}
28
Tool: Firebug and YSlow
29
YSlow
• http://developer.yahoo.com/yslow• performance lint tool• scores web pages for each rule• Firefox add-on integrated with Firebug• open source license
30
Guidelines and Rules for High Performance Web Site
31
The Performance Golden Rule80-90% of the end-user response time is spent
on the frontend. Start there.
• Greater potential for improvement• Simpler• Proven to work
32
13 RulesMake fewer HTTP requestsUse a CDNAdd an Expires headerGzip componentsPut stylesheets at the topMove scripts to the bottomAvoid CSS expressionsMake JS and CSS externalReduce DNS lookupsMinify JSAvoid redirectsRemove duplicate scriptsConfigure ETags
33
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
34
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>
35
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
36
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
37
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());
38
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
39
Gzip: not just for HTML• gzip all scripts, stylesheets, XML, JSON but not
images, PDF
somesomexyoutube.comxxxyahoo.comxxxwikipedia.orgxxxmyspace.com
deflatedeflatexmsn.comxxxfroogle.google.com
xebay.comcnn.com
somesomexaol.comxamazon.com
Stylesheetsome
ScriptsHTML
40
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
41
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
42
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 eventswindow.onresize = setMinWidth;function setMinWidth() {...}
43
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
44
Post-Onload Download• inline JavaScript and CSS in the front page• dynamically download external files after
onloadwindow.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
45
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
46
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
47
minify inline scripts, too
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> minifying will still reduce the size by 5% or more even
after you gzip
48
Rule 11: Avoid redirects (content)• 3xx status codes – mostly 301 and 302
HTTP/1.1 301 Moved PermanentlyLocation: 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
49
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
50
Script Insertion Functions<?phpfunction 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>";}?>
51
Rule 13: Configure Etags (Entity Tags) (server)• Etags: validate entities, unique identifier
returned in responseETag: "10c24bc-4ab-457e1c1f" //md5 hash of content
Last-Modified: Tue, 12 Dec 2008 03:03:59 GMT
• Used in conditional GET requestsGET /i/yahoo.gif HTTP/1.1Host: us.yimg.comIf-Modified-Since: Tue, 12 Dec 2008 03:03:59 GMTIf-None-Match: "10c24bc-4ab-457e1c1f"HTTP/1.1 304 Not Modified
• If ETag doesn't match, can't send 304
52
Next Rules• Split static content across multiple domains• Reduce the size of cookies• Host static content on a different domain• Minify CSS• Avoid IFrames
53
Frameworks and Case Study
54
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
55
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
56
Performance Data
• More widgets, more performance gain• Up to 30% reduce in component upload• Your mileage will be different
57
Summary and Resources
58
Doris Chen Ph.D.Staff Engineer/Technology Evangelist
top related