Build better 
responsive websites 
Hrvoje Jurišić, Inchoo
Nobody likes waiting
OMGcommerce 2014 @hrvojejurisic
Users expect 
2 seconds 
Source: akamai.com
After 3 seconds 
40% will leave 
Source: akamai.com
88% of customers 
will never come back 
Source: gomez.com
1 second delay 
7% less conversions 
Source: tagman.com
Amazon: 100 ms latency 
1% less revenue 
Source: highscalability.com
Bad performance 
Bad business
2013 load time: 7.2s 
2014 load time: 10.7s 
Source: http://www.radware.com/
2013: 1007 KB 
2014: 1677 KB 
Source: http://www.radware.com/
Source: http://httparchive.org/
55% of eCommerce traffic 
happens on mobile device 
Source: webperformancetoday.com
Mobile users expect sites to load 
as fast or even faster 
than on their desktops 
Source: strangeloopnetworks.com
Meet Magento New York 2014 @hrvojejurisic
4G to the 
rescue??
not so 
fast...
Source: igvita.com
Source: mobify.com
Source: facebook
Source: guypo.com 
Page Size 
Smallest resolution 
vs 
Biggest resolution
Popular themeforest Magento Theme
RWD is bad for 
performance!
6% of RWD sites 
done right
RWD is bad for performance!
RWD is bad for performance! 
Blame the 
implementation, 
not the technique
Speed is a feature 
treat it as a part of UX design
Mobile first, content out 
workflow 
Source: http://www.lukew.com
Set a 
performance budget 
Source: http://timkadlec.com
Optimization
Foundations:
Foundations: 
1. Reduce http requests
Foundations: 
1. Reduce http requests 
● Use CSS sprites 
● Use icon fonts 
● Merge javascript 
● Merge CSS
Foundations: 
1. Reduce http requests 
2. Gzip components
Foundations: 
1. Reduce http requests 
2. Gzip components 
3. Minify JS and CSS
Foundations: 
1. Reduce http requests 
2. Gzip components 
3. Minify JS and CSS 
4. Optimize images
Foundations: 
1. Reduce http requests 
2. Gzip components 
3. Minify JS and CSS 
4. Optimize images 
5. CSS at the top
Foundations: 
1. Reduce http requests 
2. Gzip components 
3. Minify JS and CSS 
4. Optimize images 
5. CSS at the top 
6. JS at the bottom or async
Foundations: 
1. Reduce http requests 
2. Gzip components 
3. Minify JS and CSS 
4. Optimize images 
5. CSS at the top 
6. JS at the bottom or async 
7. Use CDN
Tools 
1. Firebug/Web inspector 
2. webpagetest.org 
3. Google PageSpeed
Case study: 
Load time: 2.85s Start render: 2.95s Visually Complete: 3.1s Speed index: 3060
Javascript delivery 
● Merge JS files 
● Don’t block rendering
Javascript delivery - grouping js 
<default> 
<reference name="head"> 
<action method="addJs"> 
<script>prototype/prototype.js</script> 
</action> 
. . . 
. . . 
. . . 
<action method="addJs"> 
<script>scriptaculous/builder.js</script> 
</action> 
</reference> 
</default>
Javascript delivery - grouping js 
Homepage JS 
<script src="....ebbc8820d00736a6f2402ff7b21567b2.js"></script>
Javascript delivery - grouping js 
<catalog_product_view> 
<reference name="head"> 
<action method="addJs"> 
<script>varien/product.js</script> 
</action> 
<action method="addJs"> 
<script>varien/configurable.js</script> 
</action> 
</reference> 
</catalog_product_view>
Javascript delivery - grouping js 
Product page JS 
<script src="....3c5329efd2e437592d48e1a3a4eac5b1.js"></script>
Javascript delivery - grouping js 
Homepage JS 
<script src="....ebbc8820d00736a6f2402ff7b21567b2.js"></script> 100KB 
Product page JS 
<script src="....3c5329efd2e437592d48e1a3a4eac5b1.js"></script> 120KB
Javascript delivery - grouping js 
<default> 
<reference name="head"> 
<action method="addJs"> 
<script>prototype/prototype.js</script> 
<params>data-group="main"</params> 
</action> 
. . . 
. . . 
<action method="addJs"> 
<script>scriptaculous/builder.js</script> 
<params>data-group="main"</params> 
</action> 
</reference> 
</default>
Javascript delivery - grouping js 
Homepage JS 
<script src="....ebbc8820d00736a6f2402ff7b21567b2.js" data-group="main"> - 100Kb 
Product page JS 
<script src="....ebbc8820d00736a6f2402ff7b21567b2.js" data-group="main"> - cached 
<script src="....3c5329efd2e437592d48e1a3a4eac5b1.js"> - 20Kb
Javascript delivery - defer js 
<action method="addJs"> 
<script>prototype/prototype.js</script> 
<params>data-group="main" defer</params> 
</action>
Javascript delivery - defer js 
<script type="text/javascript"> 
document.addEventListener( "DOMContentLoaded", function(){ 
Mage.Cookies.path = '<?php echo $this->getPath()?>'; 
Mage.Cookies.domain = '<?php echo $this->getDomain()?>'; 
}, false ); 
</script>
Load time: 2.66s 
Start render: 1.3s 
Visually Complete: 2.8s 
Speed index: 2223
Font serving 
● Choose fallback font wisely 
● Prepare for failure - style fallback font 
● Don’t block rendering 
● Minimize FOUT 
● Store Base64 encoded font in local storage
Font serving 
/** Pseudocode **/ 
if (fonts_in_localStorage) { 
inject cached Font style sheet 
} else { 
// Don't block the loading of the page; 
on(window, "load", function() { 
load webfont.css 
store fonts_in_localStorage 
}); 
} 
Script: https://gist.github.com/
Load time: 1.8s 
Start render: 1.29s 
Visually Complete: 2.3s 
Speed index: 1746
Images delivery 
● Don’t waste user’s bandwidth 
● Load image when needed: “Lazy loading” 
● Load images based on screen size and pixel density: 
“Responsive images”
Images delivery 
<img 
class="lazy" 
src="default_image_url/loader" 
data-small = "small_image_url" 
data-big = "big_image_url" 
alt="" 
/>
Images delivery 
/** Pseudocode **/ 
if (image_is_on_screen) { 
if (resolution < 500px) && (pixel_density < 2 ) { 
show small image 
} else { 
show big image 
} 
} 
Script: echo.js
Load time: 1.50s 
Start render: 1.29s 
Visually Complete: 2.2s 
Speed index: 1653
CSS delivery 
● Start rendering early 
● Inline Critical CSS 
● Merge external CSS files 
● Defer loading of non-critical CSS
CSS delivery - inline critical CSS 
critical styles 
non-critical styles
CSS delivery - inline critical CSS 
/** Pseudocode **/ 
if (cssLoaded_cookie_exists) { 
Load CSS normally 
} else { 
<style> 
inject_critical_css 
</style> 
Load non-critical CSS async 
set cssLoaded cookie 
}); 
} 
Script: loadCSS
CSS delivery - critical CSS 
SCSS 
_account.scss 
_breadcrumbs.scss 
_buttons.scss 
_cart.scss 
_checkout.scss 
_footer.scss 
_forms.scss 
_header.scss 
_global.scss 
_navigation.scss 
_search.scss 
. . . 
. . . 
styles.scss styles.css
CSS delivery - critical CSS 
SCSS 
_account.scss 
_breadcrumbs.scss 
_buttons.scss 
_cart.scss 
_checkout.scss 
_footer.scss 
_forms.scss 
_header.scss 
_global.scss 
_navigation.scss 
_search.scss 
. . . 
. . . 
critical.scss critical.css
Load time: 1.55s 
Start render: 0.7s 
Visually Complete: 2.1s 
Speed index: 1547
Load time: 1.55s 
Start render: 0.7s 
Visually Complete: 2.1s 
Speed index: 1547 
Load time: 2.85s 
Start render: 2.95s 
Visually Complete: 3.1s 
Speed index: 3060
Takeaways: 
1. Performance matters
Takeaways: 
1. Performance matters 
2. Treat performance as a part of UX
Takeaways: 
1. Performance matters 
2. Treat performance as a part of UX 
3. Set performance budget
Takeaways: 
1. Performance matters 
2. Treat performance as a part of UX 
3. Set performance budget 
4. Optimize
Takeaways: 
1. Performance matters 
2. Treat performance as a part of UX 
3. Set performance budget 
4. Optimize 
5. RWD is NOT bad for performance!
Thank you 
Presentation: http://goo.gl/H0aNIc

Build Better Responsive websites. Hrvoje Jurišić

  • 1.
    Build better responsivewebsites Hrvoje Jurišić, Inchoo
  • 3.
  • 4.
  • 5.
    Users expect 2seconds Source: akamai.com
  • 6.
    After 3 seconds 40% will leave Source: akamai.com
  • 7.
    88% of customers will never come back Source: gomez.com
  • 8.
    1 second delay 7% less conversions Source: tagman.com
  • 9.
    Amazon: 100 mslatency 1% less revenue Source: highscalability.com
  • 10.
  • 11.
    2013 load time:7.2s 2014 load time: 10.7s Source: http://www.radware.com/
  • 12.
    2013: 1007 KB 2014: 1677 KB Source: http://www.radware.com/
  • 13.
  • 15.
    55% of eCommercetraffic happens on mobile device Source: webperformancetoday.com
  • 16.
    Mobile users expectsites to load as fast or even faster than on their desktops Source: strangeloopnetworks.com
  • 17.
    Meet Magento NewYork 2014 @hrvojejurisic
  • 18.
    4G to the rescue??
  • 19.
  • 20.
  • 21.
  • 22.
  • 24.
    Source: guypo.com PageSize Smallest resolution vs Biggest resolution
  • 25.
  • 26.
    RWD is badfor performance!
  • 27.
    6% of RWDsites done right
  • 29.
    RWD is badfor performance!
  • 30.
    RWD is badfor performance! Blame the implementation, not the technique
  • 32.
    Speed is afeature treat it as a part of UX design
  • 33.
    Mobile first, contentout workflow Source: http://www.lukew.com
  • 34.
    Set a performancebudget Source: http://timkadlec.com
  • 36.
  • 37.
  • 38.
  • 39.
    Foundations: 1. Reducehttp requests ● Use CSS sprites ● Use icon fonts ● Merge javascript ● Merge CSS
  • 40.
    Foundations: 1. Reducehttp requests 2. Gzip components
  • 41.
    Foundations: 1. Reducehttp requests 2. Gzip components 3. Minify JS and CSS
  • 42.
    Foundations: 1. Reducehttp requests 2. Gzip components 3. Minify JS and CSS 4. Optimize images
  • 43.
    Foundations: 1. Reducehttp requests 2. Gzip components 3. Minify JS and CSS 4. Optimize images 5. CSS at the top
  • 44.
    Foundations: 1. Reducehttp requests 2. Gzip components 3. Minify JS and CSS 4. Optimize images 5. CSS at the top 6. JS at the bottom or async
  • 45.
    Foundations: 1. Reducehttp requests 2. Gzip components 3. Minify JS and CSS 4. Optimize images 5. CSS at the top 6. JS at the bottom or async 7. Use CDN
  • 47.
    Tools 1. Firebug/Webinspector 2. webpagetest.org 3. Google PageSpeed
  • 48.
    Case study: Loadtime: 2.85s Start render: 2.95s Visually Complete: 3.1s Speed index: 3060
  • 49.
    Javascript delivery ●Merge JS files ● Don’t block rendering
  • 50.
    Javascript delivery -grouping js <default> <reference name="head"> <action method="addJs"> <script>prototype/prototype.js</script> </action> . . . . . . . . . <action method="addJs"> <script>scriptaculous/builder.js</script> </action> </reference> </default>
  • 51.
    Javascript delivery -grouping js Homepage JS <script src="....ebbc8820d00736a6f2402ff7b21567b2.js"></script>
  • 52.
    Javascript delivery -grouping js <catalog_product_view> <reference name="head"> <action method="addJs"> <script>varien/product.js</script> </action> <action method="addJs"> <script>varien/configurable.js</script> </action> </reference> </catalog_product_view>
  • 53.
    Javascript delivery -grouping js Product page JS <script src="....3c5329efd2e437592d48e1a3a4eac5b1.js"></script>
  • 54.
    Javascript delivery -grouping js Homepage JS <script src="....ebbc8820d00736a6f2402ff7b21567b2.js"></script> 100KB Product page JS <script src="....3c5329efd2e437592d48e1a3a4eac5b1.js"></script> 120KB
  • 55.
    Javascript delivery -grouping js <default> <reference name="head"> <action method="addJs"> <script>prototype/prototype.js</script> <params>data-group="main"</params> </action> . . . . . . <action method="addJs"> <script>scriptaculous/builder.js</script> <params>data-group="main"</params> </action> </reference> </default>
  • 56.
    Javascript delivery -grouping js Homepage JS <script src="....ebbc8820d00736a6f2402ff7b21567b2.js" data-group="main"> - 100Kb Product page JS <script src="....ebbc8820d00736a6f2402ff7b21567b2.js" data-group="main"> - cached <script src="....3c5329efd2e437592d48e1a3a4eac5b1.js"> - 20Kb
  • 57.
    Javascript delivery -defer js <action method="addJs"> <script>prototype/prototype.js</script> <params>data-group="main" defer</params> </action>
  • 58.
    Javascript delivery -defer js <script type="text/javascript"> document.addEventListener( "DOMContentLoaded", function(){ Mage.Cookies.path = '<?php echo $this->getPath()?>'; Mage.Cookies.domain = '<?php echo $this->getDomain()?>'; }, false ); </script>
  • 59.
    Load time: 2.66s Start render: 1.3s Visually Complete: 2.8s Speed index: 2223
  • 60.
    Font serving ●Choose fallback font wisely ● Prepare for failure - style fallback font ● Don’t block rendering ● Minimize FOUT ● Store Base64 encoded font in local storage
  • 61.
    Font serving /**Pseudocode **/ if (fonts_in_localStorage) { inject cached Font style sheet } else { // Don't block the loading of the page; on(window, "load", function() { load webfont.css store fonts_in_localStorage }); } Script: https://gist.github.com/
  • 62.
    Load time: 1.8s Start render: 1.29s Visually Complete: 2.3s Speed index: 1746
  • 63.
    Images delivery ●Don’t waste user’s bandwidth ● Load image when needed: “Lazy loading” ● Load images based on screen size and pixel density: “Responsive images”
  • 64.
    Images delivery <img class="lazy" src="default_image_url/loader" data-small = "small_image_url" data-big = "big_image_url" alt="" />
  • 65.
    Images delivery /**Pseudocode **/ if (image_is_on_screen) { if (resolution < 500px) && (pixel_density < 2 ) { show small image } else { show big image } } Script: echo.js
  • 66.
    Load time: 1.50s Start render: 1.29s Visually Complete: 2.2s Speed index: 1653
  • 67.
    CSS delivery ●Start rendering early ● Inline Critical CSS ● Merge external CSS files ● Defer loading of non-critical CSS
  • 68.
    CSS delivery -inline critical CSS critical styles non-critical styles
  • 69.
    CSS delivery -inline critical CSS /** Pseudocode **/ if (cssLoaded_cookie_exists) { Load CSS normally } else { <style> inject_critical_css </style> Load non-critical CSS async set cssLoaded cookie }); } Script: loadCSS
  • 70.
    CSS delivery -critical CSS SCSS _account.scss _breadcrumbs.scss _buttons.scss _cart.scss _checkout.scss _footer.scss _forms.scss _header.scss _global.scss _navigation.scss _search.scss . . . . . . styles.scss styles.css
  • 71.
    CSS delivery -critical CSS SCSS _account.scss _breadcrumbs.scss _buttons.scss _cart.scss _checkout.scss _footer.scss _forms.scss _header.scss _global.scss _navigation.scss _search.scss . . . . . . critical.scss critical.css
  • 72.
    Load time: 1.55s Start render: 0.7s Visually Complete: 2.1s Speed index: 1547
  • 73.
    Load time: 1.55s Start render: 0.7s Visually Complete: 2.1s Speed index: 1547 Load time: 2.85s Start render: 2.95s Visually Complete: 3.1s Speed index: 3060
  • 74.
  • 75.
    Takeaways: 1. Performancematters 2. Treat performance as a part of UX
  • 76.
    Takeaways: 1. Performancematters 2. Treat performance as a part of UX 3. Set performance budget
  • 77.
    Takeaways: 1. Performancematters 2. Treat performance as a part of UX 3. Set performance budget 4. Optimize
  • 78.
    Takeaways: 1. Performancematters 2. Treat performance as a part of UX 3. Set performance budget 4. Optimize 5. RWD is NOT bad for performance!
  • 79.
    Thank you Presentation:http://goo.gl/H0aNIc