Slides about Slides
- 📱
- 🐌
- 💰
- 🖥
Hey! This Sounds Familiar
You're Right!
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>
Behold Our new
Modern JS Baseline
const
and partiallet
support- Promises and
async
functions fetch
- Arrow functions
- Proxy objects
- Rest parameters
- Classes
- Template literals
- Generators
- And, of course, JavaScript Modules
👹 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>
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 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 Response | A Animation | I Idle | L Load |
---|---|---|---|
Tap to paint in less than 100ms | Produce each frame in 10ms | Background functions are processed in 50ms chunks | <5000ms TTI on average mobile connection |
Code Splitting
🏡 Bringin' It Home
- 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