Upload
jonas-ohlsson
View
158
Download
2
Tags:
Embed Size (px)
Citation preview
Killer performance
Jonas Ohlsson@pocketjoso
BEATING THE COMPETITION
Jonas Ohlsson
Front end developer at State
Perf and tooling geek
Author of Penthouse
https://github.com/pocketjoso/penthouse/
10 seconds later
LET’S GO SOMEWHERE ELSE..
https://www.facebook.com/instantArticles
Is the Web slow?
http://www.quirksmode.org/blog/archives/2015/05/web_vs_native_l.html
Are heavy JS frameworks responsible for the slow
web?
Page LoadKEY CONCEPTS
Perceived load
PAGE LOAD KEY CONCEPTS
Start Render
Total Page Load Time
PAGE LOAD KEY CONCEPTS
SpeedIndex
PAGE LOAD KEY CONCEPTS
1 second to“break the glass”
PAGE LOAD KEY CONCEPTS
https://developers.google.com/speed/docs/insights/mobile
(Request) Latency kills mobile performance
https://developers.google.com/speed/docs/insights/mobile
PAGE LOAD KEY CONCEPTS
Page LoadSTATS
#perfmatters
https://twitter.com/hashtag/perfmatters
http://www.webperformancetoday.com/2012/02/28/4-awesome-slides-showing-how-page-speed-correlates-to-business-metrics-at-walmart-com/
PAGE LOAD STATS
http://kylerush.net/blog/meet-the-obama-campaigns-250-million-fundraising-platform/
PAGE LOAD STATS
https://blog.mozilla.org/metrics/2010/04/05/firefox-page-load-speed-%E2%80%93-part-ii/
PAGE LOAD STATS
Page LoadTOOLS
https://developers.google.com/speed/pagespeed/insights/
PAGE LOAD TOOLS
https://developers.google.com/speed/pagespeed/insights/
PAGE LOAD TOOLS
WebPageTest CLI / Node module
https://github.com/marcelduran/webpagetest-api
Perf budget (grunt)
https://github.com/tkadlec/grunt-perfbudget
PAGE LOAD TOOLS
http://timkadlec.com/2015/05/choosing-performance/
http://www.filamentgroup.com/lab/weight-wait.html
http://www.filamentgroup.com/lab/weight-wait.html
THEORY
Critical Path for rendering
HTML
<html><head><script src=‘bundle.js’></script><link rel=‘style’
href=‘styles.css’></link></head><body>…
</body></html>
CSS
JS
Start render
CRITICAL PATH FOR RENDERING
<html><head><link rel=‘style’
href=‘styles.css’></link></head><body>…<script src=‘bundle.js’></script>
</body></html>
Start render
HTMLCSS
JS
CRITICAL PATH FOR RENDERING
<html><head></head><body>…<script src=‘bundle.js’></script><link rel=‘style’
href=‘styles.css’></link></body></html>
Start render
HTMLCSS
JS
CRITICAL PATH FOR RENDERING
<html><head><style>/* critical styles for page*/
</style></head><body>…<script src=‘bundle.js’></script><link rel=‘style’
href=‘styles.css’></link></body></html>
Start render
HTMLCSS
JS
CRITICAL PATH FOR RENDERING
<html><head><style>/* critical styles for page*/
</style><script src=‘bundle.js’
async></script>
</head><body>…<link rel=‘style’
href=‘styles.css’></link></body></html>
Start render
HTMLCSS
JS
CRITICAL PATH FOR RENDERING
<html><head><style>/* critical styles for page*/
</style><script>function loadCss()…loadCss(‘styles.css’);</script><script src=‘bundle.js’
async></script>
</head><body>…
</body></html>
Start render
HTMLCSS
JS
CRITICAL PATH FOR RENDERING
https://github.com/filamentgroup/loadCSS
TCP slow start
First roundtrip only fits ~14kb
Styles needed to render immediately visible content
~ “above the fold”
Per page
Critical Path CSS
https://github.com/addyosmani/critical/
Critical path css generators
Manually
http://jonassebastianohlsson.com/criticalpathcssgenerator
Static content
https://github.com/addyosmani/critical
CLI or build process (node, gulp, grunt)
https://github.com/pocketjoso/penthouse
Automating Critical Css
AUTOMATING CRITICAL CSS
grunt-penthouse
penthouse: {home : {
css : ‘styles/fullCss.css’,url : ‘localhost:8000/’,outfile : 'index.html.css',width : 1300, height : 900
}}
AUTOMATING CRITICAL CSS
grunt-penthousepenthouse: {
home : {css : ‘styles/fullCss.css’,url : ‘localhost:8000/’,outfile : 'index.html.css',width : 1300, height : 900
},work : {
css : ‘styles/fullCss.css’,url : ‘localhost:8000/work/’,outfile : 'work/index.html.css',width : 1300, height : 900
}, ..
AUTOMATING CRITICAL CSS
Rewrite relative paths
<link rel=‘style’ href=‘css/styles.css’></link>
// cssurl: (‘../fonts/Lato.woff’)
// inline in <head><style>url: (‘fonts/Lato.woff’)
</style>
AUTOMATING CRITICAL CSS
penthouse (Node)[ ‘localhost:8000/’, ‘localhost:8000/work/’].map(function(url){ penthouse({
css : ‘styles/fullCss.css’, url : url, width : 1300, height : 900 }, function(err, criticalCss) {if (err) return;
fs.writeFile(someFileName, criticalCss); });});
AUTOMATING CRITICAL CSS
Using local files[ ‘index.html’, // will be rendered over file protocol ‘work/index.html’].map(function(url){ penthouse({
css : ‘styles/fullCss.css’, url : url, width : 1300, height : 900 }, function(err, criticalCss) {if (err) return;
fs.writeFile(someFileName, criticalCss); });});
AUTOMATING CRITICAL CSS
Serving critical css
<head>{{#if criticalCss}} <style>{{{ criticalCss }}}</style> <script> function loadCSS(){…} loadCSS(‘{{ stylesUrl }}’); </script> {{else}} <link rel='stylesheet'
href='{{ stylesUrl }}' /> {{/if}}</head>
AUTOMATING CRITICAL CSS
Serving critical css<head>{{#if criticalCss}} <style>{{{ criticalCss }}}</style> <script> function loadCSS(){…} loadCSS(‘{{ stylesUrl }}’); </script> <noscript><link rel='stylesheet'
href='{{ stylesUrl }}' /></noscript> {{else}} <link rel='stylesheet'
href='{{ stylesUrl }}' /> {{/if}}</head>
Flash Of Invisible Text
var ffObserver = new FontFaceObserver('Lato Web', { weight: 400});var ffBoldObserver = new FontFaceObserver('Lato Web', { weight: 700});
window.Promise.all([ ffObserver.check(), ffBoldObserver.check()]).then(function(){
document.documentElement.className +=
‘ fonts-loaded’;});
FLASH OF INVISIBLE TEXT FIX
FontFaceObserver
https://github.com/bramstein/fontfaceobserver
body { font-family: sans-serif;};
.fonts-loaded body {font-family: ‘Lato Web’, sans-serif;}
FLASH OF INVISIBLE TEXT FIX
FontFaceObserver
https://github.com/bramstein/fontfaceobserver
FLASH OF INVISIBLE TEXT FIX
Questions?
Jonas Ohlsson@pocketjoso
BOOM!