Lorsqu'une page Web contient un seul fichier CSS et une image, pourquoi les navigateurs et les serveurs perdent-ils du temps avec cet itinéraire prenant beaucoup de temps:
- Le navigateur envoie une requête GET initiale pour la page Web et attend la réponse du serveur.
- Le navigateur envoie une autre requête GET pour le fichier css et attend la réponse du serveur.
- Le navigateur envoie une autre requête GET pour le fichier image et attend la réponse du serveur.
Quand au lieu de cela pourraient-ils utiliser cet itinéraire court, direct et rapide?
- Le navigateur envoie une demande GET pour une page Web.
- Le serveur Web répond avec ( index.html suivi de style.css et image.jpg )
Réponses:
La réponse courte est "Parce que HTTP n'a pas été conçu pour cela".
Tim Berners-Lee n'a pas conçu de protocole réseau efficace et extensible. Son objectif de conception était la simplicité. (Le professeur de ma classe de réseautage à l'université a dit qu'il aurait dû laisser le travail à des professionnels.) Le problème que vous décrivez n'est qu'un des nombreux problèmes du protocole HTTP. Dans sa forme originale:
Le protocole a ensuite été révisé pour résoudre bon nombre de ces problèmes:
GET /foo.html HTTP/1.1
Connection: keep-alive
À ce stade, HTTP a été utilisé aussi loin que possible sans que la compatibilité avec les versions précédentes ne soit brisée.
Vous n'êtes pas la première personne à suggérer qu'une page et toutes ses ressources soient transmises au client. En fait, Google a conçu un protocole appelé SPDY, capable de le faire .
Aujourd'hui, à la fois Chrome et Firefox peuvent utiliser SPDY au lieu de HTTP pour les serveurs qui le prennent en charge. Depuis le site Web de SPDY, ses principales caractéristiques par rapport à HTTP sont les suivantes:
Si vous souhaitez que votre site Web avec SPDY soit utilisé par les navigateurs qui le prennent en charge, vous pouvez le faire. Par exemple, Apache a mod_spdy .
SPDY est devenu la base de HTTP version 2 avec la technologie push serveur.
la source
Votre navigateur Web ne connaît pas les ressources supplémentaires jusqu'à ce qu'il télécharge la page Web (HTML) à partir du serveur, qui contient les liens vers ces ressources.
Vous vous demandez peut-être pourquoi le serveur n'analyse pas simplement son propre code HTML et n'envoie pas toutes les ressources supplémentaires au navigateur Web lors de la demande initiale de la page Web. Cela s'explique par le fait que les ressources peuvent être réparties sur plusieurs serveurs et que le navigateur Web n'a peut-être pas besoin de toutes ces ressources car il en a déjà mis en cache ou peut ne pas les prendre en charge.
Le navigateur Web conserve un cache de ressources afin qu'il ne soit pas obligé de télécharger sans cesse les mêmes ressources depuis les serveurs qui les hébergent. Lorsque vous naviguez sur différentes pages d'un site Web qui utilisent toutes la même bibliothèque jQuery, vous ne souhaitez pas télécharger cette bibliothèque à chaque fois, mais pour la première fois.
Ainsi, lorsque le navigateur Web récupère une page Web du serveur, il vérifie les ressources liées qu'il n'a PAS déjà dans le cache, puis effectue des demandes HTTP supplémentaires pour ces ressources. Assez simple, très flexible et extensible.
Un navigateur Web peut généralement faire deux demandes HTTP en parallèle. Cela ressemble à AJAX: ce sont deux méthodes asynchrones de chargement de pages Web: le chargement de fichier asynchrone et le chargement de contenu asynchrone. Avec keep-alive , nous pouvons faire plusieurs demandes en utilisant une seule connexion, et avec le traitement en pipeline, nous pouvons faire plusieurs demandes sans attendre les réponses. Ces deux techniques sont très rapides car la majeure partie des frais généraux provient généralement de l'ouverture / la fermeture de connexions TCP:
Un peu d'histoire web ...
Les pages Web ont débuté sous la forme de courriers électroniques en texte brut, les systèmes informatiques étant conçus autour de cette idée, formant une plate-forme de communication assez libre pour tous; Les serveurs Web étaient encore propriétaires à l'époque. Plus tard, davantage de couches ont été ajoutées à la "spécification de courrier électronique" sous la forme de types MIME supplémentaires, tels que des images, des styles, des scripts, etc. Après tout, MIME signifie Extension de messagerie Internet polyvalente . Tôt ou tard, nous avons eu essentiellement des communications par courrier électronique multimédia, des serveurs Web normalisés et des pages Web.
À mesure que la technologie évolue, elle doit permettre aux développeurs d'incorporer progressivement de nouvelles fonctionnalités sans compromettre les logiciels existants. Par exemple, lorsqu'un nouveau type MIME est ajouté à la spécification - disons JPEG -, les serveurs Web et les navigateurs Web mettront un certain temps à l'implémenter. Vous ne forcez pas soudainement JPEG dans la spécification et ne commencez pas à l'envoyer à tous les navigateurs Web, vous autorisez le navigateur Web à demander les ressources qu'il prend en charge, ce qui satisfait tout le monde et fait progresser la technologie. Un lecteur d'écran a-t-il besoin de tous les JPEG d'une page Web? Probablement pas. Devez-vous être obligé de télécharger un ensemble de fichiers Javascript si votre appareil ne prend pas en charge Javascript? Probablement pas. Googlebot doit-il télécharger tous vos fichiers Javascript pour pouvoir indexer votre site correctement? Nan.
Source: J'ai développé un serveur Web basé sur des événements, tel que Node.js. C'est ce qu'on appelle Rapid Server .
Les références:
Lectures complémentaires:
la source
https://
envoi de gros fichiers distribués publiquement qui doivent être authentifiés mais ne doivent pas rester confidentiels: incluez dans l'URL un hachage de certaines parties de l'en-tête d'une réponse légitime, ce qui pourrait à son tour inclure une signature ou un hachage de la charge de données et demander aux navigateurs de valider les données reçues par rapport à l'en-tête? Une telle conception permettrait non seulement d’économiser certaines étapes de négociation SSL, mais permettrait surtout de mettre en cache les proxies. Obtenez l'URL via un lien SSL et les données pourraient être alimentées de n'importe où.Parce qu'ils ne savent pas quelles sont ces ressources. Les ressources requises par une page Web sont codées au format HTML. Ce n'est qu'après qu'un analyseur a déterminé quels sont ces actifs que l'utilisateur-agent peut les demander.
De plus, une fois que ces actifs sont connus, ils doivent être servis individuellement afin que les en-têtes appropriés (c.-à-d. Le type de contenu) puissent être servis afin que l'agent utilisateur sache comment les gérer.
la source
<head>
élément en recherchant les liens alternatifs RSS pour trouver exactement cela: le client pourrait envoyer une liste de ce qui l’intéresse, mais il doit ensuite savoir ce qui est disponible et nous sommes de retour au débutParce que, dans votre exemple, le serveur Web envoie toujours les fichiers CSS et les images, que le client les possède déjà, gaspillant ainsi beaucoup de bande passante (et ralentissant ainsi la connexion au lieu de la rendre plus rapide en réduisant la latence, ce qui était sans doute votre intention). Notez que les fichiers CSS, JavaScript et les fichiers image sont généralement envoyés avec des délais d'expiration très longs pour cette raison (par exemple, lorsque vous devez les modifier, il vous suffit de modifier le nom du fichier pour forcer la nouvelle copie, qui sera à nouveau mise en cache pendant une longue période).
Maintenant, vous pouvez essayer de contourner ce gaspillage de bande passante en disant " OK, mais le client pourrait indiquer qu'il dispose déjà de certaines de ces ressources, afin que le serveur ne l'envoie pas à nouveau ". Quelque chose comme:
Et ensuite, seuls les fichiers qui n'ont pas été modifiés sont envoyés via une seule connexion TCP (à l'aide du traitement en pipeline HTTP via une connexion persistante). Et devine quoi? C'est comme ça que ça fonctionne déjà (vous pouvez aussi utiliser If-Modified-Since au lieu de If-None-Match ).
Mais si vous voulez vraiment réduire le temps de latence en gaspillant beaucoup de bande passante (comme dans votre demande initiale), vous pouvez le faire aujourd'hui en utilisant la norme HTTP / 1.1 lors de la conception de votre site Web. La plupart des gens ne le font pas parce qu'ils ne pensent pas que cela en vaut la peine.
Pour ce faire, vous n'avez pas besoin d'avoir CSS ou JavaScript dans un fichier séparé, vous pouvez les inclure dans le fichier HTML principal en utilisant
<style>
et<script>
tags (vous n'avez probablement même pas besoin de le faire manuellement, votre moteur de template peut probablement le faire automatiquement) . Vous pouvez même inclure des images dans le fichier HTML à l'aide de l'URI des données , comme ceci:Bien sûr, l’encodage en base64 augmente légèrement l’utilisation de la bande passante, mais si vous ne vous souciez pas de la bande passante gaspillée, cela ne devrait pas poser de problème.
Maintenant, si cela vous intéresse, vous pouvez même créer des scripts Web assez intelligents pour tirer le meilleur parti des deux mondes: à la première demande (l'utilisateur ne dispose pas de cookie), envoyez tout ce qu'il contient (CSS, JavaScript, images) au sein d'un seul code HTML. comme décrit ci-dessus, ajoutez un lien rel = "prefetch" pour les copies externes des fichiers et ajoutez un cookie. Si l'utilisateur a déjà un cookie (par exemple, il l'a déjà visité auparavant), envoyez-lui simplement un code HTML normal avec
<img src="example.jpg">
,<link rel="stylesheet" type="text/css" href="style.css">
etc.Ainsi, lors de la première visite, le navigateur demande un seul fichier HTML et affiche et affiche tout. Ensuite, il précèderait (lorsqu'il était inactif) les images CSS, JS et externes externes spécifiées. Lors de la prochaine visite de l'utilisateur, le navigateur demandera et obtiendra uniquement les ressources modifiées (probablement uniquement du nouveau HTML).
Les données d'images supplémentaires CSS + JS + ne seront envoyées que deux fois, même si vous avez cliqué des centaines de fois sur le site Web. Beaucoup mieux que des centaines de fois comme suggéré par votre solution proposée. Et il n’utilisera jamais (ni la première fois ni les suivantes) plus d’ un aller-retour augmentant le temps de latence.
Maintenant, si cela semble trop demander et que vous ne voulez pas utiliser un autre protocole tel que SPDY , il existe déjà des modules tels que mod_pagespeed pour Apache, qui peuvent automatiquement effectuer une partie de ce travail pour vous (fusion de plusieurs fichiers CSS / JS). en une seule, auto-alignant les petites CSS et les minimisant, créant de petites images en attente en attendant le chargement des originaux, un chargement paresseux des images, etc.) sans exiger que vous modifiiez une seule ligne de votre page Web.
la source
HTTP2 est basé sur SPDY et fait exactement ce que vous suggérez:
Plus est disponible sur HTTP 2 Faq
la source
Parce que cela ne suppose pas que ces choses sont réellement nécessaires .
Le protocole ne définit aucun traitement particulier pour un type de fichier ou un agent d'utilisateur particulier. Il ne connaît pas la différence entre, par exemple, un fichier HTML et une image PNG. Pour faire ce que vous demandez, le serveur Web doit identifier le type de fichier, l'analyser pour déterminer quels autres fichiers il référence, puis déterminer quels autres fichiers sont réellement nécessaires, compte tenu de ce que vous souhaitez faire avec le fichier . Cela pose trois gros problèmes.
Le premier problème est qu’il n’existe aucun moyen standard et robuste d’identification des types de fichiers sur le serveur . HTTP gère via le mécanisme Content-Type, mais cela n'aide pas le serveur, qui doit résoudre ce problème seul (en partie pour qu'il sache quoi mettre dans le type de contenu). Les extensions de nom de fichier sont largement prises en charge, mais fragiles et faciles à duper, parfois à des fins malveillantes. Les métadonnées du système de fichiers sont moins fragiles, mais la plupart des systèmes ne les supportent pas très bien, donc les serveurs ne se dérangent même pas. Le sniffing de contenu (comme certains navigateurs et la
file
commande Unix tentent de le faire) peut être robuste si vous voulez le rendre coûteux, mais le sniffing robuste est trop coûteux pour être pratique côté serveur, et le sniffing à prix réduit n'est pas assez robuste.Le deuxième problème est que l' analyse d'un fichier est coûteuse, en termes de calcul . Cela rejoint un peu le premier, dans la mesure où vous auriez besoin d'analyser le fichier de différentes manières si vous voulez analyser le contenu de manière robuste, mais cela s'applique également après avoir identifié le type de fichier, car vous avez besoin pour savoir quelles sont les références. Ce n’est pas si grave lorsque vous ne créez que quelques fichiers à la fois, comme le navigateur, mais un serveur Web doit gérer des centaines, voire des milliers de demandes à la fois. Cela s’ajoute, et si cela va trop loin, cela peut réellement ralentir les choses plus que ne le feraient plusieurs demandes. Si vous avez déjà visité un lien provenant de Slashdot ou de sites similaires, mais que vous constatiez que le serveur est terriblement lent en raison d'une utilisation intensive, vous avez pu constater ce principe.
Le troisième problème est que le serveur n'a aucun moyen de savoir ce que vous avez l'intention de faire avec le fichier . Un navigateur peut avoir besoin des fichiers référencés dans le code HTML, mais cela n’est peut-être pas le cas, en fonction du contexte exact dans lequel le fichier est exécuté. Cela serait assez complexe, mais le Web ne se limite pas aux seuls navigateurs: entre les spiders, les agrégateurs de flux et les mashups, de nombreux types d’agents utilisateurs ne nécessitent pas les fichiers référencés dans le code HTML : ils ne vous souciez que du HTML lui-même. L'envoi de ces autres fichiers à ces utilisateurs-agents ne ferait que gaspiller de la bande passante.
L'essentiel est que déterminer ces dépendances côté serveur représente plus de problèmes qu'il n'en vaut la peine . Alors, au lieu de cela, ils laissent le client comprendre ce dont il a besoin.
la source