J'ai fait des projets 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 de SO, alors j'ai créé cette question.
Un exemple de page ressemble à 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>
Donc, voici mes questions:
J'ai la compréhension suivante:
<script>
est rencontré, le chargement sera bloqué et attendra que le fichier JS soit chargé et exécuté, puis continuera.Ou est-ce comme ça:
Le navigateur analyse le code HTML (DOM) et récupère 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 de ce qui se passe lorsque vous avez la réponse d'une page HTML? Est-ce que cela varie selon les navigateurs? Toute référence à cette question?
Merci.
MODIFIER:
J'ai fait une expérience dans Firefox avec Firebug. Et cela montre l'image suivante:
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:
<script src="jquery.js" ...
jquery.js
est téléchargé et analysé<script src="abc.js" ...
abc.js
est téléchargé, analysé et exécuté<link href="abc.css" ...
abc.css
est téléchargé et analysé<style>...</style>
<script>...</script>
<img src="abc.jpg" ...
abc.jpg
est téléchargé et affiché<script src="kkk.js" ...
kkk.js
est téléchargé, analysé et exécutéNotez que le téléchargement peut être asynchrone et non bloquant en raison des comportements du navigateur. Par exemple, dans Firefox, ce paramètre limite le nombre de demandes simultanées par domaine.
De plus, selon que le composant a déjà été mis en cache ou non, il est possible que le composant ne soit plus demandé dans une demande future. 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 que le document est prêt et chargé, les événements onload
sont déclenchés. Ainsi, lorsque onload
est déclenché, la $("#img").attr("src","kkk.png");
est exécutée. Alors:
$("#img").attr("src", "kkk.png");
kkk.png
est téléchargé et chargé dans #img
L'événement $(document).ready()
est en réalité 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) .ready ()
Par défaut, et d'après ce que je comprends actuellement, le navigateur exécute 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. Il doit donc être capable d'appeler les 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 effectuera 3 appels, deux en Javascript et un en CSS. Tout d’abord, l’analyseur créera cet élément et l’enregistrera dans l’espace de noms DOM, avec tous les attributs associés à cet élément. Deuxièmement, l'analyseur appellera pour lier l'événement onclick à cet élément particulier. Enfin, il faudra faire un autre appel au thread CSS pour appliquer le style CSS à cet élément particulier.
L'exécution est top down et single threaded. Javascript peut sembler multi-threadé, mais le fait est que Javascript est mono-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. Cela signifie que les éléments sont toujours repeints avec les règles CSS les plus récentes, ce qui permet de les débloquer.
Un élément ne sera disponible dans le DOM qu'après son analyse. 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 cela fonctionnerait:
<div id="mydiv">Hello World</div>
<script type="text/javascript">/* <![CDATA[ */
alert($("#mydiv").html());
/* ]]> */</script>
OR
<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'actif est atteinte, le navigateur tente de télécharger l'actif. Une configuration par défaut pour 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é d’actifs 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 de script bloquent les demandes d'actifs parallèles dans IE. C'est pourquoi il est fortement recommandé de placer tout le JavaScript dans des fichiers JavaScript externes et de placer la demande juste avant la balise body de fermeture dans le code HTML.
3) Une fois que le HTML est analysé, le DOM est rendu. CSS est rendu parallèlement au rendu du DOM dans presque tous les agents utilisateurs. Par conséquent, il est vivement recommandé de placer tout le code CSS dans des fichiers CSS externes demandés aussi haut que 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 à partir du haut.
4) Ce n'est qu'après que le DOM est complètement restitué et que les demandes de tous les actifs de la page sont résolues ou que le délai d'expiration JavaScript s'exécute à partir de l'événement onload. IE7, et je ne suis pas sûr pour IE8, n'expire pas rapidement les ressources si une réponse HTTP n'est pas reçue à partir de la demande d'actif. Cela signifie qu'une ressource demandée par JavaScript en ligne dans la page, c'est-à-dire que le code JavaScript écrit dans des balises HTML non 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 parvient pas à s'exécuter en raison d'une collision entre espaces de noms provoquant un blocage du code.
Parmi les étapes ci-dessus, celle qui consomme le plus de ressources en processeur est l'analyse du DOM/CSS. Si vous souhaitez 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ément possibles. Réduire le nombre de nœuds dans votre arborescence DOM produira également un rendu plus rapide.
N'oubliez pas que chaque actif que vous demandez à votre HTML ou même à vos actifs CSS/JavaScript est demandé avec un en-tête HTTP distinct. Cela consomme de la bande passante et nécessite un traitement à la demande. Si vous souhaitez que votre page se charge le plus rapidement possible, réduisez le nombre de requêtes HTTP et la taille de votre code HTML. Vous ne faites pas de cadeau à votre expérience utilisateur en calculant le poids moyen d'une page à 180 Ko à partir de HTML seul. De nombreux développeurs souscrivent à l’erreur selon laquelle un utilisateur prend une décision en 6 nanosecondes sur la qualité du contenu de la page, puis purge la requête DNS de son serveur et grave son ordinateur si cela ne lui plaît pas. 250k de HTML. Gardez votre code HTML court et simple afin qu'un utilisateur puisse charger vos pages plus rapidement. Rien n'améliore l'expérience de l'utilisateur, à la différence d'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 archivist.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 fichier navigateur. Le navigateur démarre alors analyser la page (éventuellement avant tout de celle-ci a été renvoyée).
Quand il trouve une référence à un entité externe telle qu'un fichier CSS, un fichier fichier image, un fichier script, un fichier Flash fichier, ou tout autre élément externe à la page (sur le même serveur/domaine .__ ou non), elle se prépare à faites une autre demande GET pour cela Ressource.
Cependant, le standard HTTP spécifie que le navigateur ne devrait pas en faire plus que deux demandes simultanées au même domaine. Donc, il met chaque demande dans un domaine particulier d'une file d'attente, et lorsque chaque entité est renvoyée, elle commence le prochain dans la file d'attente pour cela domaine.
Le temps qu'il faut à une entité pour être retourné dépend de sa taille, le charger le serveur est actuellement l'expérience, et l'activité de chaque machine entre le 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ù celle-ci l'image pourrait voyager des États-Unis à moi au Royaume-Uni sur l'Atlantique, alors que un autre du même serveur sort via le Pacifique, l’Asie et l’Europe, ce qui prend plus de temps. Donc, vous pourriez obtenir un séquence comme celle-ci, où a page a (dans cet ordre) références à trois fichiers de script et cinq images des fichiers de tailles différentes:
- GET 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 ne parvient pas à arriver en raison d'un problème de réseau - GET script3 à nouveau (nouvelle tentative automatique).
- image2 arrive, le script3 n'est toujours pas là; GET image3, file d'attente images4-5.
- l'image 3 arrive; GET image4, file d'attente image5, script3 toujours en route.
- image4 arrive, GET image5;
- image5 arrive.
- script3 arrive.
En bref: n'importe quel ordre ancien, dépendant de ce que fait le serveur, ce que le reste de l'Internet fait, et si quelque chose a ou non des erreurs et doit être récupéré. Ceci peut semble être une façon bizarre de faire choses, mais ce serait littéralement être impossible pour Internet (pas seulement le WWW) de fonctionner avec n'importe quel degré de fiabilité si ce n’était pas fait cela façon.
En outre, la file d'attente interne du navigateur pourrait ne pas récupérer les entités dans l'ordre ils apparaissent dans la page - ce n'est pas requis par n'importe quelle norme.
(Oh, et n'oubliez pas la mise en cache, à la fois dans Du navigateur et dans les proxy de mise en cache Utilisés par les FAI pour alléger la charge du réseau )
Si vous demandez ceci parce que vous souhaitez accélérer votre site Web, consultez la page de Yahoo sur Meilleures pratiques pour accélérer votre site Web Il contient de nombreuses meilleures pratiques pour accélérer votre site Web.
Dynatrace AJAX Edition vous indique la séquence exacte du chargement, de l'analyse et de l'exécution de la page.
Autant que je sache, 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 faire avant même qu’il ait reçu la totalité du document HTML ... c’est-à-dire qu’il pourrait toujours télécharger le document HTML à ce moment-là.
Pour Firefox, des files d’attente de navigateur s’appliquent, en fonction de leur configuration dans about: config. Par exemple, il ne tentera pas de télécharger plus de 8 fichiers simultanément sur le même serveur ... les demandes supplémentaires seront mises en file d'attente. Je pense qu'il existe des limites par domaine, par proxy et autres, 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 prêt jQuery est déclenché dès que le document HTML principal a été téléchargé et analysé dans le DOM. Ensuite, l'événement de chargement est déclenché une fois que toutes les ressources liées (CSS, images, etc.) ont été téléchargées et analysées. Cela est précisé dans la documentation de jQuery.
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 d'utiliser JavaScript.
La réponse choisie semble ne pas s'appliquer aux navigateurs modernes, du moins sur Firefox 52. Ce que j'ai observé, c'est que les requêtes de chargement de ressources comme css, javascript sont émises avant que l'analyseur HTML n'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 découvert, c’est que l’heure de début des demandes de chargement de 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 code HTML.