developing high performance web apps
DESCRIPTION
An overview of some ways developers can improve the performance of their web applications.TRANSCRIPT
PERFOMANCE MATTERS
DEVELOPING HIGH PERFORMANCE WEB
APPS
Timothy FisherCompuware
September 15, 2010
WHO AM I?
Timothy FisherTechnical Consultant (Eagle)Compuware
@tfisher
www.timothyfisher.com
AGENDA
•Why Front-end Performance Matters
•Optimize Page Load
•Responsive Interfaces
•Loading and Executing JavaScript
AGENDA
•DOM Scripting
•Tools
•Gomez and Front-End Performance
•Questions
An overview to spark thought and further investigation
Why Front-end Performance matters
According to Yahoo:
“80% of end-user response time is spent on the front-end”
According to Steve Souders (Google performance guru):
“80-90% of end-user response time is spent on the front-end”
Syndicated Content Services
CDN’s Ads
Integration is happening on the client-side
OPTIMIZE PAGE LOAD
PAGE LOAD TIME IS IMPORTANT
Google: +500 ms → -20% traffic
Yahoo: +400 ms → -5-9% full-page traffic
Amazon: +100 ms → -1% sales
Page load time is critical to the success of a web site/app
Small performance flucutations affect traffic and sales!!!
BEST PRACTICES
• Minimize HTTP Requests
• combine javascript and css into less number of files
• consider sprites for combining images
• Use a Content Delivery Network (CDN)
• static content delivered by fast distributed network with low latency
BEST PRACTICES
• Make Pages Cacheable
• use appropriate header tags
• Use GZIP Page Compression
• all modern browsers support GZIP compression
BEST PRACTICES
• Place Stylesheets at the Top
• browser needs style info first to avoid repaints/reflows later
• Place Scripts at the Bottom
• allow page content to be rendered first
BEST PRACTICES
• Minify JavaScript and CSS
• save bandwidth / download time
• lots of tools to automate this for you
• Post/pre Load Components
• consider how you are loading content and scripts
BEST PRACTICES
• Split Components Across Domains
• enables browser to load more stuff in parallel
• Optimize Images
• avoid high-res images unless it is intentional
• don’t let the browser scale your images
RESPONSIVE INTERFACES
A SINGLE BROWSER THREAD
SINGLE THREAD IMPLICATIONS
• Single UI Thread for both UI updates and JavaScript execution
• only one of these can happen at a time!
Page downloading and rendering must stop and wait for scripts to be downloaded and executed
“0.1 second is about the limit for having the user feel that a system is reacting instantaneoulsy”
- Jakob Nielsen, Usability Expert
Translation: No single JavaScript should execute for more than 100 mS to ensure a responsive UI.
LOADING & EXECUTINGJAVASCRIPT
WHY JAVASCRIPT?
• Poorly written JavaScript is the most common reason for slow client-side performance
• Loading
• Parsing
• Execution
TYPICAL JAVASCRIPT PLACEMENT
<html> <head> <link href=”style.css” rel=”stylesheet” type=”text/css”/>
<script src=”myscript.js” type=”text/javascript”></script> <script src=”myscript.js” type=”text/javascript”></script>
<script> function hello_world() { alert(‘hello world’); } var complex_data = // some complex calculation // </script> </head>
<body> ... </body></html>
BETTER JAVASCRIPT PLACEMENT
<html> <head> <link href=”style.css” rel=”stylesheet” type=”text/css”/> </head>
<body> ...
<script src=”myscript.js” type=”text/javascript”></script> <script src=”myscript.js” type=”text/javascript”></script> <script> function hello_world() { alert(‘hello world’); } var complex_data = // some complex calculation </script> </body></html>
COMBINE JAVASCRIPT FILES
• Each script request requires HTTP performance overhead
• Minimize overhead by combining scripts
file1.js file2.js file3.jsfile.js
Browser Browser
=>
MINIFY JAVASCRIPT
• Removes all unecessary space/comments from your JS files
• Replace variables with short names
• Easy to do at built-time with a tool
• Checkout YUI Compressor, Closure Compiler...
Avoid manual code-size optimization!
NON-BLOCKING LOADS
• Add JavaScript to a page in a way that does not block the browser thread
‣Dynamic Script Elements
‣Script Injection
DYNAMIC SCRIPT ELEMENTS
• JavaScript is downloaded and executed without blocking other page processes.
var script = document.createElement(‘script’);script.type = “text/javascript”; script.src = “file1.js”;document.getElementsByTagName(“head”)[0].appendChild(script);
SCRIPT INJECTION
• Use Ajax to get script• Can control when script is parsed/executed• JavaScript must be served from same domain
var xhr = XMLHttpRequest();xhr.open(“get”, “file.js”, true);xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) { var script = document.createElement(“script”); script.type = “text/javascript”; script.text = xhr.responseText; document.body.appendChild(script); } }};xhr.send(null);
RECOMMENDED NONBLOCKING LOAD
• Include the code necessary to dynamically the the rest of the JS required for page init
<script type="text/javascript" src="loader.js"></script> <script type="text/javascript"> loadScript("the-rest.js", function(){ Application.init(); });</script>
Optionally include the loadScript function directly in the page
REAL WORLD USE
• This technique is used by many JavaScript libraries including YUI and Dojo.
YUI().use("dom", function(Y){ Y.DOM.addClass(document.body, "loaded");});
<script type="text/javascript" src="http://yui.yahooapis.com/combo?3.0.0/build/yui/yui-min.js"></script>
Dynamically loads the DOM utility and calls ‘loaded’ functionwhen loading is complete.
SUMMARY
• Browser UI and JS share a single thread
• Code execution blocks other browser processes such as UI painting
• Put script tags at the bottom of page
• Load as much JS dynamically as possible
•Minimize and compress your JS
DOM SCRIPTING
DOCUMENT OBJECT MODEL
•Document Object Model (DOM) is a language independent API for working with HTML and XML
•DOM Scripting is expensive and a common cause of performance problems
DOM/JS ISOLATION
• DOM and JavaScript implementations are independent of each other in all major browsers
• This causes overhead performance costs as these two pieces of code must interface
JavaScript
DOM
Minimize how many times you cross this bridge
BAD DOM SCRIPTING
function innerHTMLLoop() { for (var count = 0; count < 1500; count++) { document.getElementById('here').innerHTML += 'a'; }}
function innerHTMLLoop2() { var content = ''; for (var count = 0; count < 1500; count++) { content += 'a'; } document.getElementById('here').innerHTML += content;}
Bad (we cross the bridge 1500 times!)
Good (we cross the bridge 1 time)
REPAINTS AND REFLOWS
A reflow occurs whenever you change the geometry of an element that is displayed on the page.
A repaint occurs whenever you change the content of an element that is displayed on the screen.
These are both expensive operations in terms of performance!
AVOIDING REPAINTS/REFLOWS
var el = document.getElementById('mydiv'); el.style.borderLeft = '1px'; el.style.borderRight = '2px'; el.style.padding = '5px';
var el = document.getElementById('mydiv'); el.style.cssText = 'border-left: 1px; border-right: 2px; padding: 5px;';
var el = document.getElementById('mydiv'); el.className = 'active';
This will potentially cause 3 repaints/reflows...
Better... 1 repaint/reflow
or...
TOOLS
TOOLS ARE YOUR FRIEND
The right tools can help a developer identify and fix performance problems related to client-side behaviour.
ProfilingTiming functions and operations during script execution
Network AnalysisExamine loading of images, stylesheets, and scripts and their effect on page load and rendering
FIREBUG
•Firefox plugin
•Debug JavaScript
•View page load waterfall:
PAGE SPEED
•Extension to Firebug from Google•Provides tips for improving page performance
Y-SLOW
•Extension to Firebug from Yahoo•tips for improving page performance
DYNATRACE AJAX EDITION
•extension for IE, coming soon for Firefox•deeper client-side tracing than the firebug extensions
SPEED TRACER
•performance extension for Google Chrome•similar features to Dynatrace Ajax
YUI PROFILER
•profile JavaScript performance•developer must insert JS code
MORE TOOLS...
Internet Explorer Developer Tools
Safari Web Inspector
Chrome Developer Tools
Lots of developer tools to debug performance!
GOMEZ AND FRONT-ENDPERFORMANCE
GOMEZ
Gomez is the web performance division of Compuware
•Active Monitoringsynthetic tests using a dedicated node and a Gomez controlled browser
•Actual Monitoringtests the actual end-user experience by transmitting data while users are browsing to a Gomez server
ACTIVE
ACTUAL
GOMEZ ACTIVE
• Synthetic tests
• Uses nodes in Gomez network to perform web application testing.
• Today pure client-side metrics are not collected
GOMEZ ACTUAL
• Real User Monitoring (RUM)
• JavaScript ‘tags’ inserted into web pages.
• Tags report performance metrics to Gomez server
• Page and object load performance metrics
EXTENDING ACTIVE/ACTUAL
•Desire to collect more client-side metrics
•JavaScript - load, parse, execution timing•CSS - load, parse timing•full Waterfall page load metrics
•Attribute client-side performance to specific sources (i.e. javascript library from vendor abc is the source of your slow performance)
•Expose full end-to-end performance
RESOURCES• Yahoo Exceptional Performance
http://developer.yahoo.com/performance/
• Google Web Performancehttp://code.google.com/speed
• JavaScript: The Good Parts by Douglas Crockford
• High Performance JavaScript by Nicholas Zakas
• Even Faster Websites by Steve Souders
• Steve Souders Sitehttp://www.stevesouders.com
• John Resig’s Bloghttp://www.ejohn.org
QUESTIONS