Front-end Performance. Why Performance? Users Download time JavaScript execution time Browser memory...

Preview:

Citation preview

Front-end Performance

Why Performance?Users

Download time JavaScript execution time Browser memory usage

Search EnginesFast-loading pages are ranked higher

Server ResourcesSize on server Bandwidth consumed

Measuring PerformanceHTTP Request Waterfall

Firebug (Net tab)Chrome Developer Tools (Network tab)

JavaScript ProfilingFirebug (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 websiteEach request has overhead (headers, etc.) in addition

to the actual response bodyProcessing each request also has additional overhead

on the serverNow, 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 elementsNeed to attach a few event listeners to each What

if "a lot" means "hundreds," and moreelements 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 flow10 second – Limit for the user's attention span

Users and search engines prefer fast sites to slower ones!

Efficient MarkupMinimize 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 MarkupEach 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 emptyWastes client resourcesBurdens 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 ImagesCSS 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 lookupsThe 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 pageAllows the page to be rendered progressively as

other components load

Best Practice: Include CSS in the head

JavaScript at the bottomJavaScript downloads will block all other parallel

downloadsEven on other hostnames!

Best Practice: Include JavaScript at the bottom of the page whenever possible

Efficient ServersEnable GZip compression

Configure ETags

Add Expires headers

Enable GZip CompressionThe size of static content served quickly adds up

Best Practice: Turn on GZip compression for plain text, XML, and HTML files via mod_deflateSome 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 ETagsETags 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-specificWhen 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 HeadersResources 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 HeadersBest 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 contentWe'll discuss why later in the semester

Efficient MediaUse CSS instead of images

Use the proper file format

Use Image Sprites

Use a Content Delivery Network (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 CSSExample: Gradients

Use Proper File FormatsThe 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 SpritesMany small images incur HTTP request overhead

for each

Small images (sprites) can be combined into one image file to save request overhead

Use Image SpritesCreate 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 SpritesBest 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 pageSprite maps are often site-wide for this reason

<code>Use the sprites_poor example as a starting point

Convert the example to use image sprites (the sprite map is apple_sprites in the imgs 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 contentUsing a CDN can be costly – for this course, just

know that the option exists

Efficient CSSWrite efficient selectors

Aggregate CSS files

Minify CSS

Don't Use CSS Expressions

Write Efficienct SelectorsSome 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 SelectorsBest 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 filesEach style sheet loaded introduces request

overhead

Best Practice: Combine related style sheets into a single file wherever possible

Minify CSSCSS 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 JavaScriptWrite 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 JavaScriptEach script loaded introduces request overhead

Best Practice: Combine related scripts into a single file wherever possible

Minify JavaScriptJavaScript 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 thishttp://jscompress.com/

Use CSS InsteadFor visual effects, CSS is more efficient than

JavaScript

Best Practice: Apply CSS according to the principles of progressive enhancement

Use Event DelegationTraditional event listeners have two main

drawbacks in advanced JSThey need to be attached to elements not in the

initial DOMAdding 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 targetO(1) instead of O(n) thanks to event bubbling jQuery .on() does this for you

Event DelegationGiven: 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 BubblingMay 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 AJAXUse GET instead of POST wherever possible

Use an appropriate polling method for your application

Use GET instead of POSTPOST 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 intervalsCan 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 PollingAdvantage

Data is being fetched at regular intervals

DisadvantageHigh server traffic even if there are no updates

Long PollingAdvantage

Simulates the server pushing data to the client

DisadvantageMay 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 MethodsBest Practice: Use the right polling method for

your application.Traditional Polling for when the data is frequently

updated, and you can tolerate slight delaysLong Polling for when the data is infrequently

updated, but you want updates immediately

<footer>Next up: User Experience

Lab #6: Front-end Optimization

Recommended