Web Performance:
Perception & Metrics


Progressive WebApps & Lighthouse

Table of Contents

  1. Performance Overview
  2. Visual Metrics: SI & PSI
  3. Progressive WebApps & Lighthouse
  4. SpeedPerception Study

Progressive Web Applications

PWA Features

  • Reliable
  • Fast
  • Engaging

PWA Benefits

  • Can be added to home screen
  • Smaller & faster than native apps
  • Code once. Works cross platform
  • No need for app stores
  • Visible from home screen, trays , app lists

PWA Features

Web technologies
  • HTML
    • Audio / Video
    • Images
  • CSS
  • JavaScript
    • Service Workers
    • JSON Manifest
  • SVG
Progressively Enhanced
  • Works no matter what.
    · in all browsers
    · on all devices
  • Works even better when browser supports PWA features
  • Search Engine Friendly
  • Doesn't require a store
  • Future: identifiable as application due to manifest.
  • Shareable via URL
  • Each page has a URL
  • Page load is fast enough on 3G
  • Works no matter the dimensions of the viewport
  • Content is sized correctly for the viewport
  • Has a <meta name="viewport"> tag with width or initial-scale
  • Look like a native app
  • Built on app shell model
  • Look and feel described in Manifest

Not SPAs, but minimize page refreshes

Works offline

Avoid the Chrome Dinosaur

  • Works when user is online
  • Works when user is offline.
  • Works when user has a shitty connection
  • Useful even when offline

Get resources from network, cache, or combo of both

  • Add to home screen
  • Available fast, even when offline
  • Name, color, and icon defined in manifest
  • No installation friction like store apps
Automatically Updated

Current content displayed when user is online

  • Add to homescreen
  • Push Notifications

What Lighthouse Tests

  • Progressive Web App
  • Performance
  • Best Practices
  • Accessibility

Accessing Lighthouse

More info: https://developers.google.com/web/tools/lighthouse/

Accessibility Checks

  • Elements Use Attributes Correctly
  • Every Image Element Has An alt Attribute
  • ARIA Attributes Follow Best Practices
  • Element aria-* Attributes are Allowed for the Role
  • Element aria-* Attributes Have Valid Values
  • Elements With ARIA Roles Have The Required aria-* Attributes
  • Elements Have Discernable Names
  • Buttons have an accessible name
  • Every Form Element Has A Label
  • Elements Describe Contents Well
  • Color Contrast Is Satisfactory
  • Elements Are Well Structured
  • Page Specifies Valid Language
  • Meta Tags Used Properly

Accessibility Concerns

  • Fixed color contrast on headers
  • Checked the language attribute on the HTML
  • <html lang="en-US">


Best Practices Checks

  • Use HTTP/2 for own resources
  • Avoid Application Cache
  • Avoid WebSQL DB
  • Use HTTPS
  • Use passive listeners to improve scrolling performance
  • Avoid Mutation Events in its own scripts
  • Avoid document.write()
  • Open external anchors using rel="noopener"
  • Avoid requesting geolocation permission on page load
  • Avoid requesting notification permission on page load
  • Avoid deprecated APIs
  • Allow pasting in password input fields

Best Practices Issues

  • Uses HTTPS: 16 insecure requests found
  • Uses HTTP/2 for its own resources: 12 requests were not handled over h2
  • Manifest's short_name won't be truncated when displayed on homescreen

Let's Encrypt

Install Let's Encrypt

$ /scripts/install_lets_encrypt_autossl_provider

Redirect http:// to https:// in .htaccess

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}/%{REQUEST_URI}
Installing LetsEncrypt on cPanel


  • Metrics
    • First meaningful paint
    • First Interactive
    • Consistently Interactive
    • Perceptual Speed Index (target: < 1,250)
    • Estimated Input Latency (target: < 50 ms)
  • Opportunities
    • Reduce render-blocking stylesheets
    • Reduce render-blocking scripts
    • Optimize images
    • Properly size images
    • Offscreen images
  • Diagnostics
    • Critical Request Chain

Critical Network Waterfall

Initial Navigation
 / (www.machinelearningworkshop.com)
  /css?family=Open+Sans%3A400 (fonts.googleapis.com) - 601.7ms, 10.5KB
  /css?family=Raleway:400 (fonts.googleapis.com) - 593.8ms, 10.5KB
  /css/style.css (www.machinelearningworkshop.com) - 577.2ms, 10.5KB
    …v11/QAU...o4.woff2 (fonts.gstatic.com) - 781.2ms, 10.5KB
    …v13/cJZ...20.woff2 (fonts.gstatic.com) - 786.6ms, 10.5KB
  • Get rid of Open Sans
  • Include @font-face inline
  • Move external CSS to internal

Performance (Passed)

  • Reduce render-blocking scripts
  • Properly size images
  • Optimize images
  • Serve images as WebP
  • Enable text compression
  • Avoid enormous network payloads: 159 KB (target: < 1,600 KB)
  • Avoids an excessive DOM size: 156 nodes (target: < 1,500 nodes)
  • User Timing marks and measures

Progressive Web App Requirements


  • Site is served over HTTPS
  • Pages are responsive on tablets & mobile devices
  • The start URL (at least) loads while offline
  • Metadata provided for Add to Home screen
  • First load fast even on 3G
  • Site works cross-browser
  • Page transitions don't feel like they block on the network
  • Each page has a URL
  • Schema.org metadata is provided where appropriate
  • Social metadata is provided where appropriate
  • Canonical URLs are provided when necessary
  • Pages use the History API
  • Content doesn't jump as the page loads
  • Pressing back from a detail page retains scroll position on the previous list page
  • When tapped, inputs aren't obscured by the on screen keyboard
  • Content is easily sharable from standalone or full screen mode
  • Site is responsive across phone, tablet and desktop screen sizes
  • Any app install prompts are not used excessively
  • The Add to Home Screen prompt is intercepted
  • First load very fast even on 3G
  • Site uses cache-first networking
  • Site appropriately informs the user when they're offline
  • Provide context to the user about how notifications will be used
  • UI encouraging users to turn on Push Notifications must not be overly aggressive.
  • Site dims the screen when permission request is showing
  • Push notifications must be timely, precise and relevant
  • Provides controls to enable and disable notifications
  • User is logged in across devices via Credential Management API
  • User can pay easily via native UI from Payment Request API.
  • Reliable
  • Fast
  • Engaging

Progressive Web App

Manual Checks

  • Site works cross-browser
  • Page transitions don't feel like they block on the network
  • Each page has a URL

Passed auto checks

  • Contains content when JavaScript is not available
  • Page load is fast enough on 3G
  • Has a <meta name="viewport"> tag with width or initial-scale
  • Content is sized correctly for the viewport

Progressive Web App Issues


  "short_name": "MLW",
  "name": "Machine Learning Workshop",
  "start_url": "/?source=homescreen", 
  "icons": [
      "src": "icon-sm.png",	
      "type": "image/png",
      "sizes": "48x48"
      "src": "icon-med.png",
      "type": "image/png",
      "sizes": "96x96"
      "src": "icon-lg.png",
      "type": "image/png",
      "sizes": "192x192"
      "src": "icon-huge.png",
      "type": "image/png",
      "sizes": "512x512"
  "background_color": "#FFFFFF",
  "theme_color": "#226DAA", 
  "display": "standalone",  
  "orientation": "portrait",
  "description": "An April Fool's joke that Estelle still finds funny"

Include the manifest

<link rel="manifest" href="manifest.json">

Let's re-run lighthouse

Screenshot of Machine Learning Workshop on an android device

Current Status

Dealing with iOS...

<meta name="apple-mobile-web-app-title" content="MLW">
<meta name="apple-mobile-web-app-capable" content="yes">
<!-- use UI framework for back button if you use this -->
<meta name="apple-mobile-web-status-bar-style" content="black">
<link rel="apple-touch-icon" href="icon_152x152.png"/>
<link rel="apple-touch-startup-image" href="pageloadimg.jpg"/>

... and Windows

<meta name="msapplication-TileImage" content="icon-144x144.png">
<meta name="msapplication-TileColor" content="#226DAA">

PWA Issues

  • Registers a Service Worker
  • Responds with a 200 when offline
  • User can be prompted to Install the Web App
    • Site does not register a Service Worker
    • Manifest start_url is not cached by a Service Worker.
  • Configured for a custom splash screen
    • Manifest does not have icons at least 512px.

Service Worker

Script browser runs in background, separate from a web page, on a separate thread, awakened by events

if ('serviceWorker' in navigator) {


  window.addEventListener('load', function() {

  self.addEventListener('install', function(event) {
    .then(function(cache) {
        return cache.addAll(CACHE_LIST);

self.addEventListener('activate', function(event) {
    console.log("service worker has been activated.");

self.addEventListener('fetch', function(event) {
 console.log('Fetch event for ' + event.request.url);
         caches.match(event.request).then(function(response) {
             if (response) {
                 console.log('Response found in cache:', response);
                 return response;
             } else {
             	console.log('Fetching from network');
             	return fetch(event.request);

Load, Install, Activate, Fetch

Lastly: App Shell Architecture

SpeedPerception launch

  1. SpeedPerception Study Overview
  2. Hypothesis
  3. Results
  4. Learnings
  5. Phase 2
Go launch

Thank you

Speed Perception: Understanding and Measuring Perceived Performance