Speed is a Feature

Performance on the Mobile Web

Eric Phetteplace @phette23

Chesapeake College


Just attackclone the grit repo pushmerge, then rubygem the lymphnode js shawarma module – and presto!

HTML9 Responsive Boilerstrap JS

Speed is Important

spinning loading wheel



What's More...



Bad Trend

It's Simple

⇩ Reduce HTTP Requests

⇩ Send Fewer Bytes

Honey, I Shrunk the
Page Load Time!

Server Configuration

Don't be scared.



<IfModule mod_deflate.c>
  <IfModule mod_setenvif.c>
    <IfModule mod_headers.c>
    SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
    RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
  <IfModule mod_filter.c>
    AddOutputFilterByType DEFLATE application/javascript \
                                  text/css \


  <httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
    <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll"/>
      <add mimeType="text/✱" enabled="true"/>
      <add mimeType="message/✱" enabled="true"/>
      <add mimeType="application/javascript" enabled="true"/>
      <add mimeType="✱/✱" enabled="false"/>
      <add mimeType="text/✱" enabled="true"/>
      <add mimeType="message/✱" enabled="true"/>
      <add mimeType="application/javascript" enabled="true"/>
      <add mimeType="✱/✱" enabled="false"/>
  <urlCompression doStaticCompression="true" doDynamicCompression="true"/>

See this MSDN blog post or H5BP again.


# These are pretty far-future expires headers.
# Assumes filename-based versioning
<IfModule mod_expires.c>
  ExpiresActive on
# Perhaps better to whitelist expires rules? Perhaps.
  ExpiresDefault                          "access plus 1 month"
# Your document html
  ExpiresByType text/html                 "access plus 0 seconds"
# Media: images, video, audio
  ExpiresByType image/png                 "access plus 1 month"
  ExpiresByType image/jpeg                "access plus 1 month"
# CSS & JavaScript
  ExpiresByType text/css                  "access plus 1 year"
  ExpiresByType application/javascript    "access plus 1 year"

Use CDNs

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>


The Kitchen Sink

Linux Apache only?

HTTP Requests

Reduce HTTP Requests

 Download both  

Concatenate Files

Goal: a single CSS file, a single JS file.

<script type="text/javascript" src="/pm/plugins/system/mtupgrade/mootools-uncompressed.js"></script>
<script type="text/javascript" src="/pm/media/system/js/caption.js"></script>
<link rel="stylesheet" href="system/css/system.css" type="text/css" />
<link rel="stylesheet" href="system/css/general.css" type="text/css" />
<link rel="stylesheet" href="ja_purity/css/template.css" type="text/css" />
<style type="text/css" media="screen">@import "anllosa/standard_upv.css";</style>
<script language="javascript" type="text/javascript" src="ja_purity/js/ja.script.js"></script>
<script language="javascript" type="text/javascript" src="ja_purity/js/ja.rightcol.js"></script>
<link rel="stylesheet" href="ja_purity/css/menu.css" type="text/css" />
<link rel="stylesheet" href="ja_purity/styles/background/lighter/style.css" type="text/css" />
<link rel="stylesheet" href="ja_purity/styles/elements/black/style.css" type="text/css" />

4 scripts, 6 style sheets

Image Sprites

1 HTTP Request, Many Icons

SpriteMe.org makes this easy.

Facebook's sprite

Be Antisocial

Sharing buttons are the lawn gnomes of the Internet.™

7 requests, 48.72kbs, ≈550-700ms onload



2 requests, 5.84kbs, ≈250-350ms onload

Inline Everything

.inline-img { background: url(data:image/jpeg;base64,wTfD0esALlth1Sgi1313ERishM34n...); }


Code Minification

HTML Compression; not just for JavaScript!

Source Order

Scripts at the bottom, please.

<!doctype html public "¿">
		<title>Teh Awesome Sauce</title>
		<link rel="stylesheet" href="css/style.css">
		<script src="js/logic.js"></script>
		<h1>Teh Awesome Sauce</h1>
		<p>Lorem ipsum dolor sit amet...</p>

Defer JS Execution

<script id="lazy">/*
alert("Hello, edUI!");
function lazyLoad() {
	var lazyEl = document.getElementById('lazy');
	var lazyElBody = lazyEl.innerHTML;
	var len = lazyElBody.length;
	var jsCode = lazyElBody.substring(2, len - 2);

Touch Events


<a href="//www.example.com/">Link</a>


var links = document.getElementsByTagName( 'a' );
var numLinks = links.length;
for ( var i = 0; i < numLinks; i++ ) {
	links[ i ].addEventListener( "touchstart", goNow, false);
function goNow( event ) {
	location = event.currentTarget.href;

jQuery Mobile has touch & virtual mouse events built in.

Application Cache


<!doctype html public "☃">
<html manifest="offline.appcache">


#version 1.0 9-25-2012

Appcache Douchebag

AJAX Include

Take Only What You Need

jQuery 1.8 offers modules:

  • AJAX
  • CSS
  • Deprecated
  • Dimensions
  • Effects
  • Offsets

jQuery Mobile has a Download Builder in alpha.

Slim Content

Deliver what users need & will use.


This one's tough.


OptiPNG & jpegtran, ImageOptim

Responsive Images

I have no idea what I'm doing. spreadsheet

Don't Use Images

Best Website Evar

Art party kale chips aliquip scenester. Whatever put a bird on it minim keffiyeh chillwave vinyl, letterpress nesciunt carles exercitation butcher freegan. Tofu brooklyn veniam next level small batch ullamco, nulla proident pickled swag fingerstache ex 3 wolf moon. Ad readymade kale chips twee quis DIY. 3 wolf moon exercitation direct trade mustache wayfarers assumenda. Before they sold out echo park photo booth godard. Butcher artisan aliquip, messenger bag pork belly 8-bit eiusmod vice incididunt umami gastropub portland food truck voluptate. Small batch labore chambray sapiente aesthetic, gastropub ea. Hoodie next level cardigan veniam commodo, carles synth narwhal eu echo park occupy accusamus thundercats. Viral sint swag dreamcatcher occaecat. Cillum semiotics sapiente, sint aliqua mcsweeney's enim portland before they sold out assumenda pariatur keffiyeh aesthetic pop-up raw denim. Chambray pitchfork vinyl brooklyn nesciunt, squid est post-ironic sed excepteur VHS lo-fi banksy dreamcatcher lomo. Cardigan anim ea portland shoreditch cupidatat. Est fixie qui small batch, gluten-free kogi swag mollit. Consectetur semiotics organic quinoa, sunt duis gentrify do vegan veniam. Nesciunt qui shoreditch occaecat put a bird on it. Jean shorts skateboard DIY, next level salvia portland cosby sweater occupy irure wes anderson dreamcatcher mustache minim. Cred nostrud whatever, et mcsweeney's voluptate locavore sustainable swag. Mlkshk fixie velit et. Sint ethical kale chips scenester, excepteur in fap banksy vero ex gluten-free. Butcher seitan labore reprehenderit. VHS consequat officia scenester authentic, twee aliqua. Officia qui delectus keytar, trust fund blog mcsweeney's portland put a bird on it wolf ennui marfa locavore. Mustache sustainable terry richardson trust fund laborum, williamsburg aliqua organic. Authentic placeat irony beard, marfa semiotics american apparel readymade labore. Brunch gentrify elit mcsweeney's officia salvia. Bespoke kogi sapiente fixie gluten-free aesthetic. Street art aesthetic nulla consequat, keytar commodo fugiat placeat odd future tempor. Cardigan bicycle rights odio enim, odd future letterpress ennui scenester kale chips jean shorts nesciunt typewriter occupy freegan. Whatever consectetur pour-over farm-to-table, lomo marfa deserunt consequat mcsweeney's vero culpa. Butcher ethnic raw denim wayfarers consequat. Terry richardson dreamcatcher chillwave vinyl ullamco duis farm-to-table marfa eiusmod etsy consectetur sriracha, tumblr salvia. Master cleanse etsy officia vegan seitan. Pop-up deserunt carles marfa, keffiyeh banh mi lo-fi occupy officia brooklyn. Sed keffiyeh vice, tattooed aesthetic esse letterpress etsy swag skateboard cliche deserunt occaecat thundercats. Incididunt reprehenderit assumenda helvetica, art party trust fund you probably haven't heard of them letterpress cardigan aliquip yr mumblecore non four loko. Dolor assumenda jean shorts nihil typewriter scenester, pitchfork messenger bag cred iphone consequat letterpress. Lo-fi proident vinyl, chambray dolor before they sold out post-ironic consequat sustainable. American apparel gluten-free id irony, locavore artisan occupy anim. 8-bit mumblecore kogi chillwave dreamcatcher sartorial. Small batch selvage etsy raw denim bushwick. You probably haven't heard of them semiotics single-origin coffee minim bespoke ad est mumblecore, velit odio cupidatat ex cred.

<img> Alternatives

CSS RSS - border-radius & pseudo-elements

SVG - IE9+

Icon Fonts - IcoMoon

Unicode Characters - Mobile Web Best Practices


Build Scripts

	_   .--------------------------.
      _|o|_ |    Welcome to Yeoman,    |
       |_|  |   ladies and gentlemen!  |
     / \Y/ \ o_________________________|
    ||  :  |//
    o/ --- \
      _\ /_

Lints, Compiles, Concatenates, Minifies, Compresses, & Generates Cache Manifest


Mobile Testing I

MobiTest or WebPageTest

Mobile Testing II

Google Analytics

Site Speed

Page Avg. Load Time Pageviews Page Load Sample
/library/m/ 1.76s 874 23
/library/m/index.html 1.01s 546 6
/library/m/p/ 0.00s 179 0
/library/m/chat.html 2.74s 57 1



Me: @phette23

The presentation: phette.net/m

The slide deck: reveal.js by Hakim El Hattab

Resources: diigo.com/user/phette23/mobileperf