10 Web Performance Lessons
For the
21st Century*
*Title loosely inspired by this bookkwasniew.com
Using the Web in 2008
•Go to website
•Do things (post a comment, read news etc.)
Using the Web nowadays
•Go to website
•Do things (post a message, read news etc.)
Using the Web nowadays
•Go to website
•Not what I intended to do
•…
•Not what I intended to do
•Do things (post a message, read news etc.)
http://requestmap.webperf.tools/
http://www.geek.com/games/the-average-web-page-is-now-larger-than-the-original-doom-1653097/
2.3MB
*Floppy disk, not a save icon
missed opportunity
10 lessons
Mateusz Kwaśniewski (kwasniew.com)
2007 2019
2013 2019
Mateusz Kwaśniewski (kwasniew.com)
2013 20192004
Mateusz Kwaśniewski (kwasniew.com)
Lesson I
“Programmers at work maintaining
a legacy web application"
My first big mistake
• Applying random optimisation without identifying a bottleneck
• There’s opportunity cost of doing useless optimisations
Theory of Constraints
Lesson 1: Measure first,
optimise bottleneck second
Practical Performance: https://www.youtube.com/watch?v=6m_E-mC0y3Y
One Metric That Matters?
1st generation
1st generation
1st generation
Lab/Synthetic
Real User Monitoring (RUM)
Raiders of the fast start: https://www.youtube.com/watch?v=qts9gPYoANU
Just after 

DOMContentLoaded
7 seconds before

Load
2nd generation
Speed Index
Custom Metrics
https://sites.google.com/a/webpagetest.org/docs/using-webpagetest/metrics/speed-index
https://blog.twitter.com/engineering/en_us/a/2012/improving-performance-on-twittercom.html
Custom Metric: Hero Image
https://speedcurve.com/blog/user-timing-and-custom-metrics/
Custom Metric: Hero Image
Image loaded early but render was blocked by the script
3rd generation
First Contentful Paint
Time to Interactive
First Meaningful Paint
First CPU Idle
3rd generation
First Contentful Paint
Time to Interactive
First Meaningful Paint
First CPU Idle
3rd generation
First Contentful Paint
Time to Interactive
First Meaningful Paint
First CPU Idle
speed index
speed index
Show it to your CEO
Interactivity metric in RUM?
Web Performance: Leveraging the Metrics that Most Affect User Experience: https://www.youtube.com/watch?v=6Ljq-Jn-EgU&t=898s
First (Contentful) Paint
Custom Metric
Lighthouse metrics
This process we follow, this cycle we ride
The search is not over
Last Painted Hero = max(largest heading, largest image)
Lesson 2:
Measure
what
matters
How I learned to stop worrying and love UX metrics:
https://www.youtube.com/watch?v=lLR_nGA5t5g
WEB PERFORMANCE METRICS
What does good look like?
20% faster
https://treo.sh/demo/1?interval=1month
Performance Budget
Be specific
https://timkadlec.com/remembers/2019-03-07-performance-budgets-that-stick/
Continuous Web Performance Testing
Performance bankruptcy
https://product.voxmedia.com/2015/5/6/8561867/declaring-performance-bankruptcy
https://blog.radware.com/applicationdelivery/applicationaccelerationoptimization/2013/06/web-performance-poverty-line/
https://www.youtube.com/watch?v=Lx1cYJAVnzA
Time to Interactive < 5s for the first load
https://addyosmani.com/blog/performance-budgets/
100ms 1000ms
Magic numbers
https://www.mediawiki.org/wiki/Wikimedia_Performance_Team/Perceived_Performance
100ms 1000ms
https://calendar.perfplanet.com/2018/magic-numbers/
Lesson 3: Get yourself
performance budget
Web Performance Advocates
and JS Frameworkers
debating on Twitter
Web Performance Advocates
and JS Frameworkers
debating on Twitter
Platform!
React!
Web Performance Advocates
and JS Frameworkers
debating on Twitter
#perfmatters
#DX matters
Lesson 4
Disclaimer: JS startup time may not
be an issue for your type of app
Make JavaScript Faster: https://www.youtube.com/watch?v=RwSlubTBnew
https://medium.com/dev-channel/the-cost-of-javascript-84009f51e99e
Optimization: use lighter framework
Optimization: use lighter framework
this looks small
Hyperapp
•Standalone React+Redux
•400 lines of code I can reason about
•Elm architecture, very few concepts to learn - fits in my head
•Matches my JS preferences - no this/new/classes
•Loads fast by default
Hyperapp
•Standalone React+Redux
•400 lines of code I can reason about
•Elm architecture, very few concepts to learn - fits in my head
•Matches my JS preferences - no this/new/classes
•Loads fast by default
Hyperapp
•Standalone React+Redux
•400 lines of code I can reason about
•Elm architecture, very few concepts to learn - fits in my head
•Matches my JS preferences - no this/new/classes
•Loads fast by default
Hyperapp
•Standalone React+Redux
•400 lines of code I can reason about
•Inspired by Elm architecture, very few concepts to learn - fits in my head
•Matches my JS preferences - no this/new/classes
•Loads fast by default
Hyperapp
•Standalone React+Redux
•400 lines of code I can reason about
•Inspired by Elm architecture, very few concepts to learn - fits in my head
•Matches my JS preferences - no this/new/classes
•Loads fast by default
____ extends Component
@Component
Hyperapp
•Standalone React+Redux
•400 lines of code I can reason about
•Inspired by Elm architecture, very few concepts to learn - fits in my head
•Matches my JS preferences - no this/new/classes
•Loads fast by default
Hyperapp
•Standalone React+Redux
•400 lines of code I can reason about
•Inspired by Elm architecture, very few concepts to learn - fits in my head
•Matches my JS preferences - no this/new/classes
•Loads fast by default
https://github.com/kwasniew/hyperapp-realworld-example-app
27kb
14kb
13kb
1kB
https://github.com/krausest/js-framework-benchmark
Lesson 4: Write JS. Not too
much. Mostly _____.
Lesson 4: Write JS. Not too
much. Mostly functions.
https://medium.com/dev-channel/a-netflix-web-performance-case-study-c0bcde26a9d9
I don’t know
I guess it was
popular
Availability heuristic
Boring
solution
to my
boring
problem
Oh
Shiny
Shiny
Choose boring technology?
Choose boring technology.
https://mcfunley.com/choose-boring-technology
https://superuser.com/questions/927585/on-some-websites-why-doesnt-ctrl-click-work-but-right-click-open-in-new-t
Back button amnesia
Browsers help you with HTML
optimisations for free
Progressive rendering
out of the box
{"username": "@username_9","score": 499,"text": “Blah 123"}
{"username": "@username_83","score": 498,"text": “Blah 345"}
https://github.com/jakearchibald/streaming-html/blob/master/xhr-ndjson.js
But HTML is bigger
than JSON
nope.
http://codeartisan.blogspot.com/2012/07/using-html-as-media-type-for-your-api.html
But my framework
can do SSR
CSR (Client Side Render)
First Paint - 1.7s
Interactive - 2.7s
Server-Side Render (SSR) + CSR
Server-Side Render (SSR) + CSR
First Paint - 1.5s
Interactive - 4.0s
First Paint - 1.7s
Interactive - 2.7s
well-executed SPA
Lesson 5:
Write code.
Not too much.
Mostly HTMLstream based partial async hydration
How to Survive the Single Page App-ocalypse: https://www.youtube.com/watch?v=1SRO-1HBE6E
Lesson 6
CSS
JS
Compiled to JS languages
Statically typed FP langs
Elm
Elm = Types + Ramda + Immutable.js + React + Redux + …
https://elm-lang.org/blog/small-assets-without-the-headache
Hyperapp
28kb
Hyperapp
28kb32kb
🌳
Why can’t we have it in JS and
its supersets?
Array.prototype.smoosh = …
Optimisations taxonomy
• load time
• runtime
Ease and safety of optimisation
https://elm-lang.org/blog/blazing-fast-html-round-two
https://elm-lang.org/blog/blazing-fast-html
Pure functions
+
Immutable data structures
String -> Html
lazy String -> Html
Making stupid things impossible
lazy [Item] -> Html
What capabilities are enabled
by my language constraints?
Lesson 6: You may need more
than JS
The more you SPA the more you
need to understand the browser
https://developers.google.com/web/updates/2018/09/inside-browser-part1
Technique: Pushing random optimisation commit
with your fingers crossed
Flame Chart
render
Comments
Comment
Hypothesis
View optimisation strategies
Windowing/
Virtualized long list
Align work
(keyed lists)
<ul>
<li key="0">Red</li>
<li key="1">Green</li>
</ul>
<ul>
<li key="2">Refactor</li>
<li key="0">Red</li>
<li key="1">Green</li>
</ul>
Skip work
(avoid reconciliation)
lazy
shouldComponentUpdate/PureComponent
memoize
Lesson 7: Observe the not so
secret life of your browser
Browser Rendering Optimization: https://eu.udacity.com/course/browser-rendering-optimization--ud860
BROWSER
What I need my website to do?
1. Download and render most important elements of the page
What I need my website to do?
1. Download and render most important elements of the page
“You don't need all that other crap.
Have courage in your minimalism.”
http://idlewords.com/talks/website_obesity.htm
What I need my presentation to do?
1. Cover the most important elements of the talk
GitHub uses no web fonts
Parallax lag
Lesson 8: Have courage in your
minimalism
Go make the Web faster
DEV OPS
DEV OPSDesign Marketing
https://kwasniew.com/training/people-and-interactions/
What should we teach children today to
prepare them for the world of tomorrow?
1. Measure first, optimise bottleneck second
2. Measure what matters
3. Get yourself performance budget
4. Write JS. Not too much.
5. Write code. Not too much. Mostly HTML.
6. Embrace static FP. You may need more than JS.
7. Observe not so secret live of your browser
8. Bad system will beat good people every single time
9. Have courage in your minimalism
10.Sometimes 9 is enough
1. Measure first, optimise bottleneck second
2. Measure what matters
3. Get yourself performance budget
4. Write JS. Not too much. Mostly functions.
5. Write code. Not too much. Mostly HTML.
6. Embrace static FP. You may need more than JS.
7. Observe not so secret live of your browser
8. Bad system will beat good people every single time
9. Have courage in your minimalism
10.Sometimes 9 is enough
1. Measure first, optimise bottleneck second
2. Measure what matters
3. Get yourself performance budget
4. Write JS. Not too much. Mostly functions.
5. Write code. Not too much. Mostly HTML.
6. Embrace static FP. You may need more than JS.
7. Observe not so secret life of your browser
8. Bad system will beat good people every single time
9. Have courage in your minimalism
10.Sometimes 9 is enough
1. Measure first, optimise bottleneck second
2. Measure what matters
3. Get yourself performance budget
4. Write JS. Not too much. Mostly functions.
5. Write code. Not too much. Mostly HTML.
6. Embrace static FP. You may need more than JS.
7. Observe not so secret life of your browser
8. Make or join faster organisation
9. Have courage in your minimalism
10.Sometimes 9 is enough
1. Measure first, optimise bottleneck second
2. Measure what matters
3. Get yourself performance budget
4. Write JS. Not too much. Mostly functions.
5. Write code. Not too much. Mostly HTML.
6. Embrace static FP. You may need more than JS.
7. Observe not so secret life of your browser
8. Make or join faster organisation
9. Have courage in your minimalism
10.Sometimes 9 is enough
1. Measure first, optimise bottleneck second
2. Measure what matters
3. Get yourself performance budget
4. Write JS. Not too much. Mostly functions.
5. Write code. Not too much. Mostly HTML.
6. Embrace static FP. You may need more than JS.
7. Observe not so secret life of your browser
8. Make or join faster organisation
9. Have courage in your minimalism
10. Sometimes 9 is enough
Delivered with ❤ by @kwasniew
Thank you

10 Web Performance Lessons For the 21st Century