Fermer

août 23, 2021

Améliorations des performances (partie 2) —


Résumé rapide ↬

Après près de cinq ans de développement, le nouveau protocole HTTP/3 approche de sa forme finale. Examinons de près les améliorations des performances de HTTP/3, du contrôle de la congestion, du blocage en tête de ligne et de la configuration de la connexion 0-RTT.

Bienvenue dans cette série sur le nouveau protocole HTTP/3. Dans la première partie, nous avons examiné pourquoi exactement nous avons besoin de HTTP/3 et du protocole QUIC sous-jacent, et quelles sont leurs principales nouveautés.

Dans cette deuxième partie, nous allons zoomer sur ]améliorations des performances apportées par QUIC et HTTP/3 pour le chargement des pages Web. Cependant, nous serons également quelque peu sceptiques quant à l'impact que nous pouvons attendre de ces nouvelles fonctionnalités dans la pratique. réseaux lents. Si votre visiteur moyen utilise un réseau câblé ou cellulaire rapide, il ne bénéficiera probablement pas autant des nouveaux protocoles. Cependant, notez que même dans les pays et les régions où les liaisons montantes sont généralement rapides, les 1 % à 10 % les plus lents de votre audience gagner potentiellement beaucoup. En effet, HTTP/3 et QUIC aident principalement à résoudre les problèmes quelque peu rares mais potentiellement à fort impact qui peuvent survenir sur Internet d'aujourd'hui.

Cette partie est un peu plus technique que la première, bien qu'elle décharge la plupart des choses vraiment profondes vers des sources externes, en se concentrant sur l'explication de l'importance de ces choses pour le développeur Web moyen. destiné aux personnes qui découvrent HTTP/3 et les protocoles en général, et il aborde principalement les bases.

  • Caractéristiques de performance HTTP/3 (article actuel)
    Ceci est plus technique. Les personnes qui connaissent déjà les bases peuvent commencer ici.
  • Options de déploiement HTTP/3 pratiques (à venir bientôt !)
    Cela explique les défis liés au déploiement et au test de HTTP/3 vous-même. . Il détaille comment et si vous devez également modifier vos pages Web et vos ressources. ”. Étant donné que nous traitons ici des protocoles réseau, nous examinerons principalement les aspects du réseau, dont deux sont les plus importants : la latence et la bande passante. A (disons, le client) au point B (le serveur) . Elle est physiquement limitée par la vitesse de la lumière ou, pratiquement, la vitesse à laquelle les signaux peuvent voyager dans les fils ou à l'air libre. Cela signifie que la latence dépend souvent de la distance physique réelle entre A et B.

    Sur Terrecela signifie que les latences typiques sont conceptuellement petites, entre environ 10 et 200 millisecondes. Cependant, ce n'est qu'un moyen : les réponses aux paquets doivent également revenir. La latence bidirectionnelle est souvent appelée temps d'aller-retour (RTT).

    En raison de fonctionnalités telles que congestion control (voir ci-dessous), nous aurons souvent besoin de plusieurs tours voyages pour charger même un seul fichier. Ainsi, même de faibles latences de moins de 50 millisecondes peuvent entraîner des retards considérables. C'est l'une des principales raisons pour lesquelles les réseaux de diffusion de contenu (CDN) existent : ils placent les serveurs physiquement plus près de l'utilisateur final afin de réduire la latence, et donc les retards, autant que possible.

    La bande passante, alors, peut être approximativement dit être le nombre de paquets pouvant être envoyés en même temps. C'est un peu plus difficile à expliquer, car cela dépend des propriétés physiques du support (par exemple, la fréquence utilisée des ondes radio), du nombre d'utilisateurs sur le réseau, mais aussi des appareils qui interconnectent différents sous-réseaux (car ils ne peut généralement traiter qu'un certain nombre de paquets par seconde).

    Une métaphore souvent utilisée est celle d'un tuyau utilisé pour transporter l'eau. La longueur du tuyau est la latence, tandis que la largeur du tuyau est la bande passante. Sur Internet, cependant, nous avons généralement une longue série de tuyaux connectésdont certains peuvent être plus larges que d'autres (conduisant à des goulots d'étranglement au niveau des liens les plus étroits). En tant que tel, la bande passante de bout en bout entre les points A et B est souvent limitée par les sous-sections les plus lentes.

    Bien qu'une compréhension parfaite de ces concepts ne soit pas nécessaire pour le reste de cet article, avoir une définition commune de haut niveau serait bon. Pour plus d'informations, je vous recommande de consulter l'excellent chapitre d'Ilya Grigorik sur la latence et la bande passante dans son livre High Performance Browser Networking.

    Congestion Control

    Un aspect des performances concerne comment efficacement un protocole de transport peut utiliser toute la bande passante (physique) d'un réseau (c'est-à-dire approximativement, combien de paquets par seconde peuvent être envoyés ou reçus). Cela affecte à son tour la vitesse à laquelle les ressources d'une page peuvent être téléchargées. Certains prétendent que QUIC fait cela beaucoup mieux que TCP, mais ce n'est pas vrai. surcharge (ou congestion) du réseau. En effet, comme nous l'avons dit, chaque lien réseau ne dispose que d'une certaine quantité de données qu'il peut (physiquement) traiter chaque seconde. Donnez-lui plus et il n'y a pas d'autre choix que de supprimer les paquets excessifs, ce qui entraîne une perte de paquets.

    Comme discuté dans partie 1pour un protocole fiable comme TCP, le seul moyen de récupérer de la perte de paquets est de retransmettre une nouvelle copie des données, ce qui prend un aller-retour. Surtout sur les réseaux à latence élevée (disons, avec un RTT de plus de 50 millisecondes), la perte de paquets peut sérieusement affecter les performances. sera. Cela dépend souvent d'un goulot d'étranglement quelque part dans la connexion de bout en bout, mais nous ne pouvons pas prédire ou savoir où ce sera. Internet ne dispose pas (encore) de mécanismes pour signaler les capacités de liaison aux points de terminaison.

    De plus, même si nous connaissions la bande passante physique disponible, cela ne signifierait pas que nous pourrions tout utiliser nous-mêmes. Plusieurs utilisateurs sont généralement actifs sur un réseau simultanément, chacun d'entre eux ayant besoin d'une part équitable de la bande passante disponible. changer au fur et à mesure que les utilisateurs rejoignent, quittent et utilisent le réseau. Pour résoudre ce problème, TCP essaiera constamment de découvrir la bande passante disponible au fil du temps en utilisant un mécanisme appelé congestion control.

    Au début de la connexion, il n'envoie que quelques paquets (en pratique, compris entre 10 et 100 paquets, soit environ 14 et 140 Ko de données) et attend un aller-retour jusqu'à ce que le récepteur renvoie les accusés de réception de ces paquets. S'ils sont tous reconnus, cela signifie que le réseau peut gérer ce taux d'envoi, et nous pouvons essayer de répéter le processus mais avec plus de données (en pratique, le taux d'envoi double généralement à chaque itération).

    De cette façon, l'envoi le taux continue d'augmenter jusqu'à ce que certains paquets ne soient pas reconnus (ce qui indique une perte de paquets et une congestion du réseau). Cette première phase est généralement appelée « démarrage lent ». Lors de la détection d'une perte de paquets, TCP réduit le taux d'envoi et (après un certain temps) recommence à augmenter le taux d'envoi, bien que par incréments (beaucoup) plus petits. Cette logique de réduction puis de croissance est répétée pour chaque perte de paquet par la suite. Finalement, cela signifie que TCP essaiera constamment d'atteindre sa part de bande passante idéale et équitable. Ce mécanisme est illustré à la figure 1.

    Contrôle de congestion TCP

    Figure 1. Exemple simplifié de contrôle de congestion TCP, commençant par un débit d'envoi de 10 paquets (adapté de hpbn.co. (Grand aperçu)

    Il s'agit d'une explication extrêmement simplifiée à l'extrême du contrôle de congestion. Dans la pratique, de nombreux autres facteurs sont en jeu, tels que bufferbloatla fluctuation des RTT due à la congestionet le fait que plusieurs expéditeurs simultanés doivent obtenir leur juste part de la bande passante. En tant que tel, il existe de nombreux algorithmes de contrôle de congestion différents, et beaucoup sont encore en cours d'invention aujourd'hui, aucun ne fonctionne de manière optimale dans toutes les situations. débits d'envoi optimaux en fonction du RTT et de la bande passante réellement disponible. Pour le chargement de pages Web, cette approche de démarrage lent peut également affecter des métriques telles que la première peinture de contenu, car seule une petite quantité de données (des dizaines à quelques centaines de Ko) peut être transférée au cours des premiers allers-retours. (Vous avez peut-être entendu la recommandation de conserver vos données critiques à une taille inférieure à 14 Ko.)

    Le choix d'une approche plus agressive pourrait ainsi conduire à de meilleurs résultats sur les réseaux à bande passante élevée et à latence élevée, en particulier si vous ne vous souciez pas de la perte occasionnelle de paquets. C'est là que j'ai encore vu de nombreuses erreurs d'interprétation sur le fonctionnement de QUIC.

    Comme indiqué dans partie 1QUIC, en théorie, souffre moins de perte de paquets (et des blocage de tête de ligne (HOL)) car il traite indépendamment la perte de paquets sur le flux d'octets de chaque ressource. De plus, QUIC fonctionne sur le User Datagram Protocol (UDP), qui, contrairement à TCP, n'a pas de fonction de contrôle de congestion intégrée ; il vous permet d'essayer d'envoyer à n'importe quel débit et de ne pas retransmettre les données perdues.

    Cela a conduit à de nombreux articles affirmant que QUIC n'utilise pas non plus le contrôle de congestion, que QUIC peut à la place commencer à envoyer des données à un niveau beaucoup plus élevé. sur UDP (en s'appuyant sur la suppression du blocage HOL pour gérer la perte de paquets), c'est pourquoi QUIC est beaucoup plus rapide que TCP.

    En réalité, rien ne pourrait être plus éloigné de la vérité  : QUIC utilise en fait des techniques de gestion de bande passante très similaires à TCP. Elle aussi commence par un taux d'envoi plus faible et l'augmente au fil du temps, en utilisant les accusés de réception comme mécanisme clé pour mesurer la capacité du réseau. C'est (entre autres raisons) parce que QUIC doit être fiable pour être utile pour quelque chose comme HTTP, parce qu'il doit être juste pour les autres connexions QUIC (et TCP !), et parce que sa suppression de blocage HOL ne le fait pas. en fait, aide très bien contre la perte de paquets (comme nous le verrons ci-dessous).

    Cependant, cela ne signifie pas que QUIC ne peut pas être (un peu) plus intelligent sur la façon dont il gère la bande passante que TCP. Ceci est principalement dû au fait que QUIC est plus flexible et plus facile à faire évoluer que TCP. Comme nous l'avons dit, les algorithmes de contrôle de congestion évoluent encore fortement aujourd'hui, et nous devrons probablement, par exemple, peaufiner les choses pour tirer le meilleur parti de la 5G.

    Cependant, TCP est généralement implémenté dans le noyau du système d'exploitation (OS), un environnement sécurisé et plus restreint, qui pour la plupart des systèmes d'exploitation n'est même pas open source. En tant que tel, le réglage de la logique de congestion n'est généralement effectué que par quelques développeurs sélectionnés, et l'évolution est lente.

    En revanche, la plupart des implémentations QUIC sont actuellement effectuées dans « l'espace utilisateur » (où nous exécutons généralement des applications natives) et sont effectuées open sourceexplicitement pour encourager l'expérimentation par un pool beaucoup plus large de développeurs (comme déjà montré, par exemple, par Facebook).

    Un autre exemple concret est le retardé proposition d'extension de fréquence d'accusé de réception pour QUIC. Alors que, par défaut, QUIC envoie un accusé de réception tous les 2 paquets reçus, cette extension permet aux points de terminaison d'accuser réception, par exemple, tous les 10 paquets à la place. Il a été démontré que cela offrait de grands avantages en termes de vitesse sur les réseaux satellitaires et à très large bande passante, car le surcoût lié à la transmission des paquets d'accusé de réception est réduit. L'ajout d'une telle extension pour TCP prendrait beaucoup de temps à être adopté, tandis que pour QUIC, il est beaucoup plus facile à déployer. qui pourrait à son tour être également rétroporté sur TCP pour l'améliorer. Bien que cette approche soit robuste, elle est également quelque peu dépassée et n'est plus largement utilisée dans la pratique. Alors, pourquoi est-il dans le QUIC RFC ? La première raison est que lorsque QUIC a été lancé, NewReno était l'algorithme de contrôle de congestion le plus récent qui était lui-même standardisé. Des algorithmes plus avancés, tels que BBR et CUBIC, ne sont toujours pas standardisés ou seulement récemment sont devenus des RFC.

    La deuxième raison est que NewReno est une configuration relativement simple. Étant donné que les algorithmes ont besoin de quelques ajustements pour gérer les différences entre QUIC et TCP, il est plus facile d'expliquer ces changements sur un algorithme plus simple. En tant que telle, la RFC 9002 devrait être davantage lue comme « comment adapter un algorithme de contrôle de congestion à QUIC », plutôt que « c'est la chose que vous devriez utiliser pour QUIC ». En effet, la plupart des implémentations QUIC au niveau de la production ont fait des implémentations personnalisées à la fois de Cubic et BBR.

    Il convient de répéter que les algorithmes de contrôle de congestion ne sont pas TCP ou QUIC -spécifique; ils peuvent être utilisés par l'un ou l'autre protocole, et l'espoir est que les progrès de QUIC finiront par trouver leur chemin vers les piles TCP. contrôle de flux. Ces deux fonctionnalités sont souvent confondues dans TCP, car on dit qu'elles utilisent toutes les deux la « fenêtre TCP »bien qu'il y ait en fait deux fenêtres : la fenêtre de congestion et la fenêtre de réception TCP. Le contrôle de flux, cependant, entre en jeu beaucoup moins pour le cas d'utilisation du chargement de pages Web qui nous intéresse, nous allons donc l'ignorer ici. Plus d'informations plus approfondies sont disponibles.

    Qu'est-ce que tout cela signifie ?

    QUIC est toujours lié par les lois de la physique et le besoin être gentil avec les autres expéditeurs sur Internet. Cela signifie que il ne téléchargera pas par magie les ressources de votre site Web beaucoup plus rapidement que TCP. Cependant, la flexibilité de QUIC signifie que l'expérimentation de nouveaux algorithmes de contrôle de congestion deviendra plus facile, ce qui devrait améliorer les choses à l'avenir pour TCP et QUIC. combien d'allers-retours il faut avant de pouvoir envoyer des données HTTP utiles (par exemple, des ressources de page) sur une nouvelle connexion. Certains prétendent que QUIC est deux à trois allers-retours plus rapide que TCP + TLS, mais nous verrons que ce n'est vraiment qu'un.

    Le saviez-vous ?

    Comme nous l'avons dit dans partie 1une connexion effectue généralement une (TCP) ou deux (TCP + TLS) poignées de main avant que les requêtes et les réponses HTTP puissent être échangées. Ces poignées de main échangent des paramètres initiaux que le client et le serveur doivent connaître afin, par exemple, de chiffrer les données. au moins un aller-retour à compléter (TCP + TLS 1.3, (b)) et parfois deux (TLS 1.2 et avant (a)). Ceci est inefficace, car nous avons besoin d'au moins deux allers-retours de temps d'attente de négociation (overhead) avant de pouvoir envoyer notre première requête HTTP, ce qui signifie attendre au moins trois allers-retours pour les premières données de réponse HTTP (le retournant la flèche rouge) pour entrer. Sur les réseaux lents, cela peut signifier une surcharge de 100 à 200 millisecondes. ( Grand aperçu)

    Vous vous demandez peut-être pourquoi la négociation TCP + TLS ne peut pas être simplement combinée, effectuée dans le même aller-retour. Bien que cela soit conceptuellement possible (QUIC fait exactement cela), les choses n'ont pas été conçues au départ comme ça, car nous devons pouvoir utiliser TCP avec et sans TLS sur le dessus. Autrement dit, TCP ne prend tout simplement pas en charge l'envoi de données non TCP pendant la prise de contact. Il y a eu des efforts pour ajouter ceci avec l'extension TCP Fast Open ; cependant, comme indiqué dans partie 1cela s'est avéré difficile à déployer à grande échelle.

    Heureusement, QUIC a été conçu avec TLS à l'esprit dès le départ, et comme tel combine à la fois le transport et les poignées de main cryptographiques dans un seul mécanisme. Cela signifie que la poignée de main QUIC ne prendra qu'un seul aller-retour au total, ce qui représente un aller-retour de moins que TCP + TLS 1.3 (voir la figure 2c ci-dessus).

    Vous pourriez être confus, car vous avez probablement lu cela QUIC est deux ou même trois allers-retours plus rapides que TCP, pas un seul. En effet, la plupart des articles ne considèrent que le pire des cas (TCP + TLS 1.2, (a)), sans mentionner que le TCP + TLS 1.3 moderne ne fait également « que » deux allers-retours ((b) est rarement affiché). Bien qu'une augmentation de la vitesse d'un aller-retour soit agréable, ce n'est pas étonnant. Surtout sur les réseaux rapides (disons, moins d'un RTT de 50 millisecondes), ce sera à peine perceptible bien que les réseaux lents et les connexions à des serveurs distants en profiteraient un peu plus.

    Ensuite, vous pourriez être se demandant pourquoi nous devons attendre la ou les poignées de main. Pourquoi ne pouvons-nous pas envoyer de requête HTTP lors du premier aller-retour ? C'est principalement parce que, si nous le faisions, alors cette première demande serait envoyée non chiffrée lisible par n'importe quel espion sur le fil, ce qui n'est évidemment pas très bon pour la confidentialité et la sécurité. En tant que tel, nous devons attendre la fin de la négociation cryptographique avant d'envoyer la première requête HTTP. Ou le faisons-nous?

    C'est là qu'une astuce astucieuse est utilisée dans la pratique. Nous savons que les utilisateurs revisitent souvent les pages Web peu de temps après leur première visite. En tant que tel, nous pouvons utiliser la connexion chiffrée initiale pour amorcer une deuxième connexion à l'avenir. En termes simples, au cours de sa durée de vie, la première connexion est utilisée pour communiquer en toute sécurité de nouveaux paramètres cryptographiques entre le client et le serveur. Ces paramètres peuvent ensuite être utilisés pour chiffrer la deuxième connexion dès le début, sans avoir à attendre la fin de la négociation TLS complète. Cette approche est appelée « reprise de session ».

    Elle permet une optimisation puissante : nous pouvons maintenant envoyer en toute sécurité notre première requête HTTP avec la poignée de main QUIC/TLS, en économisant un autre aller-retour ! Quant à TLS 1.3, cela supprime efficacement le temps d'attente de la poignée de main TLS. Cette méthode est souvent appelée 0-RTT (bien que, bien sûr, il faut encore un aller-retour pour que les données de réponse HTTP commencent à arriver).

    La reprise de session et 0-RTT sont, encore une fois, des choses que j'ai souvent vu à tort comme étant des fonctionnalités spécifiques à QUIC. En réalité, ce sont en fait des fonctionnalités TLS qui étaient déjà présentes sous une forme ou une autre dans TLS 1.2 et sont maintenant à part entière dans TLS 1.3.

    En d'autres termes, comme vous pouvez le voir dans figure 3 ci-dessous, nous pouvons également obtenir les avantages en termes de performances de ces fonctionnalités sur TCP (et donc aussi HTTP/2 et même HTTP/1.1) ! Nous voyons que même avec 0-RTT, QUIC n'est encore qu'un aller-retour plus rapide qu'une pile TCP + TLS 1.3 fonctionnant de manière optimale. L'affirmation selon laquelle QUIC est trois allers-retours plus rapide vient de la comparaison de la figure 2 (a) avec la figure 3 (f), ce qui, comme nous l'avons vu, n'est pas vraiment juste.

     TCP + TLS par rapport à l'ensemble de connexion QUIC 0-RTT -up.

    Figure 3 : Configuration de la connexion TCP + TLS par rapport à QUIC 0-RTT. ( Grand aperçu)

    Le pire est que lors de l'utilisation de 0-RTT, QUIC ne peut même pas vraiment utiliser cet aller-retour gagné aussi bien en raison de la sécurité. Pour comprendre cela, nous devons comprendre l'une des raisons pour lesquelles la négociation TCP existe. Premièrement, cela permet au client de s'assurer que le serveur est réellement disponible à l'adresse IP donnée avant de lui envoyer des données de couche supérieure. connexion est en fait qui et où ils disent qu'ils sont avant de lui envoyer des données. Si vous vous rappelez comment nous avons défini une connexion avec le 4-tuple dans partie 1vous saurez que le client est principalement identifié par son adresse IP. Et c'est le problème : Les adresses IP peuvent être usurpées !

    Supposons qu'un attaquant demande un très gros fichier via HTTP sur QUIC 0-RTT. Cependant, ils usurpent leur adresse IP, donnant l'impression que la demande 0-RTT provient de l'ordinateur de leur victime. Ceci est illustré dans la figure 4 ci-dessous. Le serveur QUIC n'a aucun moyen de détecter si l'adresse IP a été usurpée, car il s'agit du ou des tout premiers paquets qu'il voit de ce client.

     Attaque d'amplification 0-RTT sur la victime.

    Figure 4 : attaquants peut usurper son adresse IP lors de l'envoi d'une requête 0-RTT à un serveur QUIC, déclenchant une attaque d'amplification sur la victime. ( Grand aperçu)

    Si le serveur commence alors simplement à renvoyer le fichier volumineux à l'adresse IP usurpée, il pourrait finir par surcharger la bande passante du réseau de la victime (surtout si l'attaquant effectuait plusieurs de ces fausses requêtes en parallèle) . Notez que la réponse QUIC serait abandonnée par la victime, car elle n'attend pas de données entrantes, mais cela n'a pas d'importance : leur réseau doit toujours traiter les paquets !

    C'est ce qu'on appelle une réflexion, ou amplification, attaqueet c'est un moyen important pour les pirates d'exécuter des attaques par déni de service distribué (DDoS). Notez que cela ne se produit pas lorsque 0-RTT sur TCP + TLS est utilisé, précisément parce que la négociation TCP doit être terminée avant même que la demande 0-RTT ne soit envoyée avec la négociation TLS.

    En tant que tel, QUIC doit être prudent en répondant aux requêtes 0-RTT, en limitant la quantité de données qu'il envoie en réponse jusqu'à ce que le client ait été vérifié comme étant un client réel et non une victime. Pour QUIC, cette quantité de données a été fixée à trois fois le montant reçu du client .

    En d'autres termes, QUIC a un « facteur d'amplification » maximal de trois, ce qui a été déterminé comme une transaction acceptable. -off entre l'utilité des performances et le risque de sécurité (en particulier par rapport à certains incidents qui avaient un facteur d'amplification de plus de 51 000 fois). Étant donné que le client n'envoie généralement qu'un ou deux paquets en premier lieu, la réponse 0-RTT du serveur QUIC sera plafonnée à seulement 4 à 6 Ko (y compris les autres surcharges QUIC et TLS !), ce qui est un peu moins qu'impressionnant .

    De plus, d'autres problèmes de sécurité peuvent conduire, par exemple, à des « attaques par rejeu », qui limitent le type de requête HTTP que vous pouvez effectuer. Par exemple, Cloudflare autorise uniquement les requêtes HTTP GET sans paramètres de requête en 0-RTT. Ceux-ci limitent encore plus l'utilité de 0-RTT.

    Heureusement, QUIC a des options pour améliorer un peu cela. Par exemple, le serveur peut vérifier si le 0-RTT provient d'une IP avec laquelle il a déjà eu une connexion valide. Cependant, cela ne fonctionne que si le client reste sur le même réseau (limitant quelque peu la fonctionnalité de migration de connexion de QUIC ). Et même si cela fonctionne, la réponse de QUIC est toujours limitée par la logique de démarrage lent du contrôleur de congestion dont nous avons discuté ci-dessus  ; ainsi, il n'y a aucune augmentation de vitesse massive supplémentaire en plus de l'aller-retour enregistré.

    Le saviez-vous ? Processus d'établissement de liaison 0-RTT dans la figure 2c. Cela peut être un problème si, par exemple, le certificat TLS du serveur est trop volumineux pour tenir entre 4 et 6 Ko. Dans ce cas, il devrait être divisé, le deuxième morceau devant attendre l'envoi du deuxième aller-retour (après les accusés de réception des premiers paquets, indiquant que l'adresse IP du client n'a pas été usurpée). Dans ce cas, la poignée de main de QUIC peut encore finir par prendre deux allers-retours égaux à TCP + TLS ! C'est pourquoi pour QUIC, des techniques telles que la compression de certificats seront très importantes. 0-RTT plus utile. Par exemple, le serveur pouvait se souvenir de la quantité de bande passante dont un client disposait la dernière fois qu'il a été vu, ce qui le rend moins limité par le démarrage lent du contrôle de congestion pour la reconnexion des clients (non usurpés). Cela a été étudié dans le milieu universitaire et il y a même une extension proposée dans QUIC pour le faire. Plusieurs entreprises font déjà ce genre de chose pour accélérer également TCP.

    Une autre option serait que les clients envoient plus d'un ou deux paquets (par exemple, en envoyant 7 paquets supplémentaires avec remplissage), ainsi, la limite de trois fois se traduit par une réponse plus intéressante de 12 à 14 Ko, même après la migration de la connexion. J'ai écrit à ce sujet dans l'un de mes articles .

    Enfin, les serveurs QUIC (qui se comportent mal) pourraient également augmenter intentionnellement la limite de trois fois s'ils estiment que c'est sûr de le faire ou s'ils ne ne vous souciez pas des problèmes de sécurité potentiels (après tout, il n'y a pas de police de protocole empêchant cela). RTT est vraiment plus une micro-optimisation qu'une nouvelle fonctionnalité révolutionnaire. Par rapport à une configuration TCP + TLS 1.3 à la pointe de la technologie, cela permettrait d'économiser au maximum un aller-retour. La quantité de données pouvant être réellement envoyées lors du premier aller-retour est en outre limitée par un certain nombre de considérations de sécurité.

    En tant que telle, cette fonctionnalité brillera principalement si vos utilisateurs sont sur des réseaux avec une latence très élevée (par exemple, les réseaux satellites avec des RTT de plus de 200 millisecondes) ou si vous n'envoyez généralement pas beaucoup de données. Certains exemples de ces derniers sont des sites Web fortement mis en cache, ainsi que des applications d'une seule page qui récupèrent périodiquement de petites mises à jour via des API et d'autres protocoles tels que DNS-over-QUIC. L'une des raisons pour lesquelles Google a obtenu de très bons résultats 0-RTT pour QUIC est qu'il l'a testé sur sa page de recherche déjà fortement optimisée, où les réponses aux requêtes sont assez petites.

    Dans d'autres cas, vous aurez gagnez seulement quelques dizaines de millisecondes au mieux, encore moins si vous utilisez déjà un CDN (ce que vous devriez faire si vous vous souciez des performances !).

    Migration des connexions

    Un troisième La fonction de performance rend QUIC plus rapide lors du transfert entre les réseaux, en gardant les connexions existantes intactes . Bien que cela fonctionne effectivement, ce type de changement de réseau ne se produit pas si souvent et les connexions doivent toujours réinitialiser leurs débits d'envoi. pour effectuer la migration de connexion lors de la changement de réseau. Nous l'avons illustré avec un client passant d'un réseau Wi-Fi à la 4G tout en téléchargeant un fichier volumineux. Sur TCP, ce téléchargement peut devoir être interrompu, tandis que pour QUIC, il peut continuer.

    Tout d'abord, cependant, considérez la fréquence à laquelle ce type de scénario se produit réellement. Vous pourriez penser que cela se produit également lorsque vous vous déplacez entre des points d'accès Wi-Fi dans un bâtiment ou entre des tours cellulaires sur la route. Dans ces configurations, cependant (si elles sont effectuées correctement), votre appareil conservera généralement son IP intacte, car la transition entre les stations de base sans fil se fait à une couche de protocole inférieure. En tant que tel, cela ne se produit que lorsque vous vous déplacez entre des réseaux complètement différents ce qui, je dirais, n'arrive pas si souvent.

    Deuxièmement, nous pouvons nous demander si cela fonctionne également pour d'autres cas d'utilisation en plus téléchargements de fichiers volumineux et visioconférence et streaming en direct. Si vous chargez une page Web au moment exact du changement de réseau, vous devrez peut-être redemander certaines des ressources (plus tard).

    Cependant, le chargement d'une page prend généralement quelques secondes, de sorte que coïncider avec un commutateur réseau ne sera pas non plus très courant. De plus, pour les cas d'utilisation où il s'agit d'une préoccupation urgente, d'autres mesures d'atténuation sont généralement déjà en place . Par exemple, les serveurs proposant des téléchargements de fichiers volumineux peuvent prendre en charge les demandes de plage HTTP pour autoriser les téléchargements avec reprise.

    Parce qu'il y a généralement un temps de chevauchement entre l'arrêt du réseau 1 et la disponibilité du réseau 2 , les applications vidéo peuvent ouvrir plusieurs connexions (1 par réseau), en les synchronisant avant que l'ancien réseau ne disparaisse complètement. L'utilisateur remarquera toujours le changement, mais il ne supprimera pas complètement le flux vidéo.

    Troisièmement, il n'y a aucune garantie que le nouveau réseau aura autant de bande passante disponible que l'ancien. En tant que tel, même si la connexion conceptuelle est conservée intacte, le serveur QUIC ne peut pas simplement continuer à envoyer des données à haute vitesse. Au lieu de cela, pour éviter de surcharger le nouveau réseau, il doit réinitialiser (ou au moins réduire) le débit d'envoi et redémarrer dans la phase de démarrage lent du contrôleur de congestion.

    Parce que ce taux d'envoi initial est généralement trop faible pour vraiment prendre en charge des choses telles que le streaming vidéo, vous verrez une perte de qualité ou des problèmes, même sur QUIC. D'une certaine manière, la migration de connexion consiste davantage à empêcher le désabonnement et la surcharge du contexte de connexion sur le serveur qu'à améliorer les performances. pour améliorer la migration de connexion. For example, we can, again, try to remember how much bandwidth was available on a given network last time and attempt to ramp up faster to that level for a new migration. Additionally, we could envision not simply switching between networks, but using both at the same time. This concept is called multipathand [we discuss it in more detail below](#future-developments-to-look-out-for).

    So far, we have mainly talked about active connection migration, where users move between different networks. There are, however, also cases of passive connection migrationwhere a certain network itself changes parameters. A good example of this is network address translation (NAT) rebinding. While a full discussion of NAT is out of the scope of this article, it mainly means that the connection’s port numbers can change at any given time, without warning. This also happens much more often for UDP than TCP in most routers.

    If this occurs, the QUIC CID will not change, and most implementations will assume that the user is still on the same physical network and will thus not reset the congestion window or other parameters. QUIC also includes some features such as PINGs and timeout indicators to prevent this from happening, because this typically occurs for long-idle connections.

    We discussed in part 1 that QUIC doesn’t just use a single CID for security reasons. Instead, it changes CIDs when performing active migration. In practice, it’s even more complicated, because both client and server have separate lists of CIDs, (called source and destination CIDs in the QUIC RFC). This is illustrated in figure 5 below.

    QUIC uses separate source and destination CIDs

    Figure 5: QUIC uses separate client and server CIDs. (Large preview)

    This is done to allow each endpoint to choose its own CID format and contents, which in turn is crucial to allowing advanced routing and load-balancing logic. With connection migration, load balancers can no longer just look at the 4-tuple to identify a connection and send it to the correct back-end server. However, if all QUIC connections were to use random CIDs, this would heavily increase memory requirements at the load balancer, because it would need to store mappings of CIDs to back-end servers. Additionally, this would still not work with connection migration, as the CIDs change to new random values.

    As such, it’s important that QUIC back-end servers deployed behind a load balancer have a predictable format of their CIDs, so that the load balancer can derive the correct back-end server from the CID, even after migration. Some options for doing this are described in the IETF’s proposed document. To make this all possible, the servers need to be able to choose their own CID, which wouldn’t be possible if the connection initiator (which, for QUIC, is always the client) chose the CID. This is why there is a split between client and server CIDs in QUIC.

    What does it all mean?

    Thus, connection migration is a situational feature. Initial tests by Googlefor example, show low percentage improvements for its use cases. Many QUIC implementations don’t yet implement this feature. Even those that do will typically limit it to mobile clients and apps and not their desktop equivalents. Some people are even of the opinion that the feature isn’t needed, because opening a new connection with 0-RTT should have similar performance properties in most cases.

    Still, depending on your use case or user profile, it could have a large impact. If your website or app is most often used while on the move (say, something like Uber or Google Maps), then you’d probably benefit more than if your users were typically sitting behind a desk. Similarly, if you’re focusing on constant interaction (be it video chat, collaborative editing, or gaming), then your worst-case scenarios should improve more than if you have a news website.

    Head-of-Line Blocking Removal

    The fourth performance feature is intended to make QUIC faster on networks with a high amount of packet loss by mitigating the head-of-line (HoL) blocking problem. While this is true in theory, we will see that in practice this will probably only provide minor benefits for web-page loading performance.

    To understand this, though, we first need to take a detour and talk about stream prioritization and multiplexing.

    Stream Prioritization

    As discussed in part 1a single TCP packet loss can delay data for multiple in-transit resources because TCP’s bytestream abstraction considers all data to be part of a single file. QUIC, on the other hand, is intimately aware that there are multiple concurrent bytestreams and can handle loss on a per-stream basis. However, as we’ve also seen, these streams are not truly transmitting data in parallel: Rather, the stream data is multiplexed onto a single connection. This multiplexing can happen in many different ways.

    For example, for streams A, B, and C, we might see a packet sequence of ABCABCABCABCABCABCABCABCwhere we change the active stream in each packet (let’s call this round-robin). However, we might also see the opposite pattern of AAAAAAAABBBBBBBBCCCCCCCCwhere each stream is completed in full before starting the next one (let’s call this sequential). Of course, many other options are possible in between these extremes (AAAABBCAAAAABBC…AABBCCAABBCC…ABABABCCCC…etc.). The multiplexing scheme is dynamic and driven by an HTTP-level feature called stream prioritization (discussed later in this article).

    As it turns out, which multiplexing scheme you choose can have a huge impact on website loading performance. You can see this in the video below, courtesy of Cloudflareas every browser uses a different multiplexer. The reasons why are quite complex, and I’ve written several academic papers on the topic, as well as talked about it in a conference. Patrick Meenan, of Webpagetest fame, even has a three-hour tutorial on just this topic.

    Stream prioritization in different browsers" sizes="100vw
    Stream multiplexing differences can have a large impact on website loading in different browsers. (Large preview)

    Luckily, we can explain the basics relatively easily. As you may know, some resources can be render blocking. This is the case for CSS files and for some JavaScript in the HTML head element. While these files are loading, the browser cannot paint the page (or, for example, execute new JavaScript).

    What’s more, CSS and JavaScript files need to be downloaded in full in order to be used (although they can often be incrementally parsed and compiled). As such, these resources need to be loaded as soon as possible, with the highest priority. Let’s contemplate what would happen if A, B, and C were all render-blocking resources.

    Render blocking multiplexing impact

    Figure 6: The stream multiplexing approach affects (render-blocking) resource completion time. (Large preview)

    If we use a round-robin multiplexer (the top row in figure 6), we would actually delay each resource’s total completion time, because they all need to share bandwidth with the others. Since we can only use them after they are fully loaded, this incurs a significant delay. However, if we multiplex them sequentially (the bottom row in figure 6), we would see that A and B complete much earlier (and can be used by the browser), while not actually delaying C’s completion time.

    However, that doesn’t mean that sequential multiplexing is always the best, because some (mostly non-render-blocking) resources (such as HTML and progressive JPEGs) can actually be processed and used incrementally. In those (and some other) cases, it makes sense to use the first option (or at least something in between).

    Still, for most web-page resources, it turns out that sequential multiplexing performs best. This is, for example, what Google Chrome is doing in the video above, while Internet Explorer is using the worst-case round-robin multiplexer.

    Packet Loss Resilience

    Now that we know that all streams aren’t always active at the same time and that they can be multiplexed in different ways, we can consider what happens if we have packet loss. As explained in part 1if one QUIC stream experiences packet loss, then other active streams can still be used (whereas, in TCP, all would be paused).

    However, as we’ve just seen, having many concurrent active streams is typically not optimal for web performance, because it can delay some critical (render-blocking) resources, even without packet loss! We’d rather have just one or two active at the same time, using a sequential multiplexer. However, this reduces the impact of QUIC’s HoL blocking removal.

    Imagine, for example, that the sender could transmit 12 packets at a given time (see figure 7 below) — remember that this is limited by the congestion controller). If we fill all 12 of those packets with data for stream A (because it’s high priority and render-blocking — think main.js), then we would have only one active stream in that 12-packet window.

    If one of those packets were to be lost, then QUIC would still end up fully HoL blocked because there would simply be no other streams it could process besides A: All of the data is for Aand so everything would still have to wait (we don’t have B or C data to process), similar to TCP.

    HoL blocking with round-robin versus sequential multiplexing

    Figure 7: Packet loss impact depends on the multiplexer used. (Note that we assume each stream has more data to send than in the previous similar images. (Large preview)

    We see that we have a kind of contradiction: Sequential multiplexing (AAAABBBBCCCC) is typically better for web performance, but it doesn’t allow us to take much advantage of QUIC’s HoL blocking removal. Round-robin multiplexing (ABCABCABCABC) would be better against HoL blocking, but worse for web performance. As such, one best practice or optimization can end up undoing another.

    And it gets worse. Up until now, we’ve sort of assumed that individual packets get lost one at a time. However, this isn’t always true, because packet loss on the Internet is often “bursty”meaning that multiple packets often get lost at the same time.

    As discussed abovean important reason for packet loss is that a network is overloaded with too much data, having to drop excess packets. This is why the congestion controller starts sending slowly. However, it then keeps growing its send rate until… there is packet loss!

    Put differently, the mechanism that’s intended to prevent overloading the network actually overloads the network (albeit in a controlled fashion). On most networks, that occurs after quite a while, when the send rate has increased to hundreds of packets per round trip. When those reach the limit of the network, several of them are typically dropped together, leading to the bursty loss patterns.

    Did You Know?

    This is one of the reasons why we wanted to move to using a single (TCP) connection with HTTP/2, rather than the 6 to 30 connections with HTTP/1.1. Because each individual connection ramps up its send rate in pretty much the same way, HTTP/1.1 could get a good speed-up at the start, but the connections could actually start causing massive packet loss for each other as they caused the network to become overloaded.

    At the time, Chromium developers speculated that this behaviour caused most of the packet loss seen on the Internet. This is also one of the reasons why BBR has become an often used congestion-control algorithm, because it uses fluctuations in observed RTTs, rather than packet loss, to assess available bandwidth.

    Did You Know?

    Other causes of packet loss can lead to fewer or individual packets becoming lost (or unusable), especially on wireless networks. There, however, the losses are often detected at lower protocol layers and solved between two local entities (say, the smartphone and the 4G cellular tower), rather than by retransmissions between the client and the server. These usually don’t lead to real end-to-end packet loss, but rather show up as variations in packet latency (or “jitter”) and reordered packet arrivals.

    So, let’s say we are using a per-packet round-robin multiplexer (ABCABCABCABCABCABCABCABC…) to get the most out of HoL blocking removal, and we get a bursty loss of just 4 packets. We see that this will always impact all 3 streams (see figure 8, middle row)! In this case, QUIC’s HoL blocking removal provides no benefits, because all streams have to wait for their own retransmissions.

    Packet loss patterns and their interaction with different multiplexers

    Figure 8: Depending on the multiplexer used and the packet loss pattern, more or fewer streams are affected. (Large preview)

    To lower the risk of multiple streams being affected by a lossy burst, we need to concatenate more data for each stream. For example, AABBCCAABBCCAABBCCAABBCC… is a small improvement, and AAAABBBBCCCCAAAABBBBCCCC… (see bottom row in figure 8 above) is even better. You can again see that a more sequential approach is better, even though that reduces the chances that we have multiple concurrent active streams.

    In the end, predicting the actual impact of QUIC’s HoL blocking removal is difficult, because it depends on the number of streams, the size and frequency of the loss bursts, how the stream data is actually used, etc. However, most results at this time indicate it will not help much for the use case of web-page loading, because there we typically want fewer concurrent streams.

    If you want even more detail on this topic or just some concrete examples, please check out my in-depth article on HTTP HoL blocking.

    Did You Know?

    As with the previous sections, some advanced techniques can help us here. For example, modern congestion controllers use packet pacing. This means that they don’t send, for example, 100 packets in a single burst, but rather spread them out over an entire RTT. This conceptually lowers the chances of overloading the network, and the QUIC Recovery RFC strongly recommends using it. Complementarily, some congestion-control algorithms such as BBR don’t keep increasing their send rate until they cause packet loss, but rather back off before that (by looking at, for example, RTT fluctuations, because RTTs also rise when a network is becoming overloaded).

    While these approaches lower the overall chances of packet loss, they don’t necessarily lower its burstiness.

    What does it all mean?

    While QUIC’s HoL blocking removal means, in theory, that it (and HTTP/3) should perform better on lossy networks, in practice this depends on a lot of factors. Because the use case of web-page loading typically favours a more sequential multiplexing set-up, and because packet loss is unpredictable, this feature would, again, likely affect mainly the slowest 1% of users. However, this is still a very active area of research, and only time will tell.

    Still, there are situations that might see more improvements. These are mostly outside of the typical use case of the first full page load — for example, when resources are not render blocking, when they can be processed incrementally, when streams are completely independent, or when less data is sent at the same time.

    Examples include repeat visits on well-cached pages and background downloads and API calls in single-page apps. For example, Facebook has seen some benefits from HoL blocking removal when using HTTP/3 to load data in its native app.

    UDP and TLS Performance

    A fifth performance aspect of QUIC and HTTP/3 is about how efficiently and performantly they can actually create and send packets on the network. We will see that QUIC’s usage of UDP and heavy encryption can make it a fair bit slower than TCP (but things are improving).

    First, we’ve already discussed that QUIC’s usage of UDP was more about flexibility and deployability than about performance. This is evidenced even more by the fact that, up until recently, sending QUIC packets over UDP was typically much slower than sending TCP packets. This is partly because of where and how these protocols are typically implemented (see figure 9 below).

    Implementation differences between TCP and QUIC

    Figure 9: Implementation differences between TCP and QUIC. (Large preview)

    As discussed aboveTCP and UDP are typically implemented directly in the OS’ fast kernel. In contrast, TLS and QUIC implementations are mostly in slower user space (note that this is not really needed for QUIC — it is mostly done because it’s much more flexible). This makes QUIC already a bit slower than TCP.

    Additionally, when sending data from our user-space software (say, browsers and web servers), we need to pass this data to the OS kernelwhich then uses TCP or UDP to actually put it on the network. Passing this data is done using kernel APIs (system calls), which involves a certain amount of overhead per API call. For TCP, these overheads were much lower than for UDP.

    This is mostly because, historically, TCP has been used a lot more than UDP. As such, over time, many optimizations were added to TCP implementations and kernel APIs to reduce packet send and receive overheads to a minimum. Many network interface controllers (NICs) even have built-in hardware-offload features for TCP. UDP, however, was not as lucky, because its more limited use didn’t justify the investment in added optimizations. In the past five years, this has luckily changed, and most OSes have since added optimized options for UDP as well.

    Secondly, QUIC has a lot of overhead because it encrypts each packet individually. This is slower than using TLS over TCP, because there you can encrypt packets in chunks (up to about 16 KB or 11 packets at a time), which is more efficient. This was a conscious trade-off made in QUIC, because bulk encryption can lead to its own forms of HoL blocking.

    Unlike the first point, where we could add extra APIs to make UDP (and thus QUIC) faster, here, QUIC will always have an inherent disadvantage to TCP + TLS. However, this is also quite manageable in practice with, for example, optimized encryption libraries and clever methods that allow QUIC packets headers to be encrypted in bulk.

    As a result, while Google’s earliest QUIC versions were still twice as slow as TCP + TLSthings have certainly improved since. For example, in recent tests, Microsoft’s heavily optimized QUIC stack was able to get 7.85 Gbps, compared to 11.85 Gbps for TCP + TLS on the same system (so here, QUIC is about 66% as fast as TCP + TLS).

    This is with the recent Windows updates, which made UDP faster (for a full comparison, UDP throughput on that system was 19.5 Gbps). The most optimized version of Google’s QUIC stack is currently about 20% slower than TCP + TLS. Earlier tests by Fastly on a less advanced system and with a few tricks even claim equal performance (about 450 Mbps), showing that depending on the use case, QUIC can definitely compete with TCP.

    However, even if QUIC were twice as slow as TCP + TLS, it’s not all that bad. First, QUIC and TCP + TLS processing is typically not the heaviest thing happening on a server, because other logic (say, HTTP, caching, proxying, etc.) also needs to execute. As such, you won’t actually need twice as many servers to run QUIC (it’s a bit unclear how much impact it will have in a real data center, though, because none of the big companies have released data on this).

    Secondly, there are still plenty of opportunities to optimize QUIC implementations in the future. For example, over time, some QUIC implementations will (partially) move to the OS kernel (much like TCP) or bypass it (some already do, like MsQuic and Quant). We can also expect QUIC-specific hardware to become available.

    Still, there will likely be some use cases for which TCP + TLS will remain the preferred option. For example, Netflix has indicated that it probably won’t move to QUIC anytime soon, having heavily invested in custom FreeBSD set-ups to stream its videos over TCP + TLS.

    Similarly, Facebook has said that QUIC will probably mainly be used between end users and the CDN’s edgebut not between data centers or between edge nodes and origin servers, due to its larger overhead. In general, very high-bandwidth scenarios will probably continue to favour TCP + TLS, especially in the next few years.

    Did You Know?

    Optimizing network stacks is a deep and technical rabbit hole of which the above merely scratches the surface (and misses a lot of nuance). If you’re brave enough or if you want to know what terms like GRO/GSOSO_TXTIMEkernel bypass, and sendmmsg() and recvmmsg() mean, I can recommend some excellent articles on optimizing QUIC by Cloudflare and Fastlyas well as an extensive code walkthrough by Microsoftand an in-depth talk from Cisco. Finally, a Google engineer gave a very interesting keynote about optimizing their QUIC implementation over time.

    What does it all mean?

    QUIC’s particular usage of the UDP and TLS protocols has historically made it much slower than TCP + TLS. However, over time, several improvements have been made (and will continue to be implemented) that have closed the gap somewhat. You probably won’t notice these discrepancies in typical use cases of web-page loading, though, but they might give you headaches if you maintain large server farms.

    HTTP/3 Features

    Up until now, we’ve mainly talked about new performance features in QUIC versus TCP. However, what about HTTP/3 versus HTTP/2? As discussed in part 1HTTP/3 is really HTTP/2-over-QUICand as such, no real, big new features were introduced in the new version. This is unlike the move from HTTP/1.1 to HTTP/2, which was much larger and introduced new features such as header compression, stream prioritization, and server push. These features are all still in HTTP/3, but there are some important differences in how they are implemented under the hood.

    This is mostly because of how QUIC’s removal of HoL blocking works. As we’ve discusseda loss on stream B no longer implies that streams A and C will have to wait for B’s retransmissions, like they did over TCP. As such, if A, B, and C each sent a QUIC packet in that order, their data might well be delivered to (and processed by) the browser as A, C, B! Put differently, unlike TCP, QUIC is no longer fully ordered across different streams!

    This is a problem for HTTP/2, which really relied on TCP’s strict ordering in the design of many of its features, which use special control messages interspersed with data chunks. In QUIC, these control messages might arrive (and be applied) in any order, potentially even making the features do the opposite of what was intended! The technical details are, again, unnecessary for this article, but the first half of this paper should give you an idea of how stupidly complex this can get.

    As such, the internal mechanics and implementations of the features have had to change for HTTP/3. A concrete example is HTTP header compressionwhich lowers the overhead of repeated large HTTP headers (for example, cookies and user-agent strings). In HTTP/2, this was done using the HPACK set-up, while for HTTP/3 this has been reworked to the more complex QPACK. Both systems deliver the same feature (i.e. header compression) but in quite different ways. Some excellent deep technical discussion and diagrams on this topic can be found on the Litespeed blog.

    Something similar is true for the prioritization feature that drives stream multiplexing logic and which we’ve briefly discussed above. In HTTP/2, this was implemented using a complex “dependency tree” set-up, which explicitly tried to model all page resources and their interrelations (more information is in the talk “The Ultimate Guide to HTTP Resource Prioritization”). Using this system directly over QUIC would lead to some potentially very wrong tree layouts, because adding each resource to the tree would be a separate control message.

    Additionally, this approach turned out to be needlessly complex, leading to many implementation bugs and inefficiencies and subpar performance on many servers. Both problems have led the prioritization system to be redesigned for HTTP/3 in a much simpler way. This more straightforward set-up makes some advanced scenarios difficult or impossible to enforce (for example, proxying traffic from multiple clients on a single connection), but still enables a wide range of options for web-page loading optimization.

    While, again, the two approaches deliver the same basic feature (guiding stream multiplexing), the hope is that HTTP/3’s easier set-up will make for fewer implementation bugs.

    Finally, there is server push. This feature allows the server to send HTTP responses without waiting for an explicit request for them first. In theory, this could deliver excellent performance gains. In practice, however, it turned out to be hard to use correctly and inconsistently implemented. As a result, it is probably even going to be removed from Google Chrome.

    Despite all this, it is still defined as a feature in HTTP/3 (although few implementations support it). While its internal workings haven’t changed as much as the previous two features, it too has been adapted to work around QUIC’s non-deterministic ordering. Sadly, though, this will do little to solve some of its longstanding issues.

    What does it all mean?

    As we’ve said before, most of HTTP/3’s potential comes from the underlying QUIC, not HTTP/3 itself. While the protocol’s internal implementation is very different from HTTP/2’s, its high-level performance features and how they can and should be used have stayed the same.

    Future Developments to Look Out For

    In this series, I have regularly highlighted that faster evolution and higher flexibility are core aspects of QUIC (and, by extension, HTTP/3). As such, it should be no surprise that people are already working on new extensions to and applications of the protocols. Listed below are the main ones that you’ll probably encounter somewhere down the line:

    • Forward error correction
      This purpose of this technique is, again, to improve QUIC’s resilience to packet loss. It does this by sending redundant copies of the data (though cleverly encoded and compressed so that they’re not as large). Then, if a packet is lost but the redundant data arrives, a retransmission is no longer needed.

      This was originally a part of Google QUIC (and one of the reasons why people say QUIC is good against packet loss), but it is not included in the standardized QUIC version 1 because its performance impact wasn’t proven yet. Researchers are now performing active experiments with it, though, and you can help them out by using the PQUIC-FEC Download Experiments app.

    • Multipath QUIC
      We’ve previously discussed connection migration and how it can help when moving from, say, Wi-Fi to cellular. However, doesn’t that also imply we might use both Wi-Fi and cellular at the same time? Concurrently using both networks would give us more available bandwidth and increased robustness! That is the main concept behind multipath.

      This is, again, something that Google experimented with but that didn’t make it into QUIC version 1 due to its inherent complexity. However, researchers have since shown its high potential, and it might make it into QUIC version 2. Note that TCP multipath also exists, but that has taken almost a decade to become practically usable.

    • Unreliable data over QUIC and HTTP/3
      As we’ve seen, QUIC is a fully reliable protocol. However, because it runs over UDP, which is unreliable, we can add a feature to QUIC to also send unreliable data. This is outlined in the proposed datagram extension. You would, of course, not want to use this to send web page resources, but it might be handy for things such as gaming and live video streaming. This way, users would get all of the benefits of UDP but with QUIC-level encryption and (optional) congestion control.

    • WebTransport
      Browsers don’t expose TCP or UDP to JavaScript directly, mainly due to security concerns. Instead, we have to rely on HTTP-level APIs such as Fetch and the somewhat more flexible WebSocket and WebRTC protocols. The newest in this series of options is called WebTransport, which mainly allows you to use HTTP/3 (and, by extension, QUIC) in a more low-level way (although it can also fall back to TCP and HTTP/2 if needed).

      Crucially, it will include the ability to use unreliable data over HTTP/3 (see the previous point), which should make things such as gaming quite a bit easier to implement in the browser. For normal (JSON) API calls, you’ll, of course, still use Fetch, which will also automatically employ HTTP/3 when possible. WebTransport is still under heavy discussion at the moment, so it’s not yet clear what it will eventually look like. Of the browsers, only Chromium is currently working on a public proof-of-concept implementation.

    • DASH and HLS video streaming
      For non-live video (think YouTube and Netflix), browsers typically make use of the Dynamic Adaptive Streaming over HTTP (DASH) or HTTP Live Streaming (HLS) protocols. Both basically mean that you encode your videos into smaller chunks (of 2 to 10 seconds) and different quality levels (720p, 1080p, 4K, etc.).

      At runtime, the browser estimates the highest quality your network can handle (or the most optimal for a given use case), and it requests the relevant files from the server via HTTP. Because the browser doesn’t have direct access to the TCP stack (as that’s typically implemented in the kernel), it occasionally makes a few mistakes in these estimates, or it takes a while to react to changing network conditions (leading to video stalls).

      Because QUIC is implemented as part of the browser, this could be improved quite a bit, by giving the streaming estimators access to low-level protocol information (such as loss rates, bandwidth estimates, etc.). Other researchers have been experimenting with mixing reliable and unreliable data for video streaming as well, with some promising results.

    • Protocols other than HTTP/3
      With QUIC being a general purpose transport protocol, we can expect many application-layer protocols that now run over TCP to be run on top of QUIC as well. Some works in progress include DNS-over-QUICSMB-over-QUICand even SSH-over-QUIC. Because these protocols typically have very different requirements than HTTP and web-page loading, QUIC’s performance improvements that we’ve discussed might work much better for these protocols.

    What does it all mean?

    QUIC version 1 is just the start. Many advanced performance-oriented features that Google had earlier experimented with did not make it into this first iteration. However, the goal is to quickly evolve the protocol, introducing new extensions and features at a high frequency. As such, over time, QUIC (and HTTP/3) should become clearly faster and more flexible than TCP (and HTTP/2).

    Conclusion

    In this second part of the series, we have discussed the many different performance features and aspects of HTTP/3 and especially QUIC. We have seen that while most of these features seem very impactful, in practice they might not do all that much for the average user in the use case of web-page loading that we’ve been considering.

    For example, we’ve seen that QUIC’s use of UDP doesn’t mean that it can suddenly use more bandwidth than TCP, nor does it mean that it can download your resources more quickly. The often-lauded 0-RTT feature is really a micro-optimization that saves you one round trip, in which you can send about 5 KB (in the worst case).

    HoL blocking removal doesn’t work well if there is bursty packet loss or when you’re loading render-blocking resources. Connection migration is highly situational, and HTTP/3 doesn’t have any major new features that could make it faster than HTTP/2.

    As such, you might expect me to recommend that you just skip HTTP/3 and QUIC. Why bother, right? However, I will most definitely do no such thing! Even though these new protocols might not aid users on fast (urban) networks much, the new features do certainly have the potential to be highly impactful to highly mobile users and people on slow networks.

    Even in Western markets such as my own Belgium, where we generally have fast devices and access to high-speed cellular networks, these situations can affect 1% to even 10% of your user base, depending on your product. An example is someone on a train trying desperately to look up a critical piece of information on your website, but having to wait 45 seconds for it to load. I certainly know I’ve been in that situation, wishing someone had deployed QUIC to get me out of it.

    However, there are other countries and regions where things are much worse still. There, the average user might look a lot more like the slowest 10% in Belgium, and the slowest 1% might never get to see a loaded page at all. In many parts of the worldweb performance is an accessibility and inclusivity problem.

    This is why we should never just test our pages on our own hardware (but also use a service like Webpagetest) and also why you should definitely deploy QUIC and HTTP/3. Especially if your users are often on the move or unlikely to have access to fast cellular networks, these new protocols might make a world of difference, even if you don’t notice much on your cabled MacBook Pro. For more details, I highly recommend Fastly’s post on the issue.

    If that doesn’t fully convince you, then consider that QUIC and HTTP/3 will continue to evolve and get faster in the years to come. Getting some early experience with the protocols will pay off down the road, allowing you to reap the benefits of new features as soon as possible. Additionally, QUIC enforces security and privacy best practices in the background, which benefit all users everywhere.

    Finally convinced? Then stay tuned for part 3 of the series to read about how you can go about using the new protocols in practice.

    This series is divided into three parts:

    1. HTTP/3 history and core concepts
      This is targeted at people new to HTTP/3 and protocols in general, and it mainly discusses the basics.
    2. HTTP/3 performance features (current article)
      This is more in depth and technical. People who already know the basics can start here.
    3. Practical HTTP/3 deployment options (coming up soon!)
      This explains the challenges involved in deploying and testing HTTP/3 yourself. It details how and if you should change your web pages and resources as well.
    Smashing Editorial" width="35" height="46" loading="lazy" decoding="async(vf, il, al)



  • Source link