500 likes | 609 Views
Front-end Perfor m ance. Why Performance?. Users Download time JavaScript execution time Browser memory usage Search Engines Fast-loading pages are ranked higher Server Resources Size on server Bandwidth consumed. Measuring Performance. HTTP Request Waterfall Firebug (Net tab)
E N D
Why Performance? • Users • Download time • JavaScript execution time • Browser memory usage • Search Engines • Fast-loading pages are ranked higher • Server Resources • Size on server • Bandwidth consumed
Measuring Performance • HTTP Request Waterfall • Firebug (Net tab) • Chrome Developer Tools (Network tab) • JavaScript Profiling • Firebug (Console > Profiler) • Chrome Dev Tools (Timeline tab > Record) • On average, over 80% of response time is front-end!
A Game of Bytes and Milliseconds • Consider a high traffic website • Each request has overhead (headers, etc.) in addition to the actual response body • Processing each request also has additional overhead on the server • Now, multiply that overhead by 10 simultaneous hits/second… • You may very well run into bandwidth and memory issues!
A Game of Bytes and Milliseconds • Consider a page with a lot of HTML elements • Need to attach a few event listeners to each What if "a lot" means "hundreds," and more • elements may be added later… • The script may delay/stall during processing, and browser memory consumption will soar
A Game of Bytes and Milliseconds • Consider the load time of a page (Nielsen, 2010) • 0.1 second – Considered "instantaneous" (goal) • 1 second – Limit for the user to feel uninterrupted and maintain flow • 10 second – Limit for the user's attention span • Users and search engines prefer fast sites to slower ones!
Efficient Markup • Minimize markup • Minimize additional HTTP requests • No empty src/href properties • Minimize DNS lookups • CSS at the top of the page • JavaScript at the bottom
Minimizing Markup • Each character increases the size of the response body • Each DOM element takes CSS/JavaScript longer to process • Best Practice: Don't use two tags when one will do
No Empty src/href Properties • Some browsers will still attempt to look for a file when src/href is empty • Wastes client resources • Burdens server with a request that will never resolve properly • Best Practice: No empty src attributes, use '#' for href placeholders
Minimize Additional Requests • Each resource requested on the page will trigger an HTTP request to retrieve it • Images • CSS • JavaScript • Video/Audio • ... • Each request has additional overhead (headers, etc.) • Browsers are recommended to download only two components per hostname at a time
Minimize DNS lookups • The browser has to translate a hostname to an IP address if it isn't locally cached already • DNS queries introduce extra overhead… • ...but separate hostnames allow for more parallel downloads • Best Practice: Strike a balance between DNS lookups and ability to support parallel downloads (2-4 recommended)
CSS at the top of the page • Allows the page to be rendered progressively as other components load • Best Practice: Include CSS in the head
JavaScript at the bottom • JavaScript downloads will block all other parallel downloads • Even on other hostnames! • Best Practice: Include JavaScript at the bottom of the page whenever possible
Efficient Servers • EnableGZipcompression • ConfigureETags • AddExpiresheaders
Enable GZip Compression • The size of static content served quickly adds up • Best Practice: Turn on GZip compression for plain text, XML, and HTML files via mod_deflate • Some browsers don't handle compression for other types very well, if at all http://httpd.apache.org/docs/2.0/mod/mod_deflate.h tml#recommended
Configure ETags • ETags are headers used to determine whether a cached resource is the same as the one on the server • Problem: The means to generate ETags are server-specific • When serving content from more than one server, false-negatives are likely to occur • Best Practice: Disable ETags unless you specifically need them • FileETag none
Add Expires Headers • Resources can be cached by the browser depending on the headers received with the response • Expires indicates when to throw away the cache and fetch a new version • If a component is cached, no attempt will be made to fetch it
Add Expires Headers • Best practice: Use mod_headers and mod_expires to set far-future Expires headers for static content • ExpiresActive On • ExpiresDefault "access plus 600 seconds" • ExpiresByType text/html "access plus 10 years”
Words of Caution... • The filename of the component must change when it is updated in order to use this technique! • This technique shouldn't be used for dynamic content • We'll discuss why later in the semester
Efficient Media • UseCSSinsteadofimages • Usetheproperfileformat • UseImageSprites • UseaContentDeliveryNetwork(CDN)
Use CSS Instead of Images • Images almost always introduce more overhead than CSS • Often, CSS can be used creatively to achieve the same effects • Best Practice: Design without these effects, then apply progressive enhancement to duplicate them in CSS • Example: Gradients
Use Proper File Formats • The file size of an image may depend a great deal on the format in which it was saved • Best Practice: Save your images in file format that produces the smallest size with an acceptable level of quality
Use Image Sprites • Many small images incur HTTP request overhead for each • Small images (sprites) can be combined into one image file to save request overhead
Use Image Sprites • Create a sprite map for any small images. • Apply the sprite map as a background image to any element that would display a single sprite on the map • Give the element an explicit width and height • Use background-position to slide the correct sprite into place
Use Image Sprites • Best Practice: Use sprite maps whenever a collection of small images is used, especially if they change state • Fewer requests to make • The entire sprite map is cached, even if not all of the sprites are used on the same page • Sprite maps are often site-wide for this reason
<code> • Usethesprites_poorexampleasastarting point • Converttheexampletouseimagesprites(the spritemapisapple_spritesintheimgs directory)
Use a Content Delivery Network • Client proximity to server affects round-trip time (RTT) • Most of content downloaded is static • Content Delivery Networks (CDNs) are geographically distributed networks that serve the same static content from the closest location • Best Practice: Use a Content Delivery Network to serve static content • Using a CDN can be costly – for this course, just know that the option exists
Efficient CSS • Write efficient selectors • Aggregate CSS files • Minify CSS • Don't Use CSS Expressions
Write Efficienct Selectors • Some selectors are more efficient than others • Also applies to jQuery selectors!
Most to Least Efficient Selectors • IDs (#heading) • Classes (.new) • Elements (h1) • Adjacent Sibling (h1 + h2) • Direct Child (ul > li) • Descendant (nav li) • Universal (*) • Attribute Selectors (input[type="text"]) • Pseudo-selectors (a:hover)
Write Efficient Selectors • Best Practice: Choose the most efficient selector for the job, and inherit as much as possible • Rule of thumb: be as specific as you can be using the fewest selectors • #header instead of h1#header • .input-text instead of input[type="text']
Aggregate CSS files • Each style sheet loaded introduces request overhead • Best Practice: Combine related style sheets into a single file wherever possible
Minify CSS • CSS can be reduced to only the characters necessary to style the page as intended • Result is called minified CSS • Best Practice: Minify CSS to reduce overall file size. • http://www.minifycss.com/
Don't Use CSS Expressions • Only supported in IE • Allows for embedding JavaScript in CSS through the expression() property • Best Practice: Don't. They're evaluated almost any time an event would fire! • Scrolling • Mouseover • Resize • etc.
Efficient JavaScript • Write efficient jQuery selectors • Cache expensive operations • Aggregate & Minify JavaScript • Use CSS instead • Use event delegation
Cache Expensive Operations • JavaScript is heavy in iteration and recursion, so the effect of redundant function calls are often multiplied • Best Practice: When calling the same function to get the same result multiple times, consider saving it to a variable first
Aggregate JavaScript • Each script loaded introduces request overhead • Best Practice: Combine related scripts into a single file wherever possible
Minify JavaScript • JavaScript can be reduced to only the characters necessary to execute as intended • This result is minified JavaScript • Best Practice: Create a minified version of all JavaScript developed to reduce file size • jQuery and many other libraries do this • http://jscompress.com/
Use CSS Instead • For visual effects, CSS is more efficient than JavaScript • Best Practice: Apply CSS according to the principles of progressive enhancement
Use Event Delegation • Traditional event listeners have two main drawbacks in advanced JS • They need to be attached to elements not in the initial DOM • Adding event listeners for each element is O(n) • Best Practice: Listen for events on child elements from a parent element, and act on the actual target • O(1) instead of O(n) thanks to event bubbling • jQuery .on() does this for you
Event Delegation • Given: A set of child elements, sharing a common event to respond to • Add an event listener for that event to a common parent • In the event listener, check for e.target OR e.srcElement (IE) to get the element originally triggering the event • Act on the triggering element as normal
Stopping Event Bubbling • May need to stop the event from bubbling further, so it doesn't interfere with other handlers • e.cancelBubble = true; // IE • if (e.stopPropagation) { e.stopPropagation(); } // others
<code> • Grab the Lab 4 source from the Examples • Using event delegation without jQuery, for all elements in the body, alert the element that you've clicked on • Do the same using .on() in jQuery
Efficient AJAX • Use GET instead of POST wherever possible • Use an appropriate polling method for your application
Use GET instead of POST • POST requires sending the message body separately, carries additional overhead • Best Practice: Use POST only when it is appropriate to do so, otherwise use GET
Use Appropriate Polling Methods • Traditional Polling: Check a resource for updates via AJAX at set intervals • Can also adjust intervals based on the situation • Long Polling: Make a request, and wait patiently for a response • If an update is ready, the server will send the response • If enough time passes, the server will ask the client to establish a new connection
Traditional Polling • Advantage • Data is being fetched at regular intervals • Disadvantage • High server traffic even if there are no updates
Long Polling • Advantage • Simulates the server pushing data to the client • Disadvantage • May need to be throttled if requests/responses are near-immediate, as requests are made one right after the other • Ties up server resources on servers (like Apache) that are one-thread-per-request, should be handled by a separate server
AJAX Polling Methods • Best Practice: Use the right polling method for your application. • Traditional Polling for when the data is frequently updated, and you can tolerate slight delays • Long Polling for when the data is infrequently updated, but you want updates immediately
<footer> • Nextup:UserExperience • Lab#6:Front-endOptimization