259 votes

Séquence de chargement et d'exécution d'une page web ?

J'ai réalisé quelques projets basés sur le web, mais je ne pense pas trop à la séquence de chargement et d'exécution d'une page web ordinaire. Mais maintenant, j'ai besoin de connaître les détails. Il est difficile de trouver des réponses dans Google ou SO, alors j'ai créé cette question.

Un exemple de page se présente comme suit :

<html>
 <head>
  <script src="jquery.js" type="text/javascript"></script>
  <script src="abc.js" type="text/javascript">
  </script>
  <link rel="stylesheets" type="text/css" href="abc.css"></link>
  <style>h2{font-wight:bold;}</style>
  <script>
  $(document).ready(function(){
     $("#img").attr("src", "kkk.png");
  });
 </script>
 </head>
 <body>
    <img id="img" src="abc.jpg" style="width:400px;height:300px;"/>
    <script src="kkk.js" type="text/javascript"></script>
 </body>
</html>

Voici donc mes questions :

  1. Comment cette page se charge-t-elle ?
  2. Quelle est la séquence du chargement ?
  3. Quand le code JS est-il exécuté ? (en ligne et externe)
  4. Quand le CSS est-il exécuté (appliqué) ?
  5. Quand est-ce que $(document).ready est exécuté ?
  6. Est-ce que abc.jpg sera téléchargé ? Ou est-ce qu'il télécharge seulement kkk.png ?

J'ai la compréhension suivante :

  1. Le navigateur charge d'abord le html (DOM).
  2. Le navigateur commence à charger les ressources externes de haut en bas, ligne par ligne.
  3. Si un <script> est respectée, le chargement sera bloqué et attendra que le fichier JS soit chargé et exécuté, puis continuera.
  4. Les autres ressources (CSS/images) sont chargées en parallèle et exécutées si nécessaire (comme les CSS).

Ou est-ce que c'est comme ça :

Le navigateur analyse le code html (DOM) et récupère les ressources externes dans un tableau ou une structure en forme de pile. Une fois le html chargé, le navigateur commence à charger les ressources externes dans la structure en parallèle et les exécute, jusqu'à ce que toutes les ressources soient chargées. Ensuite, le DOM sera modifié en fonction des comportements de l'utilisateur selon le JS.

Quelqu'un peut-il donner une explication détaillée de ce qui se passe lorsque vous obtenez la réponse d'une page html ? Cela varie-t-il selon les différents navigateurs ? Des références sur cette question ?

Gracias.

EDITAR:

J'ai fait une expérience dans Firefox avec Firebug. Et cela donne l'image suivante : alt text

11 votes

Steve Souders a réalisé de nombreux travaux dans ce domaine. Recherchez steve+souders+high+performance sur Google et jetez-y un œil.

3 votes

Je ne parle pas d'optimisation des performances. Je veux connaître les détails.

2 votes

En lisant son travail, ma compréhension de la façon dont "ça" fonctionne en détail a été décuplée, donc c'est toujours un commentaire valable. Je ne suis pas autorisé par les droits d'auteur à citer l'intégralité de son livre ici, je vous suggère donc de consulter son ouvrage.

288voto

mauris Points 19666

Selon votre échantillon,

<html>
 <head>
  <script src="jquery.js" type="text/javascript"></script>
  <script src="abc.js" type="text/javascript">
  </script>
  <link rel="stylesheets" type="text/css" href="abc.css"></link>
  <style>h2{font-wight:bold;}</style>
  <script>
  $(document).ready(function(){
     $("#img").attr("src", "kkk.png");
  });
 </script>
 </head>
 <body>
    <img id="img" src="abc.jpg" style="width:400px;height:300px;"/>
    <script src="kkk.js" type="text/javascript"></script>
 </body>
</html>

En gros, le flux d'exécution est à peu près le suivant :

  1. Le document HTML est téléchargé
  2. L'analyse du document HTML commence
  3. Parsing HTML atteint <script src="jquery.js" ...
  4. jquery.js est téléchargé et analysé
  5. L'analyse HTML est atteinte <script src="abc.js" ...
  6. abc.js est téléchargé, analysé et exécuté
  7. L'analyse HTML est atteinte <link href="abc.css" ...
  8. abc.css est téléchargé et analysé
  9. L'analyse HTML est atteinte <style>...</style>
  10. Les règles CSS internes sont analysées et définies
  11. L'analyse HTML est atteinte <script>...</script>
  12. Le Javascript interne est analysé et exécuté
  13. Parsing HTML atteint <img src="abc.jpg" ...
  14. abc.jpg est téléchargé et affiché
  15. Parsing HTML atteint <script src="kkk.js" ...
  16. kkk.js est téléchargé, analysé et exécuté
  17. Analyse syntaxique des fins de document HTML

Notez que le téléchargement peut être asynchrone et non bloquant en raison des comportements du navigateur. Par exemple, dans Firefox, il y a ce paramètre qui limite le nombre de requêtes simultanées par domaine.

De plus, selon que le composant a déjà été mis en cache ou non, il se peut que le composant ne soit pas demandé à nouveau lors d'une prochaine demande. Si le composant a été mis en cache, il sera chargé à partir du cache au lieu de l'URL actuelle.

Lorsque l'analyse syntaxique est terminée et que le document est prêt et chargé, les événements suivants se produisent onload est tiré. Ainsi, lorsque onload est tirée, la $("#img").attr("src","kkk.png"); est exécuté. Donc :

  1. Le document est prêt, le chargement est déclenché.
  2. Hits d'exécution Javascript $("#img").attr("src", "kkk.png");
  3. kkk.png est téléchargé et chargé dans #img

El $(document).ready() est en fait l'événement déclenché lorsque tous les composants de la page sont chargés et prêts. Pour en savoir plus : [http://docs.jquery.com/Tutorials:Introducing\_$(document).ready()](http://docs.jquery.com/Tutorials:Introducing_$(document).ready())

Edit - Cette partie développe davantage la partie parallèle ou non :

Par défaut, et d'après ma compréhension actuelle, le navigateur exécute généralement chaque page de 3 façons : Analyseur HTML, Javascript/DOM, et CSS.

L'analyseur HTML est responsable de l'analyse et de l'interprétation du langage de balisage et doit donc être capable de faire des appels aux deux autres composants.

Par exemple, lorsque l'analyseur syntaxique tombe sur cette ligne :

<a href="#" onclick="alert('test');return false;" style="font-weight:bold">a hypertext link</a>

L'analyseur fera 3 appels, deux à Javascript et un à CSS. Premièrement, l'analyseur créera cet élément et l'enregistrera dans l'espace de noms DOM, avec tous les attributs liés à cet élément. Deuxièmement, l'analyseur syntaxique appellera pour lier l'événement onclick à cet élément particulier. Enfin, il fera un autre appel au fil CSS pour appliquer le style CSS à cet élément particulier.

L'exécution est descendante et monofilaire. Javascript peut sembler multithreadé, mais le fait est que Javascript est single threadé. C'est pourquoi, lors du chargement d'un fichier javascript externe, l'analyse de la page HTML principale est suspendue.

Cependant, les fichiers CSS peuvent être téléchargés simultanément car les règles CSS sont toujours appliquées - c'est-à-dire que les éléments sont toujours repeints avec les règles CSS les plus récentes définies - ce qui permet de débloquer la situation.

Un élément ne sera disponible dans le DOM qu'après avoir été analysé. Ainsi, lorsqu'on travaille avec un élément spécifique, le script est toujours placé après, ou dans l'événement onload de la fenêtre.

Un script comme celui-ci provoquera une erreur (sur jQuery) :

<script type="text/javascript">/* <![CDATA[ */
  alert($("#mydiv").html());
/* ]]> */</script>
<div id="mydiv">Hello World</div>

Parce que lorsque le script est analysé, #mydiv n'est toujours pas défini. A la place, ceci fonctionnerait :

<div id="mydiv">Hello World</div>
<script type="text/javascript">/* <![CDATA[ */
  alert($("#mydiv").html());
/* ]]> */</script>

OU

<script type="text/javascript">/* <![CDATA[ */
  $(window).ready(function(){
                    alert($("#mydiv").html());
                  });
/* ]]> */</script>
<div id="mydiv">Hello World</div>

4 votes

Merci. Mais vous avez mentionné Le téléchargement peut être asynchrone et non bloquant en raison du comportement du navigateur. Quel type de composants peut être téléchargé en asynchrone (en prenant FF comme exemple) ? <script> bloquera les autres composants, n'est-ce pas ? Avez-vous des références sur les spécifications de chaque navigateur ?

5 votes

$(document).ready() est déclenché lorsque le DOM est complet, et non lorsque tous les composants de la page sont chargés.

2 votes

@Pierre par composants de page je voulais dire le DOM -> n'importe quels composants dans le DOM.

36voto

1) Le HTML est téléchargé.

2) Le HTML est analysé progressivement. Lorsqu'une demande pour un actif est atteinte, le navigateur tente de télécharger l'actif. La configuration par défaut de la plupart des serveurs HTTP et des navigateurs consiste à ne traiter que deux demandes en parallèle. IE peut être reconfiguré pour télécharger un nombre illimité de ressources en parallèle. Steve Souders a pu télécharger plus de 100 demandes en parallèle sur IE. L'exception est que les demandes script bloquent les demandes d'actifs en parallèle dans IE. C'est pourquoi il est fortement conseillé de placer tout le JavaScript dans des fichiers JavaScript externes et de placer la demande juste avant la balise de fermeture body dans le HTML.

3) Une fois le HTML analysé, le DOM est rendu. Le CSS est rendu en parallèle avec le rendu du DOM dans presque tous les agents utilisateurs. Par conséquent, il est fortement recommandé de placer tout le code CSS dans des fichiers CSS externes qui sont demandés le plus haut possible dans la section <head></head> du document. Sinon, la page est rendue jusqu'à l'occurrence de la position de la requête CSS dans le DOM, puis le rendu recommence depuis le début.

4) Ce n'est qu'une fois que le DOM est complètement rendu et que les requêtes pour tous les actifs de la page sont soit résolues, soit expirées, que JavaScript s'exécute à partir de l'événement onload. IE7, et je ne suis pas sûr pour IE8, ne fait pas expirer les actifs rapidement si une réponse HTTP n'est pas reçue pour la demande d'actifs. Cela signifie qu'un actif demandé par du JavaScript en ligne dans la page, c'est-à-dire du JavaScript écrit dans des balises HTML qui n'est pas contenu dans une fonction, peut empêcher l'exécution de l'événement onload pendant des heures. Ce problème peut être déclenché si un tel code en ligne existe dans la page et ne parvient pas à s'exécuter en raison d'une collision d'espaces de noms qui provoque un plantage du code.

Parmi les étapes ci-dessus, celle qui est la plus gourmande en ressources CPU est l'analyse du DOM/CSS. Si vous voulez que votre page soit traitée plus rapidement, écrivez un CSS efficace en éliminant les instructions redondantes et en consolidant les instructions CSS dans le moins de références d'éléments possible. La réduction du nombre de nœuds dans votre arbre DOM permettra également d'obtenir un rendu plus rapide.

N'oubliez pas que chaque ressource que vous demandez à partir de votre HTML ou même de vos ressources CSS/JavaScript est demandée avec un en-tête HTTP distinct. Cela consomme de la bande passante et nécessite un traitement par requête. Si vous voulez que votre page se charge aussi rapidement que possible, réduisez le nombre de requêtes HTTP et la taille de votre HTML. Vous ne rendez pas service à l'utilisateur si le poids moyen d'une page est de 180k pour le seul HTML. De nombreux développeurs sont persuadés qu'un utilisateur se fait une idée de la qualité du contenu de la page en 6 nanosecondes, puis supprime la requête DNS de son serveur et brûle son ordinateur s'il n'est pas satisfait, alors ils préfèrent fournir la plus belle page possible avec 250k de HTML. Gardez votre HTML court et agréable afin que l'utilisateur puisse charger vos pages plus rapidement. Rien n'améliore l'expérience de l'utilisateur comme une page Web rapide et réactive.

2 votes

consolider les instructions CSS en réduisant au maximum le nombre de références aux éléments Cela semble bizarre. Si je dois styliser trois éléments, je dois référencer exactement trois éléments. Je ne peux pas faire référence à un élément pour en styliser dix, n'est-ce pas ? Ou bien vous pouvez développer ce point.

12voto

tahdhaze09 Points 1699

Ouvrez votre page dans Firefox et obtenez l'addon HTTPFox. Il vous dira tout ce dont vous avez besoin.

J'ai trouvé ça sur archivist.incuito :

http://archivist.incutio.com/viewlist/css-discuss/76444

Lorsque vous demandez une page pour la première fois, votre navigateur envoie une requête GET au serveur, qui renvoie le HTML au navigateur. Le navigateur commence alors à l'analyse de la page (éventuellement avant que tout avant qu'elle n'ait été renvoyée dans son intégralité).

Lorsqu'il trouve une référence à une entité externe telle qu'un fichier CSS, un fichier image, un fichier script, un fichier Flash ou tout autre élément externe à la la page (que ce soit sur le même serveur/domaine ou non), il se prépare à faire une autre demande GET pour cette ressource.

Cependant, la norme HTTP spécifie que le navigateur ne doit pas faire plus de plus de deux requêtes simultanées vers le même domaine. Il place donc chaque requête à un domaine particulier dans une file d'attente, et au fur et à mesure que chaque entité est retournée, il commence la suivante dans la file d'attente pour ce domaine.

Le temps qu'il faut pour qu'une entité soit d'une entité dépend de sa taille, de la charge actuelle du serveur serveur et de l'activité de chaque chaque machine entre la machine exécutant le navigateur et le serveur. La liste de ces machines peut en principe être différente pour chaque requête, dans la mesure où une image peut voyager des États-Unis jusqu'à moi au Royaume-Uni en passant par l'Atlantique, tandis que une autre provenant du même serveur sort via le Pacifique, l'Asie et l'Europe, ce qui prend plus de temps. Vous pouvez donc obtenir une comme la séquence suivante, où une page contient (dans cet ordre) des références à trois fichiers script, et cinq fichiers d'image tous de tailles différentes :

  1. GET script1 et script2 ; demande de file d'attente pour le script3 et les images1-5.
  2. Le script2 arrive (il est plus petit que le script1) : GET script3, file d'attente images1-5.
  3. Le script1 arrive ; GET image1, file d'attente images2-5.
  4. image1 arrive, GET image2, file d'attente images3-5.
  5. Le script3 n'arrive pas en raison d'un problème de réseau - RECOUVREZ le script3. (nouvelle tentative automatique).
  6. image2 arrive, script3 n'est toujours pas là ; GET image3, file d'attente images4-5.
  7. l'image 3 arrive ; GET image4, file d'attente image5, script3 toujours en route.
  8. image4 arrive, GET image5 ;
  9. L'image5 arrive.
  10. Le script3 arrive.

En bref : n'importe quel ordre, en fonction de ce que fait le serveur, ce que fait le ce que fait le reste de l'Internet, et si quelque chose a des erreurs ou pas et doit être réinitialisé. Cela peut sembler être une façon bizarre de faire les choses, mais il serait littéralement impossible pour l'Internet (pas pas seulement le WWW) de fonctionner avec un quelconque degré de fiabilité si ce n'était pas fait de cette de cette façon.

De plus, la file d'attente interne du navigateur du navigateur peut ne pas récupérer les entités dans l'ordre dans l'ordre où elles apparaissent dans la page. aucune norme ne l'exige.

(Oh, et n'oubliez pas la mise en cache, à la fois dans le le navigateur et dans les proxys de mise en cache utilisés par les FAI pour alléger la charge sur le réseau).

5voto

a paid nerd Points 11716

Si vous posez cette question parce que vous voulez accélérer votre site web, consultez la page de Yahoo sur Meilleures pratiques pour accélérer votre site Web . Il contient un grand nombre de bonnes pratiques pour accélérer votre site Web.

2voto

Rolf Points 922

À ma connaissance, le navigateur (au moins Firefox) demande chaque ressource dès qu'il l'analyse. S'il rencontre une balise img, il demandera cette image dès que la balise img aura été analysée. Et cela peut se produire avant même qu'il ait reçu la totalité du document HTML... c'est-à-dire qu'il pourrait être en train de télécharger le document HTML à ce moment-là.

Pour Firefox, il y a des files d'attente de navigateur qui s'appliquent, selon la façon dont elles sont définies dans about:config. Par exemple, il ne tentera pas de télécharger plus de 8 fichiers à la fois à partir du même serveur... les demandes supplémentaires seront mises en file d'attente. Je pense qu'il y a des limites par domaine, par proxy, et d'autres choses, qui sont documentées sur le site de Mozilla et peuvent être définies dans about:config. J'ai lu quelque part qu'IE n'avait pas de telles limites.

L'événement jQuery ready est déclenché dès que le document HTML principal a été téléchargé et son DOM analysé. Ensuite, l'événement load est déclenché une fois que toutes les ressources liées (CSS, images, etc.) ont été téléchargées et analysées également. La documentation de jQuery est claire à ce sujet.

Si vous voulez contrôler l'ordre dans lequel tout cela est chargé, je pense que le moyen le plus fiable de le faire est le JavaScript.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X