Inclure du javascript de
    manière performante




Jean-pierre VINCENT
Braincracking.org
Orateur
              Jean-pierre VINCENT

En ligne :
   •braincracking.org (veille)
   •twitter.com/theystolemynick
   •j...
Pourquoi ?


rendu rapide = argent




bit.ly/perfs_benefice
bit.ly/perfs_benefice2
Comment


Inclure JS de manière non bloquante

           (entre autres)
Le fautif
<script
src="my.js"></script>
</head>
Le fautif
<script
src="my.js"></script>
</head>

 •bloque ce qui vient après :
    •rendu
Le fautif
<script
src="my.js"></script>
</head>

 •bloque ce qui vient après :
    •rendu
    •exécution
Le fautif
<script
src="my.js"></script>
</head>

 •bloque ce qui vient après :
    •rendu
    •exécution
    •téléchargeme...
Le fautif
<script
src="my.js"></script>
</head>

 •bloque ce qui vient après :
    •rendu
    •exécution
    •téléchargeme...
exemple
réservation voyages-sncf.com :
   •HTML obtenu en 200ms (!)
exemple
réservation voyages-sncf.com :
   •HTML obtenu en 200ms (!)
   •certains CSS arrivent en 50ms (!!)
        (je vou...
exemple
réservation voyages-sncf.com :
   •HTML obtenu en 200ms (!)
   •certains CSS arrivent en 50ms (!!)
        (je vou...
Objectif

          remplacer
<script
src="my.js"></script>
</head>
Alternatives
•Inline
Alternatives
•Inline


•Bottom
Alternatives
•Inline


•Bottom


•DOM
Alternatives
que des désavantages
Alternatives
que des désavantages
        mais
Alternatives
 que des désavantages
         mais


non bloquant
      (= argent)
Inline
Inline

<script>
 <?php include('my.js'); ?>
</script>
</head>
Inline

✓ ordre d'exécution
Inline

✓ ordre d'exécution
✓ dépendances inline
Inline

✓ ordre d'exécution
✓ dépendances inline
✓ non bloquant (ou presque : bit.ly/inline_bloquant)
Inline

✓ ordre d'exécution
✓ dépendances inline
✓ non bloquant (ou presque : bit.ly/inline_bloquant)
✓ document.write()
Inline

✓ ordre d'exécution
✓ dépendances inline
✓ non bloquant (ou presque : bit.ly/inline_bloquant)
✓ document.write()
✓...
Inline

✓ ordre d'exécution
✓ dépendances inline
✓ non bloquant (ou presque : bit.ly/inline_bloquant)
✓ document.write()
✓...
Inline
Bon pour :

  •beaucoup de nouveaux visiteurs
Inline
Bon pour :

  •beaucoup de nouveaux visiteurs

  •peu de JS
Inline
Bon pour :

  •beaucoup de nouveaux visiteurs

  •peu de JS

  •bonne bande passante (France)
Inline
•évènementielle (jeux-concours)
Inline
•évènementielle (jeux-concours)

•Homepage, sans cookie
  •Google Search, Yahoo! (avant)
  •Netvibes, Facebook
Inline
•évènementielle (jeux-concours)

•Homepage, sans cookie
  •Google Search, Yahoo! (avant)
  •Netvibes, Facebook

•pa...
Bottom


<script
src="my.js"></script>
</body>
Bottom
Bottom

✓ ordre d'exécution
Bottom

✓ ordre d'exécution
✓ non bloquant
Bottom

✓ ordre d'exécution
✓ non bloquant
✓ mise en cache
Bottom

✓ ordre d'exécution
✓ non bloquant
✓ mise en cache


✗ dépendances inline
Bottom

✓ ordre d'exécution
✓ non bloquant
✓ mise en cache


✗ dépendances inline
✗ document.write()
Bottom
Bon pour les pages dont :
Bottom
Bon pour les pages dont :

  •le contenu textuel est primordial
Bottom
Bon pour les pages dont :

  •le contenu textuel est primordial
  •le HTML est rapide
Bottom
Bon pour les pages dont :

  •le contenu textuel est primordial
  •le HTML est rapide
  •reçoit des visiteurs zappe...
Bottom
Bon pour les pages dont :

  •le contenu textuel est primordial
  •le HTML est rapide
  •reçoit des visiteurs zappe...
Bottom
Type de pages :

  •Blogs, Journaux
Bottom
Type de pages :

  •Blogs, Journaux
  •Boutiques
Bottom
Type de pages :

  •Blogs, Journaux
  •Boutiques
  •Comparateurs
Bottom
Type de pages :

  •Blogs, Journaux
  •Boutiques
  •Comparateurs
  •...
Bottom - condition 1

 contenu principal envoyé
   en moins de 500ms ?
Bottom - condition 1

    contenu principal envoyé
      en moins de 500ms ?

•flush()
Bottom - condition 1

   contenu principal envoyé
     en moins de 500ms ?

•flush()
•cache serveur
Bottom - condition 1

   contenu principal envoyé
     en moins de 500ms ?

•flush()
•cache serveur
•en premier dans la so...
Bottom - condition 2
  dépendances JS inline
      correctibles ?
Bottom - condition 2
     dépendances JS inline
         correctibles ?

•mute + eval() : bit.ly/mute_eval
Bottom - condition 2
     dépendances JS inline
         correctibles ?

•mute + eval() : bit.ly/mute_eval

•hijacking
Bottom - condition 2
       dépendances JS inline
           correctibles ?

  •mute + eval() : bit.ly/mute_eval

  •hijac...
DOM
DOM
function loader(fCallback) {




}
DOM
function loader(fCallback) {
var oScript =
document
.getElementsByTagName("head")[0]
 .createElement('script');




}
DOM
function loader(fCallback) {
var oScript =
document
.getElementsByTagName("head")[0]
 .createElement('script');
oScrip...
DOM
function loader(fCallback) {
var oScript =
document
.getElementsByTagName("head")[0]
  .createElement('script');
oScri...
DOM
jQuery :
$.getScript(
  'my.js',
  fCallback);

YUI 3 :
Y.Get.script(
  'my.js',
   {onSuccess: fCallback} );
DOM

✓ non bloquant
DOM

✓ non bloquant
✓ mise en cache
DOM

✓ non bloquant
✓ mise en cache
✓ IE6-7 parallélise ! (bit.ly/dom_IE_para)
DOM

✓ non bloquant
✓ mise en cache
✓ IE6-7 parallélise ! (bit.ly/dom_IE_para)

✗ dépendances inline
DOM

✓ non bloquant
✓ mise en cache
✓ IE6-7 parallélise ! (bit.ly/dom_IE_para)

✗ dépendances inline
✗ document.write()
DOM

✓ non bloquant
✓ mise en cache
✓ IE6-7 parallélise ! (bit.ly/dom_IE_para)

✗ dépendances inline
✗ document.write()
✗ ...
DOM
Bon pour les pages :
DOM
Bon pour les pages :

  •éligibles à Bottom
DOM
Bon pour les pages :

     •éligibles à Bottom
     •HTML > 0.5 - 1s
ou
DOM
Bon pour les pages :

     •éligibles à Bottom
     •HTML > 0.5 - 1s
ou
     •gros volume de JS ( > 500k
     décompre...
DOM
Type de pages :

  •Blogs, Journaux
  •Boutiques
  •Comparateurs
  •...
DOM
Type de pages :

  •Blogs, Journaux
  •Boutiques
  •Comparateurs
  •...
  •Applications Web
DOM - préalable
Découper son JS en modules
DOM - préalable
Découper son JS en modules



1 module PHP = 1 fonctionalité = 1 JS

      lui donner un identifiant
DOM - préalable
✓ Découper son JS en modules

Centraliser les inclusions :

MY.loader =
    function(sScriptID, fCallback)...
DOM - préalable
✓ Découper son JS en modules

Centraliser les inclusions :

MY.loader =
    function(sScriptID, fCallback)...
DOM - préalable
✓ Découper son JS en modules
✓ Centraliser les inclusions
Corriger toutes ses dépendances :
<form id="logi...
DOM - préalable
✓ Découper son JS en modules
✓ Centraliser les inclusions
Corriger toutes ses dépendances :
<form id="logi...
DOM - préalable
✓ Découper son JS en modules
✓ Centraliser les inclusions
Corriger toutes ses dépendances :
<form id="logi...
DOM - préalable
✓ Découper son JS en modules
✓ Centraliser les inclusions
✓ Corriger toutes ses dépendances
DOM - préalable
✓ Découper son JS en modules
✓ Centraliser les inclusions
✓ Corriger toutes ses dépendances
✓ Concaténer l...
DOM - évolution
✓ Découper son JS en modules
✓ Centraliser les inclusions
✓ Corriger toutes ses dépendances
✓ Concaténer l...
DOM - évolution
✓ Découper son JS en modules
✓ Centraliser les inclusions
✓ Corriger toutes ses dépendances
✓ Concaténer l...
DOM - évolution
✓ Découper son JS en modules
✓ Centraliser les inclusions
✓ Corriger toutes ses dépendances
✓ Concaténer l...
Etude de cas
Netvibes :

  •inline : 100Ko de JS

  •DOM : 260Ko de JS

  •DOM : widget JS
Etude de cas
Facebook (Wall) :
Etude de cas
Facebook (Wall) :
  •flush() HTML presque vide
Etude de cas
Facebook (Wall) :
  •flush() HTML presque vide
  •inline : 1 loader DOM + 1 loader
  spécial (bigPipe : bit.l...
Etude de cas
Facebook (Wall) :
  •flush() HTML presque vide
  •inline : 1 loader DOM + 1 loader
  spécial (bigPipe : bit.l...
Etude de cas
Facebook (Wall) :
  •flush() HTML presque vide
  •inline : 1 loader DOM + 1 loader
  spécial (bigPipe : bit.l...
Etude de cas
Facebook (Wall) :
  •flush() HTML presque vide
  •inline : 1 loader DOM + 1 loader
  spécial (bigPipe : bit.l...
Etude de cas
YUI 3 :
Etude de cas
YUI 3 :

  •tout appel de code commence dans
  une fonction de callback
Etude de cas
YUI 3 :

  •tout appel de code commence dans
  une fonction de callback
  •liste manuelle des dépendances
Etude de cas
YUI 3 :

  •tout appel de code commence dans
  une fonction de callback
  •liste manuelle des dépendances
  •...
Etude de cas
YUI 3 :

  •tout appel de code commence dans
  une fonction de callback
  •liste manuelle des dépendances
  •...
Orateur
              Jean-pierre VINCENT

En ligne :
   •braincracking.org (veille)
   •twitter.com/theystolemynick
   •j...
Prochain SlideShare
Chargement dans…5
×

Inclure du Javascript de manière performante

3 422 vues

Publié le

slide de la mini conférence Performance du 21 juillet 2010
au menu : les 3 stratégies valables pour inclure son JS de manière non bloquante

Publié dans : Technologie
0 commentaire
2 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

Aucun téléchargement
Vues
Nombre de vues
3 422
Sur SlideShare
0
Issues des intégrations
0
Intégrations
1 130
Actions
Partages
0
Téléchargements
37
Commentaires
0
J’aime
2
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Inclure du Javascript de manière performante

  1. 1. Inclure du javascript de manière performante Jean-pierre VINCENT Braincracking.org
  2. 2. Orateur Jean-pierre VINCENT En ligne : •braincracking.org (veille) •twitter.com/theystolemynick •jp@vincent.net •google it : jpvincent 10 ans de Web dont : •3 ans de Yahoo! •2 ans d'application Web (timeofmylife.com)
  3. 3. Pourquoi ? rendu rapide = argent bit.ly/perfs_benefice bit.ly/perfs_benefice2
  4. 4. Comment Inclure JS de manière non bloquante (entre autres)
  5. 5. Le fautif <script src="my.js"></script> </head>
  6. 6. Le fautif <script src="my.js"></script> </head> •bloque ce qui vient après : •rendu
  7. 7. Le fautif <script src="my.js"></script> </head> •bloque ce qui vient après : •rendu •exécution
  8. 8. Le fautif <script src="my.js"></script> </head> •bloque ce qui vient après : •rendu •exécution •téléchargement
  9. 9. Le fautif <script src="my.js"></script> </head> •bloque ce qui vient après : •rendu •exécution •téléchargement •IE6-7 : un seul JS à la fois
  10. 10. exemple réservation voyages-sncf.com : •HTML obtenu en 200ms (!)
  11. 11. exemple réservation voyages-sncf.com : •HTML obtenu en 200ms (!) •certains CSS arrivent en 50ms (!!) (je voudrais bien jouer avec ce ping là)
  12. 12. exemple réservation voyages-sncf.com : •HTML obtenu en 200ms (!) •certains CSS arrivent en 50ms (!!) (je voudrais bien jouer avec ce ping là) •au final : 2s de page blanche #fail bit.ly/perfs_sncf
  13. 13. Objectif remplacer <script src="my.js"></script> </head>
  14. 14. Alternatives •Inline
  15. 15. Alternatives •Inline •Bottom
  16. 16. Alternatives •Inline •Bottom •DOM
  17. 17. Alternatives que des désavantages
  18. 18. Alternatives que des désavantages mais
  19. 19. Alternatives que des désavantages mais non bloquant (= argent)
  20. 20. Inline
  21. 21. Inline <script> <?php include('my.js'); ?> </script> </head>
  22. 22. Inline ✓ ordre d'exécution
  23. 23. Inline ✓ ordre d'exécution ✓ dépendances inline
  24. 24. Inline ✓ ordre d'exécution ✓ dépendances inline ✓ non bloquant (ou presque : bit.ly/inline_bloquant)
  25. 25. Inline ✓ ordre d'exécution ✓ dépendances inline ✓ non bloquant (ou presque : bit.ly/inline_bloquant) ✓ document.write()
  26. 26. Inline ✓ ordre d'exécution ✓ dépendances inline ✓ non bloquant (ou presque : bit.ly/inline_bloquant) ✓ document.write() ✓ pas de HTTP
  27. 27. Inline ✓ ordre d'exécution ✓ dépendances inline ✓ non bloquant (ou presque : bit.ly/inline_bloquant) ✓ document.write() ✓ pas de HTTP ✗ pas de cache
  28. 28. Inline Bon pour : •beaucoup de nouveaux visiteurs
  29. 29. Inline Bon pour : •beaucoup de nouveaux visiteurs •peu de JS
  30. 30. Inline Bon pour : •beaucoup de nouveaux visiteurs •peu de JS •bonne bande passante (France)
  31. 31. Inline •évènementielle (jeux-concours)
  32. 32. Inline •évènementielle (jeux-concours) •Homepage, sans cookie •Google Search, Yahoo! (avant) •Netvibes, Facebook
  33. 33. Inline •évènementielle (jeux-concours) •Homepage, sans cookie •Google Search, Yahoo! (avant) •Netvibes, Facebook •pages d'entrées •login •signup
  34. 34. Bottom <script src="my.js"></script> </body>
  35. 35. Bottom
  36. 36. Bottom ✓ ordre d'exécution
  37. 37. Bottom ✓ ordre d'exécution ✓ non bloquant
  38. 38. Bottom ✓ ordre d'exécution ✓ non bloquant ✓ mise en cache
  39. 39. Bottom ✓ ordre d'exécution ✓ non bloquant ✓ mise en cache ✗ dépendances inline
  40. 40. Bottom ✓ ordre d'exécution ✓ non bloquant ✓ mise en cache ✗ dépendances inline ✗ document.write()
  41. 41. Bottom Bon pour les pages dont :
  42. 42. Bottom Bon pour les pages dont : •le contenu textuel est primordial
  43. 43. Bottom Bon pour les pages dont : •le contenu textuel est primordial •le HTML est rapide
  44. 44. Bottom Bon pour les pages dont : •le contenu textuel est primordial •le HTML est rapide •reçoit des visiteurs zappeurs
  45. 45. Bottom Bon pour les pages dont : •le contenu textuel est primordial •le HTML est rapide •reçoit des visiteurs zappeurs •JS est secondaire mais lourd •publicités •widgets
  46. 46. Bottom Type de pages : •Blogs, Journaux
  47. 47. Bottom Type de pages : •Blogs, Journaux •Boutiques
  48. 48. Bottom Type de pages : •Blogs, Journaux •Boutiques •Comparateurs
  49. 49. Bottom Type de pages : •Blogs, Journaux •Boutiques •Comparateurs •...
  50. 50. Bottom - condition 1 contenu principal envoyé en moins de 500ms ?
  51. 51. Bottom - condition 1 contenu principal envoyé en moins de 500ms ? •flush()
  52. 52. Bottom - condition 1 contenu principal envoyé en moins de 500ms ? •flush() •cache serveur
  53. 53. Bottom - condition 1 contenu principal envoyé en moins de 500ms ? •flush() •cache serveur •en premier dans la source
  54. 54. Bottom - condition 2 dépendances JS inline correctibles ?
  55. 55. Bottom - condition 2 dépendances JS inline correctibles ? •mute + eval() : bit.ly/mute_eval
  56. 56. Bottom - condition 2 dépendances JS inline correctibles ? •mute + eval() : bit.ly/mute_eval •hijacking
  57. 57. Bottom - condition 2 dépendances JS inline correctibles ? •mute + eval() : bit.ly/mute_eval •hijacking Si non, modification du JS obligatoire
  58. 58. DOM
  59. 59. DOM function loader(fCallback) { }
  60. 60. DOM function loader(fCallback) { var oScript = document .getElementsByTagName("head")[0] .createElement('script'); }
  61. 61. DOM function loader(fCallback) { var oScript = document .getElementsByTagName("head")[0] .createElement('script'); oScript.src= 'my.js'; }
  62. 62. DOM function loader(fCallback) { var oScript = document .getElementsByTagName("head")[0] .createElement('script'); oScript.src= 'my.js'; oScript.onload = fCallback; oScript.onreadystatechange = fCallback; }
  63. 63. DOM jQuery : $.getScript( 'my.js', fCallback); YUI 3 : Y.Get.script( 'my.js', {onSuccess: fCallback} );
  64. 64. DOM ✓ non bloquant
  65. 65. DOM ✓ non bloquant ✓ mise en cache
  66. 66. DOM ✓ non bloquant ✓ mise en cache ✓ IE6-7 parallélise ! (bit.ly/dom_IE_para)
  67. 67. DOM ✓ non bloquant ✓ mise en cache ✓ IE6-7 parallélise ! (bit.ly/dom_IE_para) ✗ dépendances inline
  68. 68. DOM ✓ non bloquant ✓ mise en cache ✓ IE6-7 parallélise ! (bit.ly/dom_IE_para) ✗ dépendances inline ✗ document.write()
  69. 69. DOM ✓ non bloquant ✓ mise en cache ✓ IE6-7 parallélise ! (bit.ly/dom_IE_para) ✗ dépendances inline ✗ document.write() ✗ ordre d'exécution
  70. 70. DOM Bon pour les pages :
  71. 71. DOM Bon pour les pages : •éligibles à Bottom
  72. 72. DOM Bon pour les pages : •éligibles à Bottom •HTML > 0.5 - 1s ou
  73. 73. DOM Bon pour les pages : •éligibles à Bottom •HTML > 0.5 - 1s ou •gros volume de JS ( > 500k décompressé)
  74. 74. DOM Type de pages : •Blogs, Journaux •Boutiques •Comparateurs •...
  75. 75. DOM Type de pages : •Blogs, Journaux •Boutiques •Comparateurs •... •Applications Web
  76. 76. DOM - préalable Découper son JS en modules
  77. 77. DOM - préalable Découper son JS en modules 1 module PHP = 1 fonctionalité = 1 JS lui donner un identifiant
  78. 78. DOM - préalable ✓ Découper son JS en modules Centraliser les inclusions : MY.loader = function(sScriptID, fCallback) { };
  79. 79. DOM - préalable ✓ Découper son JS en modules Centraliser les inclusions : MY.loader = function(sScriptID, fCallback) { $.getScript( sScriptID+'.js', fCallback); };
  80. 80. DOM - préalable ✓ Découper son JS en modules ✓ Centraliser les inclusions Corriger toutes ses dépendances : <form id="login-form"> ... </form> <
  81. 81. DOM - préalable ✓ Découper son JS en modules ✓ Centraliser les inclusions Corriger toutes ses dépendances : <form id="login-form"> ... </form> <script> MY.enrichForm('login-form'); </script>
  82. 82. DOM - préalable ✓ Découper son JS en modules ✓ Centraliser les inclusions Corriger toutes ses dépendances : <form id="login-form"> ... </form> <script> MY.loader('login-js', function() { MY.enrichForm('login-form'); }); </script>
  83. 83. DOM - préalable ✓ Découper son JS en modules ✓ Centraliser les inclusions ✓ Corriger toutes ses dépendances
  84. 84. DOM - préalable ✓ Découper son JS en modules ✓ Centraliser les inclusions ✓ Corriger toutes ses dépendances ✓ Concaténer les fichiers communs
  85. 85. DOM - évolution ✓ Découper son JS en modules ✓ Centraliser les inclusions ✓ Corriger toutes ses dépendances ✓ Concaténer les fichiers communs Plus tard : •gérer les inclusions multiples
  86. 86. DOM - évolution ✓ Découper son JS en modules ✓ Centraliser les inclusions ✓ Corriger toutes ses dépendances ✓ Concaténer les fichiers communs Plus tard : •gérer les inclusions multiples Tactique YUI3 : •gérer dépendances entre classes
  87. 87. DOM - évolution ✓ Découper son JS en modules ✓ Centraliser les inclusions ✓ Corriger toutes ses dépendances ✓ Concaténer les fichiers communs Plus tard : •gérer les inclusions multiples Tactique YUI3 : •gérer dépendances entre classes •générer les JS à la volée
  88. 88. Etude de cas Netvibes : •inline : 100Ko de JS •DOM : 260Ko de JS •DOM : widget JS
  89. 89. Etude de cas Facebook (Wall) :
  90. 90. Etude de cas Facebook (Wall) : •flush() HTML presque vide
  91. 91. Etude de cas Facebook (Wall) : •flush() HTML presque vide •inline : 1 loader DOM + 1 loader spécial (bigPipe : bit.ly/fb_bigpipe)
  92. 92. Etude de cas Facebook (Wall) : •flush() HTML presque vide •inline : 1 loader DOM + 1 loader spécial (bigPipe : bit.ly/fb_bigpipe) •flush() des modules 1 par 1
  93. 93. Etude de cas Facebook (Wall) : •flush() HTML presque vide •inline : 1 loader DOM + 1 loader spécial (bigPipe : bit.ly/fb_bigpipe) •flush() des modules 1 par 1 •DOM :9 JS chargés (1 principal + 8 modules)
  94. 94. Etude de cas Facebook (Wall) : •flush() HTML presque vide •inline : 1 loader DOM + 1 loader spécial (bigPipe : bit.ly/fb_bigpipe) •flush() des modules 1 par 1 •DOM :9 JS chargés (1 principal + 8 modules) •meme technique pour CSS
  95. 95. Etude de cas YUI 3 :
  96. 96. Etude de cas YUI 3 : •tout appel de code commence dans une fonction de callback
  97. 97. Etude de cas YUI 3 : •tout appel de code commence dans une fonction de callback •liste manuelle des dépendances
  98. 98. Etude de cas YUI 3 : •tout appel de code commence dans une fonction de callback •liste manuelle des dépendances •le loader connait les dépendances et les fichiers déjà chargés
  99. 99. Etude de cas YUI 3 : •tout appel de code commence dans une fonction de callback •liste manuelle des dépendances •le loader connait les dépendances et les fichiers déjà chargés •coté serveur : un combinateur
  100. 100. Orateur Jean-pierre VINCENT En ligne : •braincracking.org (veille) •twitter.com/theystolemynick •jp@vincent.net •google it : jpvincent 10 ans de Web dont : •3 ans de Yahoo! •2 ans d'application Web (timeofmylife.com)

×