Web Application Performance

Pillars of Web Performance

Network | Compute | Render

Network

Minimize payload size + round-trip times (RTT)

Turn GZIP on the server

Compress served resources

Test GZIP enabled: Open chrome dev tools -> Network -> Select Resource -> Header. Make sure you have Content-Encoding:gzip in the header.

Enable GZIP on Apache

mod_deflate configuration for Apache 2.x:

<IfModule mod_deflate.c>
    SetOutputFilter DEFLATE
    # Don’t compress
    SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
    SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary
    #Dealing with proxy servers
    <IfModule mod_headers.c>
        Header append Vary User-Agent
    </IfModule>
</IfModule>
            

NodeJS + Express

var express = require('express');
var app = express();
app.use(express.compress());

var oneYear = 31557600000;
app.use(express.static(__dirname + '/public', { maxAge: oneYear }));

app.listen(process.env.PORT || 3000);
            

Use a CDN for popular libs

Increase probability of a cache hit

https://developers.google.com/speed/libraries/

Using a CDN - traditional pattern


Using a CDN - with yepnope

Asynchronous conditional resource loader


Using a CDN - with require.js

JavaScript file and module loader

requirejs.config({
paths: {
    jquery: [
        '//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min',
        '../js/lib/jquery'
    ]
}
});

//Later
require(['jquery'], function ($) {
});
        

Images

Over 60% of typical page sizes are images

Use proper image compression

Pick whichever compresses best per image!!!

Tools are available that perform further, lossless compression on JPEG and PNG files, with no effect on image quality

Create SPRITEs to minimize round trips

http://spritegen.website-performance.org

Using SPRITEs


Responsive Design?

One size does not fit all!!!

But, there are no perfect solutions

Images in responsive design


Adaptive Images


Minify JS/CSS/HTML

Downloading smaller files...

Remove duplicate

JS/CSS/HTML/Anything...

Use good modular design practices

Omit the protocol from embedded resources (http:, https:)

<!-- Bad -->
<script src="http://www.mysight.com/js/foo/bar/main.js"></script>
<!-- Better -->
<script src="//www.mysight.com/js/foo/bar/main.js"></script>
<!-- Best (if hostname is the same, use a relative path) -->
<script src="/js/foo/bar/main.js"></script>

Omit optional tags

Not recommended
<!DOCTYPE html>
<html>
    <head>
        <title>Sample</title>
    </head>
    <body>
        <p>Hello World</p>
    </body>
</html>
Recommended
<!DOCTYPE html>
<title>Sample</title>
<p>Hello World</p>

Omit type attribute for styles and scripts

<!-- Bad -->
<link type="text/css" rel="stylesheet" href="/foo/style.css"/>
<script type="text/javascript" src="/foo/main.js"></script>
<!-- Good -->
<link rel="stylesheet" href="/foo/style.css"/>
<script src="/foo/main.js"></script>

Use shorthand CSS where possible

/* Not recommended */
border-top-style: none;
font-family: palatino, georgia, serif;
font-size: 100%;
line-height: 1.6;
padding-bottom: 2em;
padding-left: 1em;
padding-right: 1em;
padding-top: 0;
/* Recommended */
border-top: 0;
font: 100%/1.6 palatino, georgia, serif;
padding: 0 1em 2em;

Write compressible Javascript

Compute

Don't freeze the UI

UI frozen by JS execution


UI allowed to render


My utility for long-running JS code

Defend against stack overflow and UI blocking


Web Workers


Closures are not cheap

Automatic Garbage Collection

Render

Reflow/Repaint

Repaint - also known as redraw - is what happens whenever something is made visible when it was not previously visible, or vice versa, without altering the layout of the document.

-Mark 'Tarquin' Wilton-Jones

When Repaint?

-Nicholas Zakas

Reflow is the process by which the geometry of the layout engine's formatting objects are computed.

-Chris Waterson

When Reflow?

-Nicholas Zakas

Put stylesheets at the top

Put scripts at the bottom

Don't block page rendering

Reduce DOM elements

Fewer bytes to download

Faster browser performance

Minimize Reflows!!!

Touch the live DOM as little as possible

Example 1 - bad performance


Example 1 - better, but still bad


Example 1 - good


Example 1 - even good


Browsers are intelligent

Browser has to give you the most up-to-date value when calling:
Avoid calling these in a loop where css is changed!

Avoid forcing dom reflow

display: none or use DocumentFragments (document.createDocumentFragment())

Example 2 - bad


Example 2 - good


HTMLCollection Objects - ARE LIVE!

document.images

document.forms

getElementsByTagName()

getElementsByClassName()

-Nicholas Zakas

Infinite loop!

var divs = document.getElementsByTagName('div'), div;

for(var i = 0; i < divs.length; i++) {
    div = document.createElement('div');
    divs[i].appendChild(div);
}

HTMLCollection Objects

CSS Selectors - use them efficiently

  1. ID, e.g. #header
  2. Class, e.g. .promo
  3. Type, e.g. div
  4. Adjacent sibling, e.g. h2 + p
  5. Child, e.g. li > ul
  6. Descendant, e.g. ul a
  7. Universal, i.e. *
  8. Attribute, e.g. [type="text"]
  9. Pseudo-classes/-elements, e.g. a:hover
-Steve Souders

Browsers read selectors right-to-left!

Select ALL a tags, then check which ones are under #foo and return those
#foo a {...}
The right-most expression is called the 'key'. The key will affect performance the most.

Don't overqualify selectors

If you have this:
<ul id='nav'>
    <li><a href="#home">Home</a></li>
    <li><a href="#contact">Contact</a></li>
</ul>
Don't do this:
#nav li a {...}
If you can do this:
#nav a {...}
-Harry Roberts

To prevent reflows, specify the width and height of all images, either in the HTML tag, or in CSS

Credits

Rouben Meschian

rmeschian@gmail.com