Slides about Slides

  • 📱
  • 🐌
  • 💰
  • 🖥

Hey! This Sounds Familiar

You're Right!

First Contentful Paint and Time to Consistently Interactive

First Contentful Paint trend from httparchive.org showing a 10.4% increase in the median to 5.3 seconds for mobile from December 15, 2016 to August 1, 2018 and a 32.1% decrease in the median to 1.9 seconds for desktop Time to Consistently Interactive trend from httparchive.org showing a 20.7% year-over-year increase in median to 14.6 seconds from June 1, 2017 to June 1, 2018

What can we do to reverse this trend?

🐼 Let's Talk About Slides!

😜

🏞 Core Experiences

My process starts not at features or tools or techniques, but at the
user's problem I'm trying to solve

🌉 🏞

Design a Presentation Framework Better Way to Give Web-Based Presentations

The problems we're trying to solve form our core experiences, from which we can ideate on solutions, incorporating one or more of them together to solve our user's needs

🏗 Building from the Ground Up

As we start to ideate on our core experiences, I like to grade the solutions we come up with based on the core principles of Progressive Enhancement:

  • What can we do with just HTML
  • What can we do with just HTML and CSS
  • Under what circumstances do we want to enhance our experience with JavaScript?
  • What JavaScript do we need to enhance this experience?
  • What breaks when we introduce CSS? JavaScript? Are we OK with that? Can we mitigate it?

Question:

What are the grades for a Slide Deck?

Grade X
Semantically marked up, HTML and CSS only linear "article" display. Display speaker notes in-line with content.
Requirements: HTML, CSS
Grade B
Keep semantic markup, change CSS to lay out as individual slides, only display one slide at a time, advance slides on event. Hide speaker notes.
Requirements: Above, plus JavaScript, some form of JavaScript powered State
Grade A
Provide remote control of slides and speaker-focused view (including speaker notes).
Requirements: Above, plus Presentation API

🌴 The Web's Roots

There are three groups of things I think about when writing HTML:

  • Tag semantics
  • Accessibility
  • Microdata for SEO and semantic sharing

What does this look like for our Slide Deck?

<article class="_stage">
  <header class="_stage--group">
    <div class="_stage--slide">
      <!-- Talk Title Goes Here -->
    </div>
  </header>
  <section class="_stage--group">
    <header class="_stage--slide">
      <!-- Section Heading Goes Here -->
    </header>
    <div class="_stage--slide">
      <!-- Content Goes Here -->
      <aside class="_stage--notes">
        <!-- Notes Go Here -->
      </aside>
    </div>
  </section>
<article>

🌭 Cutting the Mustard

Cutting the Mustard is a Progressive Enhancement technique used to ensure a baseline level of functionality for an enhanced experience

Let's answer what JavaScript Features or APIS do we want for our baseline?

  • What do we need for our enhancement?
  • What could reduce the cost of maintenance
  • What would drastically cut down on the custom code we need to write

Cutting the Mustard for ES2015+ Browsers

JavaScript Modules to the rescue!

<script type="module" defer src="./mustard.js"></script>
<script nomodule defer src="./no-mustard.js"></script>

<!-- Can be done inline too -->

<script type="module">
  import mustard from './mustard.js';
</script>

<script nomodule type="text/javascript">
  console.log('No Mustard!');
</script>

👹 Taming the State Beast

State is hard

State Managers keep all state in a single place
and allow updates to be centrally published and subscribed to

Client-side hydration tricks:

  • Focus only on what will change
  • Use semantic HTML and aria or custom attributes to hold state information
  • Leverage classes to help identify structure in HTML-independent ways
  • Group related bits of state together

🏎 Delivering It Quickly

Want to deliver fast? Deliver Less!

Our Critical CSS is the CSS we need to render our initial viewable area.

<style>
/** Inlined Critical CSS **/
</style>
<link rel="preload" href="style.css" as="style"
  onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="style.css"></noscript>
<script>
/*! loadCSS rel=preload polyfill. [c]2017 Filament Group, Inc. MIT License */
(function(){ ... }());
</script>

What's All This About preload Then?!

preload fonts for faster First Contentful Paint

<link rel="preload" href="font.woff2"
  as="font" type="font/woff2" crossorigin>

And our JavaScript?

<link rel="preload" href="mustard.js" as="script" >

<!-- Bottom of our HTML -->

<script type="module" defer src="mustard.js"></script>
<script nomodule defer src="no-mustard.js"></script>

Those pesky images and videos tho

Image Bytes trend from httparchive.org showing a 655.5% increase in the median to 794.0KB for mobile from July 1, 2011 to July 1, 2018 and a 141.1% increase in the median to 659.6KB for desktop Video Bytes trend from httparchive.org showing a 182456.3% increase in the median to 2920.9KB for mobile from April 15, 2016 to July 1, 2018 and a 807.9% increase in the median to 2599.3KB for desktop

IntersectionObserver Is Here!

const media = document.querySelectorAll('picture, img, video, audio, iframe');

if ('IntersectionObserver' in window) {
  const observer = new IntersectionObserver(entries => {
    entries.forEach(entry ==> entry.isIntersecting ? load(entry.target) : false);
  });

  media.forEach(m => observer.observe(m));
} else {
  media.forEach(m => load(m));
}

And Offline too?

if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/sw.js');
  });
};
module.exports = {
  globDirectory: '.www',
  swDest: '.www/sw.js',
  maximumFileSizeToCacheInBytes: 4.5 * 1024 * 1024,
  runtimeCaching: [{
      urlPattern: new RegExp('.(?:js|css|html)$'),
      handler: 'staleWhileRevalidate',
    }, {…}],
};

🎩 Putting It All Together

😐
R ResponseA AnimationI IdleL Load
Tap to paint in less than 100msProduce each frame in 10msBackground functions are processed in 50ms chunks<5000ms TTI on average mobile connection
Lighthoue Scores: First Contentful Paint: 2,4000ms, Firt Meaningful Paint 3,880ms, Speed index 8,200ms, First CPU Idle 6,6470ms, Time to Interactive 7,140ms, Input Latency 717ms, Overall Performance 51, Overall Accessibility 80
Lighthoue Scores: First Contentful Paint: 2,3000ms, Firt Meaningful Paint 3,910ms, Speed index 3,020ms, First CPU Idle 5,970ms, Time to Interactive 6,250ms, Input Latency 618ms, Overall Performance 75, Overall Accessibility 81
Lighthoue Scores: First Contentful Paint: 2,7000ms, Firt Meaningful Paint 4,880ms, Speed index 2,700ms, First CPU Idle 5,760ms, Time to Interactive 6,650ms, Input Latency 241ms, Overall Performance 71, Overall Accessibility 81

Code Splitting

Lighthoue Scores: First Contentful Paint: 1,8000ms, Firt Meaningful Paint 5,060ms, Speed index 2,210ms, First CPU Idle 5,060s, Time to Interactive 5,730ms, Input Latency 50ms, Overall Performance 80, overall Accessibility 82

🏡 Bringin' It Home

UnoptimizedOptimized MediaNew Stage FrightCode Split03,0006,0009,00012,000First Contentful PaintSpeed IndexTime to InteractiveMainThreadWorkInput LatencyTime (ms)
  • Designing tool and technique agnostic core experiences to focus on our user's needs as opposed to just features
  • Embracing progressive enhancement to allow us to deliver our core experiences regardless of browser or device
  • Enhancing our experience by Cutting the Mustard, enabling us to deliver modern JavaScript without transpiling
  • Managing our application with a State Manager to coordinate state changes with minimal overhead
  • Utilizing preload, IntersectionObserver, Service Workers, and Code Splitting to speed up and inclemently deliver our experience