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 [email protected] Performance and the mobile web: why it

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

    7 •Hope for the following answers: •Battery •CPU •screen DPI •latency
  3. mobify.com @mobify [email protected] 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 [email protected] 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 [email protected] 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 [email protected] Amount of JS 25 Phone slow JS

    execution. iPhone 4 -> iPhone 4s, 2x cpu, 15% better JS!
  7. mobify.com @mobify [email protected] 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 [email protected] Layout reflow + Painting • Repaints --

    also maybe raid some stuff from Ilya’s presentation 27
  9. mobify.com @mobify [email protected] 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 [email protected] 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 [email protected] 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 [email protected] 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 [email protected] 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 [email protected] 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 [email protected] 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 [email protected] 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 [email protected] Making use of localStorage and “smart” caching:

    localStorage performance 44 Instantiating a 20kb javascript from localStorage
  18. mobify.com @mobify [email protected] 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 [email protected] 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 [email protected] 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