Upgrade to Pro — share decks privately, control downloads, hide ads and more …

VanJS: Performance and the mobile web

VanJS: Performance and the mobile web

With mid-range smartphones now rocking 2-core processors and LTE wireless speeds of over 20 Mbps, it seems like we're out of the woods on mobile performance. Then why doesn't the mobile web feel faster? In this talk I'll review the numbers showing why performance still matters and discuss some of what you can do about it.

Peter McLachlan

February 12, 2013
Tweet

Other Decks in Programming

Transcript

  1. mobify.com @mobify hello@mobify.com Performance and the mobile web: why it

    still matters & what you can do about it (we’re hiring!) 1
  2. mobify.com @mobify hello@mobify.com Audience question What is different about mobile?

    7 •Hope for the following answers: •Battery •CPU •screen DPI •latency
  3. mobify.com @mobify hello@mobify.com Responsive design Ethan Marcotte “Fluid grids, flexible

    images, and media queries are the three technical ingredients for responsive web design” RESPONSIVE WEB DESIGN 12 We won’t talk about Responsive web design in a couple of years. Not because it’s gone away but because it will just be “web design” and people won’t do it any other way!
  4. mobify.com @mobify hello@mobify.com Bandwidth 18 Not out of the woods

    yet ... most of us are between the first pillar and the second pillar. Actual speeds tend to be a lot slower than theoretical maximums.
  5. mobify.com @mobify hello@mobify.com What does this mean? 0%# 10%# 20%#

    30%# 40%# 50%# 60%# 70%# 80%# 90%# 100%# 100ms# 1s# 2s# 3s# 4s# 5s# 6s# 7s# 8s# 9s# 10s# eCommerce'sales'lost'due'to'load'.me' Source: Amazon web team (1% sales lost per 100ms) 21
  6. mobify.com @mobify hello@mobify.com Amount of JS 25 Phone slow JS

    execution. iPhone 4 -> iPhone 4s, 2x cpu, 15% better JS!
  7. mobify.com @mobify hello@mobify.com CSS Complexity html body.s_blog section#page div.entry-content span.entry-body,

    html body.s_blog body.indexB section#page div.entry-content .hentry div.text, html body.indexB body.s_blog section#page div.entry-content .hentry div.text, html body.s_blog body.indexB section#page .hentry div.entry-content div.text, html body.indexB body.s_blog section#page .hentry div.entry-content div.text, html body.s_blog body.indexB section#page div.entry-content .dragrace-holder section.feature.dragrace div.text, html body.indexB body.s_blog section#page div.entry-content .dragrace-holder section.feature.dragrace div.text, html body.s_blog body.indexB section#page .dragrace-holder section.feature.dragrace div.entry-content div.text, html body.indexB body.s_blog section#page .dragrace-holder section.feature.dragrace div.entry-content div.text, html body.s_blog body.indexB body.list.listC .container section#page div.entry-content .hentry div.main-column .item-inner #slideshow-description-outer div.item-footer, html body.indexB body.list.listC .container body.s_blog section#page div.entry-content .hentry div.main- column .item-inner #slideshow-description-outer div.item-footer, html body.s_blog body.indexB body.list.listC .container section#page .hentry div.main-column .item-inner #slideshow-description-outer div.entry-content div.item-footer, html body.indexB body.list.listC .container body.s_blog section#page .hentry div.main-column .item-inner #slideshow-description-outer div.entry-content div.item-footer, html body.s_blog body.list.listC .container body.indexB section#page div.entry-content .hentry div.main- column .item-inner #slideshow-description-outer div.item-footer, html body.list.listC .container body.indexB body.s_blog section#page div.entry-content .hentry div.main-column .item-inner #slideshow-description-outer div.item-footer, html body.s_blog body.list.listC .container body.indexB section#page .hentry div.main-column .item-inner #slideshow-description-outer div.entry-content div.item-footer, html body.list.listC .container body.indexB body.s_blog section#page .hentry div.main-column .item-inner #slideshow- description-outer div.entry-content div.item-footer, html body.s_blog body.indexB body.list.listC .container section#page div.entry-content div.main-column .item-inner #slideshow-description-outer .hentry div.item-footer, html body.indexB body.list.listC .container body.s_blog section#page div.entry-content div.main-column .item- inner #slideshow-description-outer .hentry div.item-footer, html body.s_blog body.indexB body.list.listC .container section#page div.main-column .item-inner #slideshow-description- outer .hentry div.entry-content div.item-footer, html body.indexB body.list.listC .container body.s_blog section#page div.main-column .item-inner #slideshow-description-outer .hentry div.entry-content div.item-footer, html body.s_blog body.list.listC .container body.indexB section#page div.entry-content div.main-column .item-inner #slideshow-description- outer .hentry div.item-footer, html body.list.listC .container body.indexB body.s_blog section#page div.entry-content div.main-column .item-inner #slideshow-description- outer .hentry div.item-footer, html body.s_blog body.list.listC .container body.indexB section#page div.main-column .item-inner #slideshow-description-outer .hentry div.entry- content div.item-footer, html body.list.listC .container body.indexB body.s_blog section#page div.main-column .item-inner #slideshow-description-outer .hentry div.entry-content div.item- footer, html body.s_blog body.indexB body.list.listC .container section#page div.entry- content .dragrace-holder section.feature.dragrace div.main-column .item-inner #slideshow- description-outer div.item-footer, html body.indexB body.list.listC .container body.s_blog section#page div.entry-content .dragrace-holder section.feature.dragrace div.main- column .item-inner #slideshow-description-outer div.item-footer, html body.s_blog body.indexB body.list.listC .container section#page .dragrace-holder section.feature.dragrace div.main-column .item-inner #slideshow-description-outer div.entry-content div.item-footer, html body.indexB body.list.listC .container body.s_blog section#page .dragrace-holder section.feature.dragrace div.main-column .item-inner #slideshow-description-outer div.entry- content div.item-footer, html body.s_blog body.list.listC .container body.indexB section#page div.entry-content .dragrace-holder section.feature.dragrace div.main-column .item-inner #slideshow-description-outer div.item-footer, html body.list.listC .container body.indexB body.s_blog section#page div.entry-content .dragrace-holder section.feature.dragrace div.main-column .item-inner #slideshow-description-outer div.item-footer, html body.s_blog body.list.listC .container body.indexB section#page .dragrace-holder section.feature.dragrace div.main-column .item-inner #slideshow-description-outer div.entry-content div.item-footer, html body.list.listC .container body.indexB body.s_blog section#page .dragrace-holder section.feature.dragrace div.main-column .item-inner #slideshow-description-outer div.entry- content div.item-footer, html body.s_blog body.indexB body.list.listC .container section#page div.entry-content div.main-column .item-inner #slideshow-description-outer .dragrace-holder section.feature.dragrace div.item-footer, html body.indexB body.list.listC .container body.s_blog section#page div.entry-content div.main-column .item-inner #slideshow- description-outer .dragrace-holder section.feature.dragrace div.item-footer, html body.s_blog body.indexB body.list.listC .container section#page div.main-column .item-inner #slideshow- description-outer .dragrace-holder section.feature.dragrace div.entry-content div.item-footer, html body.indexB body.list.listC .container body.s_blog section#page div.main-column .item- inner #slideshow-description-outer .dragrace-holder section.feature.dragrace div.entry- content div.item-footer, html body.s_blog body.list.listC .container body.indexB section#page div.entry-content div.main-column .item-inner #slideshow-description-outer .dragrace-holder section.feature.dragrace div.item-footer, html body.list.listC .container body.indexB body.s_blog section#page div.entry-content div.main-column .item-inner #slideshow- description-outer .dragrace-holder section.feature.dragrace div.item-footer, html body.s_blog body.list.listC .container body.indexB section#page div.main-column .item-inner #slideshow- description-outer .dragrace-holder section.feature.dragrace div.entry-content div.item-footer, html body.list.listC .container body.indexB body.s_blog section#page div.main-column .item- inner #slideshow-description-outer .dragrace-holder section.feature.dragrace div.entry- content div.item-footer { font-size: 13px; display: block; margin-top: 10px; } 26 CSS Selector of shame Please never do this.
  8. mobify.com @mobify hello@mobify.com Layout reflow + Painting • Repaints --

    also maybe raid some stuff from Ilya’s presentation 27
  9. mobify.com @mobify hello@mobify.com What causes these? • clientHeight • clientLeft

    • clientTop • clientWidth • focus • getBoundingClientRect • getClientRects • innerText • offsetHeight • offsetLeft • offsetParent • offsetTop • offsetWidth • outerText • scrollByLines • scrollByPages • scrollHeight • scrollIntoView • scrollIntoViewIfNeeded • scrollLeft • scrollTop • scrollWidth • MouseEvent • layerX • layerY • offsetX • offsetY • Window • getComputedStyle • scrollBy • scrollTo • scrollX • scrollY • Frame • Document & Image • height • width Any DOM modification or: 28
  10. mobify.com @mobify hello@mobify.com Moving down is hard Image Credit: Brad

    Frost 30 This is the way we’ve usually done things. Time to turn it around.
  11. mobify.com @mobify hello@mobify.com Anti-pattern: domain sharding 34 Domain sharding is

    now an anti-pattern. At best it provides neutral results and adds complexity. Complexity is bad. In the future it will probably be a very significant anti-pattern.
  12. mobify.com @mobify hello@mobify.com Anti-pattern: Naive lazy loading Wait, isn’t being

    lazy good? 37 Wait, isn’t lazy-loading good? Sorta. We’re not taking advantage of browser optimizations!
  13. mobify.com @mobify hello@mobify.com Remove unneeded resources • The best optimization

    there is! • Difficult to do, ex post facto • Developer time is precious • Greedy browsers don’t help us out here 39 The best optimization there is! Only load things when we have to! * This sounds pretty easy, but it’s tricky in practice developer time is precious, there’s always another bug to squash usual approach is to throw everything in and hope to have time to wean it down later. This seldom happens. async vs defer
  14. mobify.com @mobify hello@mobify.com Compress assets 40 Again -- seems easy.

    So why don’t more sites do it? * It’s a pain. Easy to do once, difficult to maintain * Even if you write scripts that do it for you, changes can break those deployment scripts * Even sites maintained by large, capable web teams seem not to get this right. Need proof? I’m not going to shame anyone in public, just go visit some top retailer site with developer tools running.
  15. mobify.com @mobify hello@mobify.com Pre-fetching 41 * Nobody has done a

    really great job of this * DNS pre-fetching * Page pre-fetching * Image / JS pre-fetching + localStorage
  16. mobify.com @mobify hello@mobify.com Intelligent radio warmup 43 DCH = Dedicated

    channel FACH = Forward access cannel may be able to transmit small data packets on the random access channel (RACH)
  17. mobify.com @mobify hello@mobify.com Making use of localStorage and “smart” caching:

    localStorage performance 44 Instantiating a 20kb javascript from localStorage
  18. mobify.com @mobify hello@mobify.com Generic optimizations • CDN • Limit number

    of hosts • Set good caching headers • Far future expires • Cookieless domains 46 * Why limit number of hosts: Tie back to 3-way handshake & domain sharding example * Why cookieless domains make a difference
  19. mobify.com @mobify hello@mobify.com Some resources for performance • https://developers.google.com/speed/ •

    http://www.igvita.com/ (Gregorik Ilya, Google Performance team) • http://stevesouders.com/ (Author of "High Performance Websites, O'reilly & Associates" ) (author of YSlow) • Recommendations? 47
  20. mobify.com @mobify hello@mobify.com Performance - we could spend weeks on

    this • There are no shortcuts. To really get into mobile performance you need an engineer who understands: • HTTP/1.1 • pipelining • cacheing rules • TCP/IP • 3-way handshake • congestion control • packet-loss impacts • Web servers • c10k problem & solutions • cacheing • concurrency models • Content Delivery Networks • DNS • latency • cacheing • IP Anycast • DNS • Georouting • Asynchronous network communications • 3G+4G radio behavior ... • Browser concurrency models • what is threaded what is not • synchronous & asynchronous operations • Browser rendering processes • what forces a repaint? • Modern web design • workflow • content • marketing requirements 49