Making modern web performance
accessible

My name is
Amberley

  • πŸ‘©πŸ»β€πŸ’» Dev + things @ Gatsby
  • πŸ“ Live in Austin, TX
  • 🐦 @amber1ey on Twitter

The way we build for the web has
changed

Let's talk about:

  • 1️⃣ How building for the web has evolved,
  • 2️⃣ Performance challenges today,
  • 3️⃣ Ways to tackle those challenges,
  • 4️⃣ Making it easier for developers.

1️⃣ How building for the web has evolved

Static delivery

<html>
  <head>
    <title>Hello world</title>
  </head>
  <body>
    <h1>Is anyone out there?</h1>
  </body>
</html>

πŸ‘

  • πŸ’Έ Static hosting is cheap
  • 🌏 Widely supported

πŸ™πŸΌ

πŸ‘

  • πŸ’Έ Static hosting is cheap
  • 🌏 Widely supported
  • βœ‰οΈ Limited requests required
  • πŸ“¦ File sizes typically smaller
πŸ”— MDN

πŸ‘Ž

  • πŸ” Much copy-paste
  • πŸ’¬ ARY (always repeat yourself)
  • πŸ˜‘ Tedious and brittle
  • ⏹ Not dynamic

Server side rendering

<?php
get_header(); ?>

<?php
while ( have_posts() ) :
    the_post();
    endwhile;
?>

<?php
get_footer();

πŸ‘

  • 😸 Separation of concerns
  • ♻️ Code reusability and maintainability
  • ⚑️ Dynamic data manipulation
πŸ”— MDN

πŸ‘Ž

  • πŸ€‘ Servers are expensive
  • 🎩 Hosting is more complex
  • πŸ€” Vulnerability, requires security

Client-side rendering

class Hello extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

ReactDOM.render(<Hello name="Toronto" />, document.getElementById("root"));
...
<body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root"></div>
  <script src="/static/js/bundle.js"></script>
</body>
...

πŸ‘

  • πŸ“± App-like experience in the browser
  • πŸ‘‹πŸΌ Interactivity is incredibly approachable
  • 🌳 Explosion of tools in the ecosystem
  • πŸ’Έ Static file hosting is cheaper (again)
  • πŸ™…πŸ»β€ Separation of concerns, DRY (still)

πŸ‘Ž

  • βš“οΈ Tons of JavaScript sent to the browser
  • 🐌 Page load can be super slow
  • πŸ€” Requires JavaScript to be enabled
  • πŸ›  Hard to do well -- so much tooling

2️⃣ Performance challenges
in the current landscape

JS frameworks are
⚑️ powerful* ⚑️

*With a cost

πŸ‘©πŸΏπŸ§”πŸ»πŸ‘±πŸΌβ€ User experience πŸ‘©πŸΌπŸ§“πŸ»πŸ‘΄πŸ½

Time is ️valuable

  • βŒ›οΈοΈ average time to load a mobile landing page: 15 seconds πŸ”— Source
  • πŸ’πŸ»β€ 53% of mobile site visitors abandon a page that takes
    3+ seconds to load πŸ”— Source

Access is unequal

  • β—‘ 55% of the world is online.πŸ”— Source
  • πŸ“± 2/3 has a mobile device.πŸ”— Source
  • ☝🏼 50%+ of those are smart devices.πŸ”— Source
  • βš–οΈ Disparity in quality of hardware and affordability of data.

Average monthly data

  • 🌏 Globally: 2.9 GB. πŸ”— Source
  • 🌎 North America: 7.1 GB. πŸ”— Source

We build with
bias

Access is
situational

Ability (or access) is not binary...

πŸ”— Source

It's all a spectrum...

πŸ”— Source

It's also context-dependent.

πŸ‘©πŸ½β€πŸ’»πŸ‘¨πŸΏβ€πŸ’»πŸ‘©πŸ»β€πŸ’» Developer experience πŸ‘©β€πŸ’»πŸ‘©πŸ½β€πŸ’»πŸ‘¨πŸΎβ€πŸ’»

πŸ”— image

🀯

😩

(JavaScript Fatigue)

to framework or not to framework

πŸ”— image

Given where we are:

1️⃣ How do we make what's delivered to the end user as performant and accessible as possible?

2️⃣ How do we improve the development experience when trying to accomplish that?

3️⃣ Strategies to tackle performance challenges
in the current landscape

1️⃣ Implement route-based code splitting

2️⃣ Serve assets with HTTP/2

HTTP/1.1

HTTP/2

HTTP/2 with server push

3️⃣ Set up background prefetching

4️⃣ Add a service worker

5️⃣ Lazy load non-critical assets

PRPL Pattern

  • β€’ (Push) critical resources for the initial URL route.
  • β€’ (Render) initial route.
  • β€’ (Pre-cache) remaining routes.
  • β€’ (Lazy load) and create remaining routes on demand.
πŸ”— Google

6️⃣ Only ship live code

  • 🌳 tree shaking
  • πŸ’€ dead code elimination

7️⃣ Serve static files (as much as possible)

🀯 (again)

1, 2, 3... 63 😳

πŸ”— Unsplash

4️⃣ How to make perf techniques
more approachable

  • 🏎 Get most of the way there, under the hood.
  • πŸ“ Use auditing tools.
  • πŸ€“ Dig in (if you want).

Progressive disclosure

"Progressive disclosure defers advanced or rarely used features to a secondary screen, making applications easier to learn and less error-prone." πŸ”— Source

Laying a strong foundation πŸ’ͺ

  • βœ… Implement route-based code splitting
  • βœ‹πŸΌ Use HTTP/2 to serve assets
  • βœ… Set up background prefetching
  • βœ… Lazy load non-critical assets
  • βœ‹πŸΌ Add a service worker
  • βœ… Only ship live code
  • βœ… Serve static files

βœ… Implement route-based code splitting

 β”œβ”€β”€ 404
 β”‚   └── index.html
 β”œβ”€β”€ 9-f5d9c17474395c2890a3.js
 β”œβ”€β”€ about
 β”‚   └── index.html
 β”œβ”€β”€ app-2abedacd9bf03aaca373.js
 β”œβ”€β”€ component---src-pages-404-js-295c3d4f21322761edff.js
 β”œβ”€β”€ component---src-pages-about-js-3997b0d76203b183f5b3.js
 β”œβ”€β”€ component---src-pages-contact-js-34c976efa1482a119a50.js
 β”œβ”€β”€ component---src-pages-index-js-764f0d722c982d3d2789.js
 β”œβ”€β”€ contact
 β”‚   └── index.html
 └── index.html

βœ‹πŸΌ Use HTTP/2 to serve assets

yarn add gatsby-plugin-netlify

βœ… Set up background prefetching

🧐 Intersection Observer

βœ… Lazy load non-critical assets

βœ‹πŸΌ Add a service worker

yarn add gatsby-plugin-offline

βœ… Only ship live code

Webpack + Terser.js

βœ… Serve static files

  • πŸ™…πŸ» Static assets !== Static app πŸ™…πŸ½β€

Demo

Lighthouse score comparison

Static site

Gatsby site

We don't have to re-engineer optimizations for a highly performant baseline.

Thanks! πŸ‘‹πŸΌ

🐦