Séquence de chargement et d'exécution d'une page web?
J'ai fait 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 de Google ou plus, alors j'ai créé cette question.
Un exemple de page est comme ceci:
<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:
- Comment cette page se charge-t-elle?
- Quelle est la séquence du chargement?
- Quand le code JS est-il exécuté? (en ligne et externe)
- Quand est le CSS exécuté (appliqué)?
- Quand $(document).prêt exécuté?
- Sera abc.jpg être téléchargé? Ou est-ce juste télécharger kkk.png?
J'ai la compréhension suivante:
- le navigateur charge le html (DOM) au début.
- le navigateur commence à charger les ressources externes de haut en bas, ligne par ligne.
- Si un
<script>
est atteint, le chargement sera bloqué et attendra que le fichier JS soit chargé et exécuté, puis continuer. - les autres ressources (CSS / images) sont chargées en parallèle et exécutées si nécessaire (comme CSS).
Ou est-ce comme ceci:
Le navigateur analyse le html (DOM) et obtient les ressources externes dans une structure de type tableau ou pile. Une fois le code html chargé, le navigateur commence à charger les ressources externes de la structure en parallèle et à s'exécuter, jusqu'à ce que toutes les ressources soient chargées. Ensuite, le DOM sera modifié en fonction des comportements de l'utilisateur en fonction du JS.
Quelqu'un peut-il donner une explication détaillée sur ce qui se passe lorsque vous avez la réponse d'une page html? Est-ce que cela varie dans différents navigateurs? Toute référence à cette question?
Merci.
Modifier:
J'ai fait une expérience dans Firefox avec Firebug. Et il montre comme l'image suivante:
7 réponses
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>
À peu près le flux d'exécution est à peu près comme suit:
- le document HTML est téléchargé
- l'analyse du document HTML démarre
- L'analyse HTML atteint
<script src="jquery.js" ...
-
jquery.js
est téléchargé et analysé - L'analyse HTML atteint
<script src="abc.js" ...
-
abc.js
est téléchargé, analysé et exécuté - L'analyse HTML atteint
<link href="abc.css" ...
-
abc.css
est téléchargé et analysé - l'analyse HTML atteint
<style>...</style>
- les règles CSS internes sont analysées et définies
- L'analyse HTML atteint
<script>...</script>
- Javascript interne est analysé et exécuté
- L'analyse HTML atteint
<img src="abc.jpg" ...
-
abc.jpg
est téléchargé et affiché - L'analyse HTML atteint
<script src="kkk.js" ...
-
kkk.js
est téléchargé, analysé et exécuté - l'analyse du document HTML se termine
Notez que le téléchargement peut être asynchrone et non bloquant en raison des comportements du navigateur. Pour par exemple, dans Firefox il y a ce paramètre qui limite le nombre de requêtes simultanées par domaine.
En outre, selon que le composant a déjà été mis en cache ou non, le composant peut ne pas être demandé à nouveau dans une requête proche. Si le composant a été mis en cache, le composant sera chargé à partir du cache au lieu de L'URL réelle.
Lorsque l'analyse est terminée et le document est prêt et chargé, les événements onload
est déclenché. Ainsi, lorsque onload
est tiré, le $("#img").attr("src","kkk.png");
est exécuté. Donc:
- le Document est prêt, onload est déclenché.
- l'exécution Javascript frappe
$("#img").attr("src", "kkk.png");
-
{[21] } est téléchargé et chargé dans
#img
L'événement $(document).ready()
est en fait l'événement déclenché lorsque tous les composants de la page sont chargés et prêts. En savoir plus à ce sujet: http://docs.jquery.com/Tutorials:Introducing_ $ (document).prêt()
Edit - cette partie développe plus sur la partie parallèle ou non:
Par défaut, et de mon 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 2 autres composants.
Par exemple, lorsque l'analyseur rencontre cette ligne:
<a href="#" onclick="alert('test');return false;" style="font-weight:bold">a hypertext link</a>
L'analyseur fera 3 appels, deux vers Javascript et un vers CSS. Tout d'abord, l'analyseur va créer cet élément et l'enregistrer dans L'espace de noms DOM, avec tous les attributs liés à cet élément. Deuxièmement, l'analyseur appellera pour lier l'événement onclick à cet élément particulier. Enfin, il fera un autre appel au thread CSS pour appliquer le style CSS à cet élément particulier.
L'exécution est de haut en bas et mono-thread. Javascript peut sembler multi-thread, mais le fait est que Javascript est single thread. C'est pourquoi, lors du chargement du 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-ce qui signifie que les éléments sont toujours repeints avec les règles css les plus récentes définies-ce qui en fait un déblocage.
Un élément ne sera disponible dans le DOM qu'après avoir été analysé. Ainsi, lorsque vous travaillez avec un élément spécifique, le script est toujours placé après ou dans l'événement window onload.
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é, l'élément #mydiv
n'est toujours pas défini. Au lieu de cela 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>
1) HTML est téléchargé.
2) HTML est analysé progressivement. Lorsqu'une demande d'un actif est atteinte, le navigateur tente de télécharger l'actif. Une configuration par défaut pour la plupart des serveurs HTTP et la plupart des navigateurs est de traiter seulement deux requêtes en parallèle. IE peut être reconfiguré pour télécharger un nombre illimité d'actifs en parallèle. Steve Souders a été en mesure de télécharger plus de 100 demandes en parallèle sur IE. L'exception est que les requêtes de script bloquent l'actif parallèle les demandes dans IE. C'est pourquoi il est fortement suggéré de mettre tout JavaScript dans des fichiers JavaScript externes et de placer la requête juste avant la balise de corps de fermeture dans le HTML.
3) Une fois le code HTML analysé, le DOM est rendu. CSS est rendu en parallèle au rendu du DOM dans presque tous les agents utilisateurs. Par conséquent, il est fortement recommandé de mettre tout le code CSS dans des fichiers CSS externes qui sont demandés le plus haut possible dans la section
du document. Sinon, l' la page est rendue jusqu'à l'occurrence de la position de la requête CSS dans le DOM, puis le rendu commence par le haut.4) Ce N'est qu'après que le DOM est complètement rendu et que les demandes pour tous les actifs de la page sont résolues ou que JavaScript s'exécute à partir de L'événement onload. IE7, et je ne suis pas sûr de IE8, ne temporise pas rapidement les actifs si une réponse HTTP n'est pas reçue de la demande d'actif. Cela signifie un actif demandé par JavaScript en ligne sur la page, c'est-à-dire JavaScript écrit dans des balises HTML qui ne sont pas contenues 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 s'exécute pas en raison d'une collision d'espace de noms qui provoque un plantage de code.
Parmi les étapes ci-dessus, celle qui nécessite le plus de CPU est l'analyse du DOM/CSS. Si vous souhaitez que votre page soit traitée plus rapidement écrivez des CSS efficaces en éliminant les instructions redondantes et en consolidant Instructions CSS dans le moins de références d'éléments possibles. La réduction du nombre de nœuds dans votre arborescence DOM produira également un rendu plus rapide.
Gardez à l'esprit 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 séparé. Cela consomme de la bande passante et nécessite un traitement par requête. Si vous voulez charger votre page aussi rapidement que possible, réduisez le nombre de requêtes HTTP et réduisez la taille de votre HTML. Vous êtes ne pas faire de votre expérience utilisateur des faveurs en faisant la moyenne du poids de la page à 180k à partir de HTML seul. De nombreux développeurs souscrivent à une erreur selon laquelle un utilisateur se décide sur la qualité du contenu de la page en 6 nanosecondes, puis purge la requête DNS de son serveur et brûle son ordinateur en cas de mécontentement, donc ils fournissent la plus belle page possible à 250k de HTML. Gardez votre HTML court et doux afin qu'un utilisateur puisse charger vos pages plus rapidement. Rien n'améliore l'expérience utilisateur comme une page Web rapide et réactive.
Ouvrez votre page dans Firefox et obtenez L'addon HTTPFox. Il vous dira tout ce dont vous avez besoin.
Trouvé ceci sur archiviste.incuito:
Http://archivist.incutio.com/viewlist/css-discuss/76444
Lorsque vous demandez une page pour la première fois, votre le navigateur envoie une requête GET au serveur, qui renvoie le code HTML au navigateur. Le navigateur démarre alors analyser la page (peut-être avant tout il a été retournés).
Quand il trouve une référence à un entité externe telle qu'un fichier CSS, un fichier image, un fichier de script, un Flash fichier, ou toute autre chose externe à la page (soit sur le même serveur/domaine ou non), il se prépare à faites une autre demande GET pour cela ressources.
Cependant, la norme HTTP spécifie que le navigateur ne devrait pas faire plus plus de deux demandes simultanées au même domaine. Donc, il met chaque demande à un domaine particulier dans une file d'attente, et lorsque chaque entité est renvoyée elle démarre le suivante dans la file d'attente pour que domaine.
Le temps qu'il faut pour qu'une entité soit retourné dépend de sa taille, de la charger le serveur est actuellement éprouver, et l'activité de chaque machine unique entre le la machine exécutant le navigateur et le serveur. La liste de ces machines peut en principe être différent pour chaque demande, dans la mesure où un image pourrait voyager des Etats-Unis pour moi AU ROYAUME-UNI sur L'Atlantique, tandis que un autre du même serveur sortir via le Pacifique, L'Asie et L'Europe, qui prend plus de temps. Alors vous pourriez obtenir un séquence comme suit, où un page a (dans cet ordre) références à trois fichiers de script, et cinq image fichiers, tous de tailles différentes:
- récupère script1 et script2; demande de file d'attente pour script3 et images1-5.
- script2 arrive (il est plus petit que script1): GET script3, file d'attente images1-5.
- script1 arrive; GET image1, file d'attente images2-5.
- image1 arrive, GET image2, file d'attente images3-5.
- script3 échoue à arriver en raison d'un problème réseau-récupère script3 à nouveau (nouvelle tentative automatique).
- image2 arrive, script3 toujours pas ici; GET image3, file d'attente images4-5.
- l'image 3 arrive; obtenez image4, file d'attente image5, script3 toujours en chemin.
- image4 arrive, GET image5;
- image5 arrive.
- script3 arrive.
En bref: tout ancien ordre, selon ce que l' le serveur fait, ce que le reste de l'Internet est en train de faire, et si oui ou non quelque chose a des erreurs et à re-cheveux. Cela peut on dirait une façon bizarre de faire choses, mais il serait tout à fait littéralement être impossible pour Internet (PAS juste le WWW) pour travailler avec n'importe quel degré de fiabilité si ce n'était pas fait façon.
En outre, la file d'attente interne du navigateur peut ne pas récupérer les entités dans l'ordre ils apparaissent dans la page - ce n'est pas requis par toute norme.
(Oh, et n'oubliez pas la mise en cache, à la fois dans le navigateur et dans les proxies de mise en cache utilisé par les FAI pour alléger la charge sur le réseau.)
Si vous demandez cela parce que vous voulez accélérer votre site web, consultez la page de Yahoo sur Les meilleures pratiques pour accélérer votre Site web . Il a beaucoup de meilleures pratiques pour accélérer votre site web.
Dynatrace AJAX Edition vous montre la séquence exacte du chargement, de l'analyse et de l'exécution de la page.
AFAIK, 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 a été analysée. Et cela peut être avant même qu'il ait reçu la totalité du document HTML... c'est-à-dire qu'il pourrait toujours être en train de télécharger le document HTML lorsque cela se produit.
Pour Firefox, il existe des files d'attente de navigateur qui s'appliquent, en fonction de 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 limites de proxy, et d'autres choses, qui sont documentées sur le site Web de Mozilla et peuvent être définies dans about:config. J'ai lu quelque part que IE n'a 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 QU'il est DOM analysé. Ensuite, l'événement load est déclenché une fois toutes les ressources liées (css, images,etc.) ont été téléchargé et analysé aussi bien. Il est clairement indiqué dans la documentation jQuery.
Si vous voulez contrôler l'ordre dans lequel tout ce qui est chargé, je crois que le moyen le plus fiable de le faire est via JavaScript.
La réponse choisie ressemble à ne s'applique pas aux navigateurs modernes, au moins sur Firefox 52. Ce que j'ai observé, c'est que les demandes de chargement de ressources comme css, javascript sont émises avant que L'analyseur HTML atteigne l'élément, par exemple
<html>
<head>
<!-- prints the date before parsing and blocks HTMP parsering -->
<script>
console.log("start: " + (new Date()).toISOString());
for(var i=0; i<1000000000; i++) {};
</script>
<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>
Ce que j'ai trouvé que l'Heure de début des demandes de chargement des ressources CSS et javascript n'était pas bloquée. On dirait que Firefox a une analyse HTML et identifie les ressources clés(la ressource img n'est pas incluse) avant de commencer à analyser le HTML.