making modern websites
TRANSCRIPT
![Page 1: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/1.jpg)
Making Modern WebsitesPatrick Kettner
![Page 2: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/2.jpg)
@PatrickKettner
![Page 3: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/3.jpg)
@PatrickKettner
![Page 4: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/4.jpg)
@PatrickKettner
![Page 5: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/5.jpg)
@PatrickKettner
![Page 6: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/6.jpg)
@PatrickKettner
![Page 7: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/7.jpg)
Websites .
@PatrickKettner
![Page 8: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/8.jpg)
Making Websites .
@PatrickKettner
![Page 9: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/9.jpg)
Making Websites is Hard.
@PatrickKettner
![Page 10: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/10.jpg)
srsly.
@PatrickKettner
![Page 11: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/11.jpg)
![Page 12: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/12.jpg)
Clipboard API
const
Cross-document messaging
Cross-Origin Resource Sharing
crypto.getRandomValues()
CSS Font Loading
CSS.supports() API
CustomEvent
DeviceOrientation & DeviceMotion events
Document Object Model Range
DOM Parsing and Serialization
ECMAScript 5
Element.getBoundingClientRect()
Element.insertAdjacentHTML()
ES6 Number
Fetch
FIDO U2F API
File API
FileReader API
Full Screen API
Gamepad API
Geolocation
getUserMedia/Stream API
Hashchange event
High Resolution Time API
IndexedDB
Input Method Editor API
KeyboardEvent.key
KeyboardEvent.location
MathML
MP3 audio format
MPEG-4/H.264 video format
Node.textContent
Ogg Vorbis audio format
Ogg/Theora video format
Opus
PNG alpha transparency
Public Key Pinning
querySelector/querySelectorAll
Referrer Policy
Resource Hints: dns-prefetch
Resource Hints: preconnect
Resource Hints: prefetch
Resource Hints: prerender
Server Name Indication
Shadow DOM
Strict Transport Security
Upgrade Insecure Requests
WAI-ARIA Accessibility features
Wav audio format
WebM video format
Window.devicePixelRatio
WOFF - Web Open Font Format
WebGL - 3D Canvas graphics
Offline web applications
All HTML5 features
Other
AAC audio file format
asm.js
async attribute for external scripts
autocomplete attribute: on & off values
Brotli Accept-Encoding/Content-Encoding
Client Hints: DPR, Width, Viewport-Width
Content Security Policy 1.0
Content Security Policy Level 2
Data URIs
defer attribute for external scripts
document.head
DOMContentLoaded
ECMAScript 5 Strict Mode
Element.closest()
EventTarget.addEventListener()
EventTarget.dispatchEvent
getComputedStyle
HTTP/2 protocol
JPEG 2000 image format
JPEG XR image format
KeyboardEvent.code
KeyboardEvent.getModifierState()
meter element
Minimum length attribute
Multiple file selection
New semantic elements
Number input type
Pattern attribute for input fields
Picture element
PNG favicons
progress element
Range input type
relList (DOMTokenList)
Reversed attribute of ordered lists
Ruby annotation
sandbox attribute for iframes
Scoped CSS
seamless attribute for iframes
Search input type
Session history management
Spellcheck attribute
srcdoc attribute for iframes
Srcset attribute
Subresource Integrity
Text API for Canvas
Toolbar/context menu
Video element
Video Tracks
wbr (word break opportunity) element
Audio Tracks
Autofocus attribute
Canvas (basic support)
Canvas blend modes
classList (DOMTokenList)
Color input type
contenteditable attribute
Custom Elements
Custom protocol handling
Datalist element
dataset & data-* attributes
Date and time input types
Details & Summary elements
Dialog element
disabled attribute
Download attribute
Drag and Drop
Email, telephone & URL input types
Form attribute
Form validation
getElementsByClassName
hidden attribute
HTML Imports
HTML templates
HTML5 form features
input event
input placeholder attribute
letter-spacing CSS property
Media Queries: interaction media features
Media Queries: resolution feature
rem (root em) units
text-decoration styling
text-emphasis styling
TTF/OTF
Viewport units: vw, vh, vmin, vmax
:placeholder-shown CSS pseudo-class
Crisp edges/pixelated images
Backdrop Filter
Canvas Drawings
Cross-Fade Function
font-smooth
image-set
Logical Properties
Motion Path
pointer-events (for HTML)
position:sticky
Reflections
text-size-adjust
text-stroke
zoom
Improved kerning pairs & ligatures
All CSS features
accept attribute for file input
Audio element
Background-image options
Border images
Border-radius (rounded corners)
Box-shadow
Box-sizing
Colors
Cursors (original values)
Cursors: zoom-in & zoom-out
font-kerning
image-orientation
Media Queries
Multiple backgrounds
Multiple column layout
object-fit/object-position
Opacity
Overflow-wrap
selectors
tab-size
text-align-last
Text-overflow
Text-shadow
Transitions
word-break
OM Scroll-behavior
Flexible Box Layout Module
Font unicode-range subsetting
Intrinsic & Extrinsic Sizing
font-stretch
font-variant-alternates
Generated content
Gradients
Grid Layout
Hyphenation
initial value
inline-block
Masks
min/max-width/height
outline
page-break properties
position:fixed
Regions
Repeating Gradients
resize property
Scroll snap points
Shapes Level 1
Table display
touch-action property
unset value
user-select: none
Variables
will-change property
writing-mode property
2D Transforms
3D Transforms
::first-letter CSS pseudo-element selector
::placeholder CSS pseudo-element
::selection CSS pseudo-element
@font-face Web fonts
Blending of HTML/SVG elements
calc() as CSS unit value
2.1 selectors
all property
Animation
Appearance
background-attachment
background-blend-mode
background-position edge offsets
box-decoration-break
clip-path property
Counter Styles
Counters
currentColor value
Device Adaptation
element() function
Exclusions Level 1
Feature Queries
Filter Effects
filter() function
font-feature-settings
font-size-adjust
WOFF 2.0 - Web Open Font Format
XHTML served as application/xhtml+xml
Animated PNG (APNG)
EOT - Embedded OpenType fonts
KeyboardEvent.charCode
KeyboardEvent.which
Node.innerText
Resource Hints: Lazyload
SPDY protocol
WebP image format
WebVTT - Web Video Text Tracks
XHTML+SMIL animation
All Other features
SVG
Inline SVG in HTML5
SVG (basic support)
SVG effects for HTML
SVG favicons
SVG filters
SVG fonts
SVG fragment identifiers
SVG in CSS backgrounds
SVG in HTML img element
SVG SMIL animation
All SVG features
JS API
Ambient Light API
Arrow functions
Base64 encoding and decoding
Battery Status API
Beacon API
Blob constructing
Blob URLs
BroadcastChannel
Channel messaging
Internationalization API
JSON parsing
let
matches() DOM method
matchMedia
maxlength attribute for input and textarea elements
Media Source Extensions
Mutation Observer
Navigation Timing API
Object RTC (ORTC) API for WebRTC
Online/offline status
Page Visibility
PageTransitionEvent
Pointer events
PointerLock API
Promises
Proximity API
Proxy object
requestAnimationFrame
Resource Timing
Rest parameters
Screen Orientation
Server-sent events
Service Workers
Shared Web Workers
Touch events
Typed Arrays
User Timing API
Vibration API
Web Animations API
Web Audio API
Web Cryptography
Web MIDI API
Web Notifications
Web Sockets
Web Storage - name/value pairs
Web Workers
WebRTC Peer-to-peer connections
XMLHttpRequest advanced features
Basic console logging functions
Document.execCommand()
Efficient Script Yielding: setImmediate()
Filesystem & FileWriter API
Network Information API
Object.observe data binding
Permissions API
Speech Recognition API
Speech Synthesis API
Web SQL Database
![Page 13: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/13.jpg)
@PatrickKettner
![Page 14: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/14.jpg)
@PatrickKettner
![Page 15: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/15.jpg)
tools .
@PatrickKettner
![Page 16: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/16.jpg)
@PatrickKettner
![Page 17: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/17.jpg)
@PatrickKettner
![Page 18: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/18.jpg)
Second most used lib
@PatrickKettner
![Page 19: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/19.jpg)
@PatrickKettner
![Page 20: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/20.jpg)
@PatrickKettner
![Page 21: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/21.jpg)
commit a9a90192ea11dc0ff916431b40227734af9074b6
Author: Patrick Kettner <[email protected]>
Date: Fri Sep 11 18:59:17 2015 -0700
release 3.0
@PatrickKettner
![Page 22: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/22.jpg)
@PatrickKettner
![Page 23: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/23.jpg)
{{months of work}}
@PatrickKettner
![Page 24: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/24.jpg)
@PatrickKettner
![Page 25: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/25.jpg)
no one cares.
@PatrickKettner
![Page 26: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/26.jpg)
(other than me)
@PatrickKettner
![Page 27: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/27.jpg)
at best,we don’t get in the way
@PatrickKettner
![Page 28: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/28.jpg)
we are just a pitstop
@PatrickKettner
![Page 29: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/29.jpg)
we still need tomake users happy
@PatrickKettner
![Page 30: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/30.jpg)
how?
@PatrickKettner
![Page 31: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/31.jpg)
make itreally, really fast
@PatrickKettner
![Page 32: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/32.jpg)
@PatrickKettner
![Page 33: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/33.jpg)
@PatrickKettner
![Page 34: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/34.jpg)
@joecritchley
![Page 35: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/35.jpg)
@PatrickKettner
![Page 36: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/36.jpg)
@font-face
@PatrickKettner
![Page 37: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/37.jpg)
@PatrickKettner
![Page 38: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/38.jpg)
@PatrickKettner
![Page 39: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/39.jpg)
the site works, itjust looks broken
@PatrickKettner
![Page 40: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/40.jpg)
@PatrickKettner
![Page 41: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/41.jpg)
document.fonts.ready.then(() => { let body = document.body body.classList.toggle("fontzL0ad3d")});
@PatrickKettner
![Page 42: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/42.jpg)
body { font-family: 'T0t411y-R4D-Sans', 'Helvetica', 'Sans-Serif'}
@PatrickKettner
![Page 43: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/43.jpg)
body { font-family: 'Helvetica', 'Sans-Serif'}
body.fontzL0ad3d { font-family: 'T0t411y-R4D-Sans'}
@PatrickKettner
![Page 44: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/44.jpg)
@PatrickKettner
![Page 45: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/45.jpg)
@PatrickKettner
![Page 46: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/46.jpg)
@PatrickKettner
![Page 47: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/47.jpg)
@PatrickKettner
![Page 48: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/48.jpg)
FontFaceObserver
@PatrickKettner
github.com/bramstein/fontfaceobserver
![Page 49: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/49.jpg)
document.fonts.ready.then(() => { let body = document.body body.classList.toggle("fontzL0ad3d")});
@PatrickKettner
![Page 50: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/50.jpg)
@PatrickKettner
let observer = new FontFaceObserver("T0t411y-R4D-Sans");
observer.check().then(() => { let body = document.body body.classList.toggle("fontzL0ad3d")});
![Page 51: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/51.jpg)
@PatrickKettner
![Page 52: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/52.jpg)
@PatrickKettner
![Page 53: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/53.jpg)
December 1, 2015@PatrickKettner
![Page 54: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/54.jpg)
![Page 55: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/55.jpg)
@PatrickKettner
![Page 56: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/56.jpg)
@PatrickKettner
![Page 57: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/57.jpg)
@PatrickKettner
![Page 58: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/58.jpg)
@PatrickKettner
![Page 59: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/59.jpg)
@PatrickKettner
observer.check().then(() => { localStorage.setItem("fontzL0ad3d", true)});
![Page 60: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/60.jpg)
if it is cached properly
@PatrickKettner
![Page 61: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/61.jpg)
and the user didn’t clear part of the cache
@PatrickKettner
![Page 62: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/62.jpg)
and the browser didn’t automatically remove it
@PatrickKettner
![Page 63: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/63.jpg)
this was alwaysan educated guess
@PatrickKettner
![Page 64: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/64.jpg)
ServiceWorker
@PatrickKettner
![Page 65: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/65.jpg)
kindof a big deal...
@PatrickKettner
![Page 66: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/66.jpg)
@PatrickKettner
Offline ExperiencesPush NotificationsBackground Syncand much, much more...
![Page 67: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/67.jpg)
@PatrickKettner
FetchCache
- Network Proxy- Programmable Cache
![Page 68: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/68.jpg)
![Page 69: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/69.jpg)
@PatrickKettner
![Page 70: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/70.jpg)
259 modules
@PatrickKettner
![Page 71: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/71.jpg)
single module =dozens of requests
@PatrickKettner
![Page 72: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/72.jpg)
ServiceWorker?
@PatrickKettner
![Page 73: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/73.jpg)
navigator.serviceWorker.register('/serviceworker.js')
@PatrickKettner
![Page 74: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/74.jpg)
let CURRENT_CACHE = { prefetch: 'prefetch-cache-v1'};
self.addEventListener('install', event => { let prefetch = ['/T0t411y-R4D-Sans'] event.waitUntil(caches.open(CURRENT_CACHE['prefetch']) .then(cache => cache.addAll(prefetch.map((url) => new Request(url, { 'mode': 'no-cors' }) )) ) )})
@PatrickKettner
![Page 75: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/75.jpg)
self.addEventListener('fetch', event => { event.respondWith(caches.match(event.request) .then((response) => { if (response) { return response; } return fetch(event.request) .then(response => response); }));});
@PatrickKettner
![Page 76: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/76.jpg)
@PatrickKettner
![Page 77: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/77.jpg)
:(
@PatrickKettner
![Page 78: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/78.jpg)
hero
@PatrickKettner
![Page 79: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/79.jpg)
savior
@PatrickKettner
![Page 80: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/80.jpg)
douchebag
@PatrickKettner
![Page 81: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/81.jpg)
AppCache
@PatrickKettner
![Page 82: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/82.jpg)
@JaffaTheCake
![Page 83: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/83.jpg)
AppCache
@PatrickKettner
![Page 84: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/84.jpg)
ServiceWorker > AppCache
@PatrickKettner
![Page 85: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/85.jpg)
@PatrickKettner
![Page 86: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/86.jpg)
...but it covers our use
@PatrickKettner
![Page 87: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/87.jpg)
CACHE MANIFEST
#__CACHE_VERSION__
//download/css/main.css/img/logo.svg
/js/build.js
__ASSETS__
NETWORK:*
@PatrickKettner
![Page 88: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/88.jpg)
<html lang="en" manifest="/offline.appcache"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> ...
@PatrickKettner
![Page 89: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/89.jpg)
<html lang="en" manifest="/offline.appcache"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> ...
@PatrickKettner
![Page 90: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/90.jpg)
<html lang="en" manifest="/offline.appcache"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> ...
@PatrickKettner
![Page 91: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/91.jpg)
ServiceWorker > AppCache
@PatrickKettner
![Page 92: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/92.jpg)
if('serviceWorker' in navigator) { navigator.serviceWorker.register('/serviceworker.js')} else if ('applicationCache' in window) { // add AppCache}
@PatrickKettner
![Page 93: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/93.jpg)
can’t be added by js
@PatrickKettner
![Page 94: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/94.jpg)
let iframe = document.createElement('iframe')iframe.style.display = 'none'iframe.src = '/load-appcache.html'document.body.appendChild(iframe)
@PatrickKettner
![Page 95: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/95.jpg)
<html manifest="/offline.appcache"> <head> <title>loading douchebags</title> </head> <body></body></html>
@PatrickKettner
![Page 96: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/96.jpg)
20.7 seconds
@PatrickKettner
![Page 97: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/97.jpg)
190 milliseconds
@PatrickKettner
![Page 98: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/98.jpg)
ServiceWorker > AppCache
@PatrickKettner
![Page 99: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/99.jpg)
ServiceWorkers!
@PatrickKettner
![Page 100: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/100.jpg)
ServiceWorkers
@PatrickKettner
![Page 101: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/101.jpg)
WebWorkers
@PatrickKettner
![Page 102: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/102.jpg)
commit 90b52e847359ae902d3f7ce7bc511cadfbc29ea8
Author: Alexey Proskuryakov <[email protected]>
Date: Thu Nov 6 07:04:47 +0000
Implement Worker global object
@PatrickKettner
![Page 103: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/103.jpg)
2008!
@PatrickKettner
![Page 104: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/104.jpg)
Version 2@PatrickKettner
![Page 105: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/105.jpg)
Version 2@PatrickKettner
![Page 106: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/106.jpg)
WebWorkers
@PatrickKettner
![Page 107: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/107.jpg)
WebWorkers?
@PatrickKettner
![Page 108: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/108.jpg)
single threadedby default
@PatrickKettner
![Page 109: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/109.jpg)
everything is fighting for CPU time
@PatrickKettner
![Page 110: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/110.jpg)
lots of number crunchin’===
hardcore jank
@PatrickKettner
![Page 111: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/111.jpg)
Offload tasks to background thread
@PatrickKettner
![Page 112: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/112.jpg)
super expensive fnsbecome pretty cheap
@PatrickKettner
![Page 113: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/113.jpg)
dynamic filesize calculation
@PatrickKettner
![Page 114: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/114.jpg)
@PatrickKettner
![Page 115: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/115.jpg)
![Page 116: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/116.jpg)
![Page 117: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/117.jpg)
100% clientside!
@PatrickKettner
![Page 118: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/118.jpg)
if ('Worker' in window) { let gzipWorker = new Worker('/gzip.js');
window.gziper = (config, cb) => { gzipWorker.postMessage(config); gzipWorker.onmessage = (e) => cb(e.data); }}
@PatrickKettner
![Page 119: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/119.jpg)
@PatrickKettner
importScripts('/pako_deflate.js’, '/pretty-bytes.js');
onmessage = (msg, cb) => { let build = JSON.parse(msg.data).build; let response = { original: prettyBytes(build.length), compressed: prettyBytes(pako.deflate(build, {
'level’: 6 }).length) };
postMessage(response);}
![Page 120: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/120.jpg)
@PatrickKettner
![Page 121: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/121.jpg)
![Page 122: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/122.jpg)
/downloadif ('Worker' in window) { window.buildWorker = new Worker('/build.js');}
@PatrickKettner
![Page 123: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/123.jpg)
/downloadbuildWorker.postMessage(JSON.stringify({config}));
@PatrickKettner
![Page 124: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/124.jpg)
@PatrickKettner
/build.jsimportScripts('/r.js', '/modernizr/build.js’); require(['build'],(builder) => { onmessage = (msg) => { let config = JSON.parse(msg.data).config; builder(config, postMessage); }});
![Page 125: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/125.jpg)
by the time BUILD is clickedits already built
@PatrickKettner
![Page 126: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/126.jpg)
“what if their browser don’t have workers”
@PatrickKettner
![Page 127: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/127.jpg)
@PatrickKettner
![Page 128: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/128.jpg)
¯\_(ツ )_/¯ nbd
@PatrickKettner
![Page 129: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/129.jpg)
we’ll just build then
@PatrickKettner
![Page 130: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/130.jpg)
![Page 131: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/131.jpg)
@PatrickKettner
![Page 132: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/132.jpg)
@PatrickKettner
![Page 133: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/133.jpg)
let content = build()...zeroClipboard.on('copy', (e) => { let clipboard = e.clipboardData; clipboard.setData('text/plain', content);});
@PatrickKettner
![Page 134: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/134.jpg)
@PatrickKettner
![Page 135: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/135.jpg)
:(
@PatrickKettner
![Page 136: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/136.jpg)
:(
@PatrickKettner
![Page 137: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/137.jpg)
@PatrickKettner
if (Modernizr.flash) { // ZeroClipboard} else { // somethingElse}
![Page 138: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/138.jpg)
somethingElse?
@PatrickKettner
![Page 139: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/139.jpg)
@PatrickKettner
![Page 140: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/140.jpg)
let content = build()...let output = document.querySelector('output')output.innerHTML = buildoutput.style.display = 'block'output.select()
@PatrickKettner
![Page 141: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/141.jpg)
@PatrickKettner
![Page 142: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/142.jpg)
@PatrickKettner
![Page 143: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/143.jpg)
@PatrickKettner
![Page 144: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/144.jpg)
Blobs, URL, & [download]
@PatrickKettner
![Page 145: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/145.jpg)
let content = build()let blob = new Blob([content], { type: 'text/plain'});let href = URL.createObjectURL(blob)let download = 'modernizr.custom.js'
@PatrickKettner
![Page 146: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/146.jpg)
@PatrickKettner
<a href={href} download={download}>DOWNLOAD</a>
![Page 147: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/147.jpg)
@PatrickKettner
![Page 148: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/148.jpg)
@PatrickKettner
![Page 149: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/149.jpg)
@PatrickKettner
![Page 150: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/150.jpg)
@PatrickKettner
![Page 151: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/151.jpg)
~ 61% :/
@PatrickKettner
![Page 152: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/152.jpg)
@PatrickKettner
![Page 153: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/153.jpg)
@PatrickKettner
![Page 154: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/154.jpg)
Just POST It
@PatrickKettner
![Page 155: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/155.jpg)
@PatrickKettner
<a href={href} download={download}>DOWNLOAD</a>
![Page 156: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/156.jpg)
@PatrickKettner
if (supportsEurythang) { download = <a href={href} download={download}>DOWNLOAD</a>} else { download = <input type='submit' value='download'/>}
![Page 157: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/157.jpg)
Decent Markup
@PatrickKettner
![Page 158: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/158.jpg)
@PatrickKettner
![Page 159: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/159.jpg)
CSS
@PatrickKettner
![Page 160: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/160.jpg)
CSS
@PatrickKettner
![Page 161: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/161.jpg)
![Page 162: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/162.jpg)
JavaScript
@PatrickKettner
![Page 163: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/163.jpg)
JavaScript
@PatrickKettner
![Page 164: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/164.jpg)
![Page 165: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/165.jpg)
100% clientside!
@PatrickKettner
![Page 166: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/166.jpg)
100% clientside!unless it can’t
@PatrickKettner
![Page 167: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/167.jpg)
Server Side
@PatrickKettner
![Page 168: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/168.jpg)
100% static files
@PatrickKettner
![Page 169: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/169.jpg)
@PatrickKettner
let server = new Hapi.Server()
server.routes([{ method: 'GET', path: '/{param*}', handler: { directory: { path: './dist' } }}])
server.start()
![Page 170: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/170.jpg)
99.999% static files
@PatrickKettner
![Page 171: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/171.jpg)
let buildFromPostedQuery = function(request, reply) { let config = generateConfig(request.payload);
Modernizr.build(config,(build) => { reply(build) .header('Content-Type', 'text/javascript') .header('Content-Disposition', 'attachment; filename=modernizr-custom.js') })}
@PatrickKettner
![Page 172: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/172.jpg)
@PatrickKettner
let server = new Hapi.Server()
server.routes([{ method: 'GET', path: '/{param*}', handler: {directory: {path: './dist'}}}, { method: 'POST', path: '/download', handler: buildFromPostedQuery}])
server.start()
![Page 173: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/173.jpg)
works for all browsers!
@PatrickKettner
![Page 174: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/174.jpg)
srsly.
@PatrickKettner
![Page 175: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/175.jpg)
@PatrickKettner
![Page 176: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/176.jpg)
@PatrickKettner
![Page 177: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/177.jpg)
HTML is cool!
@PatrickKettner
![Page 178: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/178.jpg)
no one cares.
@PatrickKettner
![Page 179: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/179.jpg)
@PatrickKettner
![Page 180: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/180.jpg)
@PatrickKettner
![Page 181: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/181.jpg)
“I want to bower install!”
@PatrickKettner
![Page 182: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/182.jpg)
“I want to npm install!”
@PatrickKettner
![Page 183: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/183.jpg)
“There isn’t a file to install”
@PatrickKettner
![Page 184: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/184.jpg)
“...”
@PatrickKettner
![Page 185: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/185.jpg)
“I want to npm install!”
@PatrickKettner
![Page 186: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/186.jpg)
no one cares.
@PatrickKettner
![Page 187: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/187.jpg)
no one cares.
@PatrickKettner
![Page 188: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/188.jpg)
can’t publish every combo
@PatrickKettner
![Page 189: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/189.jpg)
259 modules
@PatrickKettner
![Page 190: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/190.jpg)
259 ^ 259
@PatrickKettner
![Page 191: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/191.jpg)
3.2317 x 10616
@PatrickKettner
![Page 192: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/192.jpg)
no one cares.
@PatrickKettner
![Page 193: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/193.jpg)
Server already buildsfor anything POSTed
@PatrickKettner
![Page 194: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/194.jpg)
/*! modernizr 3.2.0 (Custom Build) | MIT * * https://modernizr.com/download/?-csstransforms-csstransforms3d-csstransitions-svg !*/
!function(e,t,n){function r(e,t){return typeof e===t}function o(){var e,t,n,o,i,s,a;for(var l in y)if(y.hasOwnProperty(l)){if(e=[],t=y[l],t.name&&(e.push(t.name.toLowerCase()),t.options&&t.options.aliases&&t.options.aliases.length))for(n=0;n<t.options.aliases.length;n++)e.push(t.options.aliases[n].toLowerCase());for(o=r(t.fn,"function")?t.fn():t.fn,i=0;i<e.length;i++)s=e[i],a=s.split("."),1===a.length?Modernizr[a[0]]=o:(!Modernizr[a[0]]||Modernizr[a[0]]instanceof Boolean||(Modernizr[a[0]]=new Boolean(Modernizr[a[0]])),Modernizr[a[0]][a[1]]=o),C.push((o?"":"no-")+a.join("-"))}}function i(e){var t = E.className,A
@PatrickKettner
![Page 195: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/195.jpg)
/*! modernizr 3.2.0 (Custom Build) | MIT * * https://modernizr.com/download/?-csstransforms-csstransforms3d-csstransitions-svg !*/
!function(e,t,n){function r(e,t){return typeof e===t}function o(){var e,t,n,o,i,s,a;for(var l in y)if(y.hasOwnProperty(l)){if(e=[],t=y[l],t.name&&(e.push(t.name.toLowerCase()),t.options&&t.options.aliases&&t.options.aliases.length))for(n=0;n<t.options.aliases.length;n++)e.push(t.options.aliases[n].toLowerCase());for(o=r(t.fn,"function")?t.fn():t.fn,i=0;i<e.length;i++)s=e[i],a=s.split("."),1===a.length?Modernizr[a[0]]=o:(!Modernizr[a[0]]||Modernizr[a[0]]instanceof Boolean||(Modernizr[a[0]]=new Boolean(Modernizr[a[0]])),Modernizr[a[0]][a[1]]=o),C.push((o?"":"no-")+a.join("-"))}}function i(e){var t = E.className,A
@PatrickKettner
![Page 196: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/196.jpg)
npm install --save https://modernizr.com/download/?-csstransforms-csstransforms3d-csstransitions-svg
@PatrickKettner
![Page 197: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/197.jpg)
let handler = (request, reply) => { if (userAgent.match(/bower/)) { buildForBower(config) } else if (userAgent.match(/npm/)) { buildForNPM(config) } else { reply.view('/download', config); }}
@PatrickKettner
![Page 198: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/198.jpg)
let Archiver = require('archiver')let archive = Archiver('tar')let bowerJSON = makeBowerJSONFile()
let buildForBower = (config) => { Modernizr.build(config, (build) => { var module = archive .append(build, {name: bowerJSON.main}) .append(JSON.stringify(bowerJSON), {name: 'bower.json'}) .finalize();
reply(module) .header('Content-disposition', 'attachment; filename=Modernizr.custom.tar') })}
@PatrickKettner
![Page 199: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/199.jpg)
let Archiver = require('archiver')let archive = Archiver('tar')let pkg = makePackageJSON()
let buildForNPM = (config) => { Modernizr.build(config, (build) => { var module = archive .append(build, {name: pkgJSON.main}) .append(JSON.stringify(pkgJSON), {name: package.json'}) .finalize();
reply(module) .header('Content-disposition', 'attachment; filename=Modernizr.custom.tar') })}
@PatrickKettner
![Page 200: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/200.jpg)
![Page 201: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/201.jpg)
“wait…require(‘moderznir’)?”
@PatrickKettner
![Page 202: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/202.jpg)
@PatrickKettner
![Page 203: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/203.jpg)
require(‘moderznir’) !== modernizr
@PatrickKettner
![Page 204: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/204.jpg)
@PatrickKettner
Modernizr.build(config, (build) => { fs.writeFileSync('./modernizr.js’)}
![Page 205: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/205.jpg)
very flexible
@PatrickKettner
![Page 206: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/206.jpg)
not super friendly
@PatrickKettner
![Page 207: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/207.jpg)
we already have ainterface we like...
@PatrickKettner
![Page 208: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/208.jpg)
lets reuse it!
@PatrickKettner
![Page 209: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/209.jpg)
![Page 210: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/210.jpg)
React is cool!
@PatrickKettner
![Page 211: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/211.jpg)
![Page 212: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/212.jpg)
no one cares.
@PatrickKettner
![Page 213: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/213.jpg)
get out of the way,in the best ways possible
@PatrickKettner
![Page 214: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/214.jpg)
make awesome stuff.
@PatrickKettner
![Page 215: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/215.jpg)
use the new shiny.
@PatrickKettner
![Page 216: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/216.jpg)
have a lot of fun.
@PatrickKettner
![Page 217: Making Modern Websites](https://reader036.vdocuments.mx/reader036/viewer/2022062522/58a901411a28ab837c8b6bdf/html5/thumbnails/217.jpg)
Thanks!
@PatrickKettner