$30 off During Our Annual Pro Sale. View Details »

Optimiser les performances d'une webapp

Dev-Mind
April 05, 2017

Optimiser les performances d'une webapp

Avec les outils actuels, développer une application web (grand public ou privée), avec du JS en front et du Java en backend est de plus en plus rapide. Les premiers hics peuvent survenir le jour où vous basculez cette application en production.

Mon but est de vous montrer dans cette session, comment optimiser une webapp quelque soit les solutions techniques utilisées côté front ou côté serveur. Mes exemples se basent sur une application SpringBoot avec un frontend en JS (sans framework particulier) mais ceci est peu important. Nous allons nous focaliser sur les concepts qui restent vrais quelque soit les langages.

Nous verrons les différentes étapes pour améliorer la rapidité d'une application au premier chargement (load time), en mode offline, comment jouer sur le critical rendering... Au niveau des solutions nous parlerons cache, asynchronisme, services workers...

Conférence donnée à Devoxxfr http://cfp.devoxx.fr/2017/speaker/guillaume_ehret

Besoin d'une formation sur le sujet rendez vous sur https://www.dev-mind.fr

Dev-Mind

April 05, 2017
Tweet

More Decks by Dev-Mind

Other Decks in Technology

Transcript

  1. #DevoxxFR
    Optimiser les performances
    d’une webapp
    Guillaume EHRET
    @guillaumeehret
    #WebPerformance
    Jeudi 6 avril 2017

    View Slide

  2. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Guillaume EHRET
    @guillaumeehret
    #WebPerformance
    Optimiser les performances
    d’une webapp

    View Slide

  3. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Dev-Mind
    https://www.dev-mind.fr

    View Slide

  4. #WebPerformance / 6 avril 2017
    @guillaumeehret
    https://www.dev-mind.fr
    Développement
    Formations

    View Slide

  5. #WebPerformance / 6 avril 2017
    @guillaumeehret
    avec des crêpes et du coeur
    20 et 21 avril à Lyon
    https://mixitconf.org/

    View Slide

  6. #WebPerformance / 6 avril 2017
    @guillaumeehret
    #WebPerformance / 6 avril 2017
    @guillaumeehret
    Pourquoi une webapp doit
    être performante ?

    View Slide

  7. #WebPerformance / 6 avril 2017
    @guillaumeehret
    1
    2 3
    https://giphy.com

    View Slide

  8. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Mobile First
    mars 2017

    View Slide

  9. #WebPerformance / 6 avril 2017
    @guillaumeehret
    > 3 sec sur
    mobile

    57% des users
    en moins
    0 : 03
    DoubleClick, “The Need
    for Mobile Speed”,
    September 2016
    https://giphy.com

    View Slide

  10. #WebPerformance / 6 avril 2017
    @guillaumeehret

    View Slide

  11. #WebPerformance / 6 avril 2017
    @guillaumeehret

    View Slide

  12. #WebPerformance / 6 avril 2017
    @guillaumeehret

    View Slide

  13. #WebPerformance / 6 avril 2017
    @guillaumeehret
    2010 2017
    2016
    2015
    2014
    2013
    2012
    2011
    http://httparchive.org
    mars 2017

    View Slide

  14. #WebPerformance / 6 avril 2017
    @guillaumeehret
    3 Mb en 2017
    Wifi
    30Mb/s

    0.5 sec

    View Slide

  15. #WebPerformance / 6 avril 2017
    @guillaumeehret
    3 Mb en 2017
    Wifi
    30Mb/s

    0.5 sec
    4G
    4Mb/s

    5 sec
    H+
    1.5Mb/s

    10 sec
    3G
    750kb/s

    25 sec
    Webpagetest.org, , February 2016

    View Slide

  16. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Webpagetest.org, , February 2016
    Temps mobile
    10s
    3/4
    19s
    moy
    200
    moy
    Les performances sur mobile ne sont pas toujours au rendez vous

    View Slide

  17. #WebPerformance / 6 avril 2017
    @guillaumeehret
    #WebPerformance / 6 avril 2017
    @guillaumeehret
    Et les applications
    d’entreprise ?

    View Slide

  18. #WebPerformance / 6 avril 2017
    @guillaumeehret
    https://giphy.com

    View Slide

  19. #WebPerformance / 6 avril 2017
    @guillaumeehret

    View Slide

  20. #WebPerformance / 6 avril 2017
    @guillaumeehret

    View Slide

  21. #WebPerformance / 6 avril 2017
    @guillaumeehret
    #WebPerformance / 6 avril 2017
    @guillaumeehret
    Que faire pour créer des
    webapps performantes ?

    View Slide

  22. #WebPerformance / 6 avril 2017
    @guillaumeehret
    1 Mesurer
    Transport
    Limiter
    2
    3
    4 Cache
    Offline
    Anticiper
    5
    6

    View Slide

  23. #WebPerformance / 6 avril 2017
    @guillaumeehret
    1 Mesurer
    Transport
    Limiter
    2
    3
    4 Cache
    Offline
    Anticiper
    5
    6

    View Slide

  24. #WebPerformance / 6 avril 2017
    @guillaumeehret
    https://monsite/
    1

    View Slide

  25. #WebPerformance / 6 avril 2017
    @guillaumeehret
    https://monsite/
    HTML
    parsing
    1

    View Slide

  26. #WebPerformance / 6 avril 2017
    @guillaumeehret
    CSS
    parsing
    compile
    render
    parsing
    JavaScript
    Autres
    1

    View Slide

  27. #WebPerformance / 6 avril 2017
    @guillaumeehret
    parsing
    compile
    render
    JavaScript
    Autres
    parsing
    1
    CSS

    View Slide

  28. #WebPerformance / 6 avril 2017
    @guillaumeehret
    render
    JavaScript
    Autres
    1
    CSS

    View Slide

  29. #WebPerformance / 6 avril 2017
    @guillaumeehret
    loadtime
    https://monsite/
    HTML
    parsing
    parsing
    compile
    render
    JavaScript
    Autres
    CSS
    render
    JavaScript
    Autres
    CSS
    ...
    1

    View Slide

  30. #WebPerformance / 6 avril 2017
    @guillaumeehret
    first paint
    https://monsite/
    parsing
    parsing
    compile
    render
    JavaScript
    Autres
    CSS
    render
    JavaScript
    Autres
    CSS
    ...
    1
    HTML

    View Slide

  31. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Notre objectif < 1s
    first load
    1

    View Slide

  32. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Notre objectif
    first load refresh
    1
    < 1s

    View Slide

  33. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Notre objectif
    first load refresh offline
    1
    < 1s

    View Slide

  34. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Mes outils pour mesurer
    Webpagetest >>
    Pagespeed Insight >>
    Browser developper tools
    ...
    1

    View Slide

  35. #WebPerformance / 6 avril 2017
    @guillaumeehret
    1

    View Slide

  36. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Mobile
    Cache
    Throttling 3G
    1

    View Slide

  37. #WebPerformance / 6 avril 2017
    @guillaumeehret
    18.2s
    Load time
    loadtime
    1
    1.6Mb
    Size
    size

    View Slide

  38. #WebPerformance / 6 avril 2017
    @guillaumeehret
    first paint
    1
    7.4s
    first paint

    View Slide

  39. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Avant de commencer
    2
    7.4s
    first paint
    18.2s
    loadtime
    Sans optim
    1.6Mb
    size

    View Slide

  40. #WebPerformance / 6 avril 2017
    @guillaumeehret
    1 Mesurer
    Transport
    Limiter
    2
    3
    4 Cache
    Offline
    Anticiper
    5
    6
    2

    View Slide

  41. #WebPerformance / 6 avril 2017
    @guillaumeehret
    CSS
    JavaScript
    Autres
    HTML
    2

    View Slide

  42. #WebPerformance / 6 avril 2017
    @guillaumeehret






    JavaScript
    HTML
    2

    View Slide

  43. #WebPerformance / 6 avril 2017
    @guillaumeehret
    1
    7.4s
    first paint
    2

    View Slide

  44. #WebPerformance / 6 avril 2017
    @guillaumeehret
    2
    6.4s
    first paint

    View Slide

  45. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Ordre de définition des scripts JS
    2
    7.4s
    first paint
    18.2s
    loadtime
    Sans optim
    1.6Mb
    size
    6.4s
    first paint
    18.2s
    loadtime
    1.6Mb
    size
    -13.5%
    first paint
    0%
    loadtime
    0%
    size

    View Slide

  46. #WebPerformance / 6 avril 2017
    @guillaumeehret
    2

    View Slide

  47. #WebPerformance / 6 avril 2017
    @guillaumeehret
    2

    View Slide

  48. #WebPerformance / 6 avril 2017
    @guillaumeehret
    2
    HTTP2 côté client

    View Slide

  49. #WebPerformance / 6 avril 2017
    @guillaumeehret
    2
    HTTP2 et Java
    1. Container compatible Jetty 9.2, Undertow (JBoss) 1.3, Tomcat > 8.5
    2. Activer le mode HTTP 2
    3. Avoir un certificat
    4. Ajouter le jar ALPN au jdk (lib pour Jdk < 9)

    View Slide

  50. #WebPerformance / 6 avril 2017
    @guillaumeehret
    HTTP 2
    2
    6.4s
    first paint
    18.2s
    loadtime
    Ordre JS
    1.6Mb
    size
    6.4s
    first paint
    18.1s
    loadtime
    1.6Mb
    size
    0%
    first paint
    -0.5%
    loadtime
    0%
    size

    View Slide

  51. #WebPerformance / 6 avril 2017
    @guillaumeehret
    1 Mesurer
    Transport
    Limiter
    2
    3
    4 Cache
    Offline
    Anticiper
    5
    6
    2
    3

    View Slide

  52. #WebPerformance / 6 avril 2017
    @guillaumeehret
    3
    https://giphy.com

    View Slide

  53. #WebPerformance / 6 avril 2017
    @guillaumeehret
    3
    Minification ressources txt
    CSS
    JavaScript
    HTML

    View Slide

  54. #WebPerformance / 6 avril 2017
    @guillaumeehret
    3
    Minification ressources txt
    JavaScript
    HTML
    sur mon exemple
    -22%
    -51%
    -26%
    CSS

    View Slide

  55. #WebPerformance / 6 avril 2017
    @guillaumeehret
    3
    Le JSON est aussi du texte
    JSON

    View Slide

  56. #WebPerformance / 6 avril 2017
    @guillaumeehret
    3
    public class SessionDto {
    public String title;
    public String summary;
    public String lang;
    public String format;
    public String description;
    public Instant start;
    public Instant room;
    ...
    }
    des DTO qui collent à l’API

    View Slide

  57. #WebPerformance / 6 avril 2017
    @guillaumeehret
    3
    public class SessionDto {
    public String title;
    public String summary;
    public String lang;
    public String format;
    public String description;
    public Instant start;
    public Instant room;
    ...
    }
    public class SessionListDto {
    public String title;
    public String summary;
    ...
    }
    des DTO qui collent à l’API

    View Slide

  58. #WebPerformance / 6 avril 2017
    @guillaumeehret
    3
    Le JSON est aussi du texte
    -80%
    JSON

    View Slide

  59. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Minification du texte
    6.4s
    first paint
    18.1s
    loadtime
    HTTP2
    1.6Mb
    size
    5.5s
    first paint
    15.4s
    loadtime
    1.3Mb
    size
    -14%
    first paint
    -15%
    loadtime
    -19%
    size
    3

    View Slide

  60. #WebPerformance / 6 avril 2017
    @guillaumeehret
    3
    Le texte se compresse
    CSS JavaScript
    HTML JSON
    les navigateurs acceptent le gzip

    View Slide

  61. #WebPerformance / 6 avril 2017
    @guillaumeehret
    3
    Le texte se compresse
    JavaScript
    HTML JSON
    server:
    compression:
    enabled: true
    mime-types: application/json,text/html,text/css,application/javascript
    min-response-size: 2048
    CSS

    View Slide

  62. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Compression du texte
    5.5s
    first paint
    15.4s
    loadtime
    Minification
    1.3Mb
    size
    1.5s
    first paint
    10.8s
    loadtime
    940Kb
    size
    -72%
    first paint
    -30%
    loadtime
    -28%
    size
    3

    View Slide

  63. #WebPerformance / 6 avril 2017
    @guillaumeehret
    CSS
    JavaScript
    Autres
    HTML
    3

    View Slide

  64. #WebPerformance / 6 avril 2017
    @guillaumeehret
    #WebPerformance / 6 avril 2017
    @guillaumeehret
    CSS

    View Slide

  65. #WebPerformance / 6 avril 2017
    @guillaumeehret
    CSS 3

    View Slide

  66. #WebPerformance / 6 avril 2017
    @guillaumeehret
    3
    https://giphy.com
    CSS

    View Slide

  67. #WebPerformance / 6 avril 2017
    @guillaumeehret
    3
    Material Design Lite
    185kb
    228kb
    203kb
    20kb
    Les frameworks CSS
    CSS
    CSS +JS
    CSS +JS
    CSS +JS
    CSS
    JS
    JS
    JQuery
    69kb
    JQuery
    69kb

    View Slide

  68. #WebPerformance / 6 avril 2017
    @guillaumeehret
    3
    Quelques astuces
    Modularité frameworks
    Apprenez CSS CSS is awesome de Igor Laborie
    Nettoyage automatique avec uncss
    CSS

    View Slide

  69. #WebPerformance / 6 avril 2017
    @guillaumeehret
    3
    UnCSS
    return gulp.src(`${paths.main}/**/*.css`)
    .pipe($.if('*.css', $.uncss({
    html : [
    `${paths.main}/*.html`,
    `${paths.main}/component/**/*.html`,
    `${paths.main}/component/**/*.js`]
    })))
    .pipe(gulp.dest(`${paths.dist}/styles`));
    CSS

    View Slide

  70. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Utilisation UnCSS
    1.5s
    first paint
    10.8s
    loadtime
    Compression
    940Kb
    size
    0.5s
    first paint
    10.4s
    loadtime
    920Kb
    size
    -67%
    first paint
    -3.7%
    loadtime
    -2.1%
    size
    3
    CSS

    View Slide

  71. #WebPerformance / 6 avril 2017
    @guillaumeehret
    #WebPerformance / 6 avril 2017
    @guillaumeehret
    Images
    3

    View Slide

  72. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Compression imagemin
    0.5s
    first paint
    10.4s
    loadtime
    UnCss
    920Kb
    size
    0.5s
    first paint
    8.5s
    loadtime
    735Kb
    size
    0%
    first paint
    -18%
    loadtime
    -20%
    size
    3
    Images

    View Slide

  73. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Préférez le vectoriel
    3
    svg
    png, jpg
    Images

    View Slide

  74. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Jpeg XR
    3
    Images

    View Slide

  75. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Webp
    3
    Images

    View Slide

  76. #WebPerformance / 6 avril 2017
    @guillaumeehret
    la balise perdue
    3
    Des images responsives en HTML avec la balise
    et la propriété srcset
    Images

    View Slide

  77. #WebPerformance / 6 avril 2017
    @guillaumeehret
    3
    Images
    Images

    View Slide

  78. #WebPerformance / 6 avril 2017
    @guillaumeehret
    propriété srcset
    3
    srcset="img/mixit/mixit-amphi_640.jpg 640w,
    img/mixit/mixit-amphi_1024.jpg 1024w,
    img/mixit/mixit-amphi_2048.jpg">
    la largeur de la fenêtre nombre entier suivi par 'w' (640w), par défaut c’est l’infini
    la densité de pixel nombre entier suivi par 'x' (2x), par défaut c’est 1x.
    Images

    View Slide

  79. #WebPerformance / 6 avril 2017
    @guillaumeehret
    3

    type="image/webp"/>



    Images

    View Slide

  80. #WebPerformance / 6 avril 2017
    @guillaumeehret
    format webp
    3
    0.5s
    first paint
    8.5s
    loadtime
    imagemin
    735Kb
    size
    0.5s
    first paint
    6.7s
    loadtime
    572Kb
    size
    0%
    first paint
    -21%
    loadtime
    -22%
    size
    Images

    View Slide

  81. #WebPerformance / 6 avril 2017
    @guillaumeehret
    #WebPerformance / 6 avril 2017
    @guillaumeehret
    Fonts
    3

    View Slide

  82. #WebPerformance / 6 avril 2017
    @guillaumeehret
    #WebPerformance / 6 avril 2017
    @guillaumeehret
    Utilisez le moins de font
    possible
    3

    View Slide

  83. #WebPerformance / 6 avril 2017
    @guillaumeehret
    3
    Fonts
    Format Extension
    Exemple
    Font
    Roboto
    Compression
    EOT .eot 179 ko
    TrueType .ttf 179 ko
    WOFF .woff 89 ko >10
    WOFF2 .woff2 64ko 30% + que WOFF >10 >10
    SVG .svg 743 ko
    IE
    Edge
    Firefox
    Chrome
    Safari
    Opera
    Opera Mini
    Android Browser
    iOS Safari
    Chrome for Android

    View Slide

  84. #WebPerformance / 6 avril 2017
    @guillaumeehret
    3
    @font-face {
    font-family: Roboto;
    src: local('Roboto'),
    url(../fonts/Roboto-Regular.woff2) format('woff2'),
    url(../fonts/Roboto-Regular.woff) format('woff'),
    url(../fonts/Roboto-Regular.eot),
    url(../fonts/Roboto-Regular.ttf) format('truetype'),
    url(../fonts/Roboto-Regular.svg#Roboto) format('svg');
    font-weight: 300;
    font-style: normal
    }
    body {
    font-family: Roboto, Arial, sans-serif;
    }
    Fonts

    View Slide

  85. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Utiliser un CDN
    3
    href="https://fonts.googleapis.com/css?family=Roboto"
    rel="stylesheet">
    Fonts

    View Slide

  86. #WebPerformance / 6 avril 2017
    @guillaumeehret
    CDN pour les fonts
    3
    0.5s
    first paint
    6.7s
    loadtime
    webp
    572Kb
    size
    440ms
    first paint
    3.4s
    loadtime
    231Kb
    size
    -12%
    first paint
    -49%
    loadtime
    -59%
    size
    Fonts

    View Slide

  87. #WebPerformance / 6 avril 2017
    @guillaumeehret
    #WebPerformance / 6 avril 2017
    @guillaumeehret
    JavaScript
    3

    View Slide

  88. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Polyfill sur CDN
    3
    src="https://cdn.polyfill.io/v2/polyfill.min.js">

    Size (min) 1370 8212 464 26430 6652
    Size (min+gz) 514 2435 285 8497 2018
    JavaScript

    View Slide

  89. #WebPerformance / 6 avril 2017
    @guillaumeehret
    CDN JS
    3
    440ms
    first paint
    3.4s
    loadtime
    CDN font
    231Kb
    size
    440ms
    first paint
    2.9s
    loadtime
    200Kb
    size
    0%
    first paint
    -15%
    loadtime
    -13%
    size
    JavaScript

    View Slide

  90. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Mais encore
    3
    Tree shaking
    SSR
    Code splitting (modules)
    Pré compilation
    ...
    JavaScript

    View Slide

  91. #WebPerformance / 6 avril 2017
    @guillaumeehret
    1 Mesurer
    Transport
    Limiter
    2
    3
    4 Cache
    Offline
    Anticiper
    5
    6
    2
    4
    3

    View Slide

  92. #WebPerformance / 6 avril 2017
    @guillaumeehret
    #WebPerformance / 6 avril 2017
    @guillaumeehret
    La ressource la plus rapide et la
    mieux optimisée est une
    ressource qui n'est pas envoyée.
    4

    View Slide

  93. #WebPerformance / 6 avril 2017
    @guillaumeehret
    4
    App Data

    View Slide

  94. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Cache serveur
    Cloud base de données ou I/O
    Temps fluctuant
    Abtraction Spring @Cacheable
    4

    View Slide

  95. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Cache ressource
    4
    Browser
    Server
    Cache
    Request

    View Slide

  96. #WebPerformance / 6 avril 2017
    @guillaumeehret
    4
    Browser
    Cache
    Server
    Response

    View Slide

  97. #WebPerformance / 6 avril 2017
    @guillaumeehret
    4
    Browser
    Cache
    Server
    Response

    View Slide

  98. #WebPerformance / 6 avril 2017
    @guillaumeehret
    4
    Browser
    Server
    Cache
    Si max-age n’est pas dépassé

    View Slide

  99. #WebPerformance / 6 avril 2017
    @guillaumeehret
    4
    Browser
    Cache
    Server
    Response

    View Slide

  100. #WebPerformance / 6 avril 2017
    @guillaumeehret
    4
    Browser
    Server
    Cache
    Si max-age n’est pas dépassé

    View Slide

  101. #WebPerformance / 6 avril 2017
    @guillaumeehret
    4
    Browser
    Server
    Cache
    Si max-age est dépassé
    Request

    View Slide

  102. #WebPerformance / 6 avril 2017
    @guillaumeehret
    4
    Browser
    Cache
    Server
    Response
    304

    View Slide

  103. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Refresh / Cache
    440ms
    first paint
    2.9s
    loadtime
    First load
    200Kb
    size
    427ms
    first paint
    700ms
    loadtime
    18Kb
    size
    -3%
    first paint
    -75%
    loadtime
    -91%
    size
    4

    View Slide

  104. #WebPerformance / 6 avril 2017
    @guillaumeehret
    1 Mesurer
    Transport
    Limiter
    2
    3
    4 Cache
    Offline
    Anticiper
    5
    6
    2
    4
    3
    5

    View Slide

  105. #WebPerformance / 6 avril 2017
    @guillaumeehret
    5
    https://giphy.com

    View Slide

  106. #WebPerformance / 6 avril 2017
    @guillaumeehret
    4
    5

    View Slide

  107. #WebPerformance / 6 avril 2017
    @guillaumeehret
    #WebPerformance / 6 avril 2017
    @guillaumeehret
    Services workers
    4
    5

    View Slide

  108. #WebPerformance / 6 avril 2017
    @guillaumeehret
    4
    5

    View Slide

  109. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Web workers
    4
    5

    View Slide

  110. #WebPerformance / 6 avril 2017
    @guillaumeehret
    4
    5

    View Slide

  111. #WebPerformance / 6 avril 2017
    @guillaumeehret
    4
    5
    var worker = new Worker('doWork.js');
    worker.addEventListener('message', (e) => {
    console.log('Worker said: ', e.data);
    }, false);
    worker.postMessage('Hello World');
    self.addEventListener('message',(e) => {
    self.postMessage(e.data);
    }, false);
    doWork.js

    View Slide

  112. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Service worker
    5
    JS SW
    cache

    View Slide

  113. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Service worker
    5
    SW
    cache
    HTTPS
    JS

    View Slide

  114. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Service worker
    5
    sw-precache module node générant la configuration
    sw-toolbox lib JS qui fournit des utilitaires pour gérer le
    cache avec différentes stratégies :
    networkFirst, cacheFirst, fastest, cacheOnly, networkOnly

    View Slide

  115. #WebPerformance / 6 avril 2017
    @guillaumeehret
    5
    SW
    cache
    JS
    networkFirst
    cacheFirst
    fastest
    cacheOnly
    networkOnly

    View Slide

  116. #WebPerformance / 6 avril 2017
    @guillaumeehret
    5
    gulp.task('generate-service-worker', function(callback) {
    let config = {
    cacheId: 'dev-mind',
    runtimeCaching: [{
    urlPattern: '/(.*)',
    handler: 'networkFirst',
    options : {
    networkTimeoutSeconds: 2,
    maxAgeSeconds: 43200
    }
    }],
    staticFileGlobs: [ `${paths.dist}/**/*.{js,html,css,png,jpg,json,gif,svg,webp,woff2}`],
    stripPrefix: `${paths.dist}/`,
    verbose: true
    };
    swPrecache.write(`${paths.tmp}/service-worker.js`, config, callback);
    });

    View Slide

  117. #WebPerformance / 6 avril 2017
    @guillaumeehret
    5
    if ('serviceWorker' in navigator) {
    navigator
    .serviceWorker
    .register('service-worker.js')
    .then(registration => {
    if (typeof registration.update === 'function') {
    registration.update();
    }
    })
    .catch(function(e) {
    console.error('Error during SW registration:', e);
    });
    }

    View Slide

  118. #WebPerformance / 6 avril 2017
    @guillaumeehret
    5

    View Slide

  119. #WebPerformance / 6 avril 2017
    @guillaumeehret
    1 Mesurer
    Transport
    Limiter
    2
    3
    4 Cache
    Offline
    Anticiper
    5
    6

    View Slide

  120. #WebPerformance / 6 avril 2017
    @guillaumeehret
    #WebPerformance / 6 avril 2017
    @guillaumeehret
    Charger le plus important tout
    de suite et le reste plus tard

    View Slide

  121. #WebPerformance / 6 avril 2017
    @guillaumeehret
    6
    preload

    View Slide

  122. #WebPerformance / 6 avril 2017
    @guillaumeehret
    6
    preload
    onload="this.rel='stylesheet'">
    as="document">

    View Slide

  123. #WebPerformance / 6 avril 2017
    @guillaumeehret
    prefetch
    6

    View Slide

  124. #WebPerformance / 6 avril 2017
    @guillaumeehret
    prefetch
    6
    href="https://fonts.googleapis.com/css?family=Roboto:400"
    onload="this.rel='stylesheet'">

    View Slide

  125. #WebPerformance / 6 avril 2017
    @guillaumeehret
    preload / prefecth
    440ms
    first paint
    2.9s
    loadtime
    First load
    200Kb
    size
    300ms
    first paint
    2.9s
    loadtime
    200Kb
    size
    -31%
    first paint
    0%
    loadtime
    0%
    size
    4

    View Slide

  126. #WebPerformance / 6 avril 2017
    @guillaumeehret
    1 Mesurer
    Transport
    Limiter
    2
    3
    4 Cache
    Offline
    Anticiper
    5
    6

    View Slide

  127. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Notre objectif
    first load refresh offline
    1
    < 1s
    7.4s
    first paint
    18.2s
    loadtime
    1.6Mb
    size
    Départ

    View Slide

  128. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Notre objectif
    first load refresh offline
    1
    < 1s
    300ms
    first paint
    2.9s
    loadtime
    200Kb
    size
    220ms
    700ms
    18Kb
    first paint
    loadtime
    size
    17ms
    1.2s
    0Kb
    first paint
    loadtime
    size
    7.4s
    first paint
    18.2s
    loadtime
    1.6Mb
    size
    Départ

    View Slide

  129. #WebPerformance / 6 avril 2017
    @guillaumeehret
    https://github.com/Dev-Mind/devoxx2017

    View Slide

  130. #WebPerformance / 6 avril 2017
    @guillaumeehret
    Référence
    https://developers.google.com/web/fundamentals/performance
    https://github.com/ben-eb/gulp-uncss
    https://github.com/filamentgroup/loadCSS
    https://medium.com/reloading/preload-prefetch-and-priorities-in-chrome-776165961bbf
    https://nolanlawson.github.io/frontendday-2016/#1
    https://www.youtube.com/watch?v=RWLzUnESylc
    https://github.com/GoogleChrome/sw-precache
    https://github.com/GoogleChrome/sw-toolbox
    https://developer.mozilla.org/fr/docs/Web/API/ServiceWorker
    https://jakearchibald.com/2014/offline-cookbook/

    View Slide

  131. #WebPerformance / 6 avril 2017
    @guillaumeehret
    #WebPerformance / 6 avril 2017
    @guillaumeehret
    First do it, then do it right, then
    do it better...
    Addy Osmani

    View Slide

  132. #WebPerformance / 6 avril 2017
    @guillaumeehret
    https://github.com/Dev-Mind/devoxx2017
    Thanks

    View Slide