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

    View Slide

  2. mobify.com @mobify [email protected]
    About me
    2
    Peter McLachlan
    chief architect & co-founder @ Mobify Research & Development

    View Slide

  3. mobify.com @mobify [email protected]
    Mobify
    3

    View Slide

  4. mobify.com @mobify [email protected]
    Trusted by Leading Companies
    4

    View Slide

  5. mobify.com @mobify [email protected]
    Some questions for
    you:
    5
    Interactive -- ask some questions, solicit some responses.

    View Slide

  6. mobify.com @mobify [email protected]
    Audience question
    What kinds of optimizations do you make for web
    performance?
    6

    View Slide

  7. mobify.com @mobify [email protected]
    Audience question
    What is different about mobile?
    7
    •Hope for the following answers:
    •Battery
    •CPU
    •screen DPI
    •latency

    View Slide

  8. mobify.com @mobify [email protected]
    Trends in the mobile
    web
    8

    View Slide

  9. mobify.com @mobify [email protected]
    Latest Trends - Metrics
    9

    View Slide

  10. mobify.com @mobify [email protected]
    Latest Trends - International Mobile Growth
    Image Credit: Brad Frost
    10

    View Slide

  11. mobify.com @mobify [email protected]
    What about mobile
    design?
    11

    View Slide

  12. 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!

    View Slide

  13. mobify.com @mobify [email protected]
    Adaptive Web
    Image Credit: Brad Frost
    13

    View Slide

  14. mobify.com @mobify [email protected]
    Adaptive Web
    Image Credit: Brad Frost
    14

    View Slide

  15. mobify.com @mobify [email protected]
    What makes mobile
    websites slow
    15

    View Slide

  16. mobify.com @mobify [email protected]
    Blocking resources
    16
    External CSS
    CSS includes via @import
    (Most) Javascript

    View Slide

  17. mobify.com @mobify [email protected]
    Non-blocking resources
    17
    Most images (sorta)
    Async or deferred scripts

    View Slide

  18. 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.

    View Slide

  19. mobify.com @mobify [email protected]
    Latency
    Source: Ilya Grigorik (Google)
    19

    View Slide

  20. mobify.com @mobify [email protected]
    Latency
    20

    View Slide

  21. 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

    View Slide

  22. mobify.com @mobify [email protected]
    No problem, we’ll make c faster
    Image credit: XKCD - “relativistic baseball”
    22

    View Slide

  23. mobify.com @mobify [email protected]
    Parsing: HTML
    23
    Unfortunately Responsive HTML is usually even more
    complicated

    View Slide

  24. mobify.com @mobify [email protected]
    Image Credit: Guy Podjarny
    24
    http://www.guypo.com/mobile/javascript-pre-execution-for-mobile-taking-scripts-out-of-the-loop/

    View Slide

  25. mobify.com @mobify [email protected]
    Amount of JS
    25
    Phone slow JS execution. iPhone 4 -> iPhone 4s, 2x cpu, 15%
    better JS!

    View Slide

  26. 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.

    View Slide

  27. mobify.com @mobify [email protected]
    Layout reflow + Painting
    • Repaints -- also maybe raid some stuff from Ilya’s presentation
    27

    View Slide

  28. 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

    View Slide

  29. mobify.com @mobify [email protected]
    Making sites faster:
    strategy
    29

    View Slide

  30. 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.

    View Slide

  31. mobify.com @mobify [email protected]
    The Web of the Future
    Mobile First: Smartphone *and* Tablet
    31

    View Slide

  32. mobify.com @mobify [email protected]
    Mobile first!
    Image Credit: Brad Frost
    32

    View Slide

  33. mobify.com @mobify [email protected]
    Performance anti-
    patterns
    33

    View Slide

  34. 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.

    View Slide

  35. mobify.com @mobify [email protected]
    Anti-pattern: blocking JavaScript at the top of the document
    35

    View Slide

  36. mobify.com @mobify [email protected]
    Anti-pattern: Large library dependencies
    36

    View Slide

  37. 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!

    View Slide

  38. mobify.com @mobify [email protected]
    Performance
    patterns
    38

    View Slide

  39. 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

    View Slide

  40. 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.

    View Slide

  41. 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

    View Slide

  42. mobify.com @mobify [email protected]
    Pre-fetching
    Homepage
    Signup Studio Services
    DNS HTML JS
    CSS Images
    42

    View Slide

  43. 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)

    View Slide

  44. mobify.com @mobify [email protected]
    Making use of localStorage and “smart” caching: localStorage performance
    44
    Instantiating a 20kb javascript from localStorage

    View Slide

  45. mobify.com @mobify [email protected]
    Making use of localStorage and “smart” caching: native cache performance
    45

    View Slide

  46. 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

    View Slide

  47. 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

    View Slide

  48. mobify.com @mobify [email protected]
    Final thoughts
    48

    View Slide

  49. 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

    View Slide

  50. mobify.com @mobify [email protected]
    50

    View Slide

  51. mobify.com @mobify [email protected]
    Thank you!
    (are you a unicorn?
    we are hiring!)
    51

    View Slide