500 likes | 621 Views
Discover essential techniques for optimizing front-end performance, ensuring faster loading times and improved user experience. Explore the impact of JavaScript execution, browser memory usage, and server response times on overall site efficiency. Learn the importance of minimizing markup, reducing HTTP requests, and strategically placing CSS and JavaScript for optimal rendering. Use performance measuring tools like Chrome Developer Tools and Firebug to identify bottlenecks. Adopt best practices that not only please users but also favor better search engine rankings.
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