Le TTFB ? Ouatszat ?
C’est le Time To First Byte.
Quand un client (navigateur ou bot) demande une page, il s’écoule « un certain temps » entre sa requête et l’arrivée du premier Octet en retour du serveur.
C’est ce fameux TTFB.
Pourquoi tu nous parles de TTFB ? A quoi ça sert ?
Des études[1] ont montré une corrélation nette entre TTFB bas et rankings.
C’est bon, vous me suivez maintenant ?
Comment ça peut s’expliquer ?
Bah, quelques pistes comme ça, sans détailler :
- Importance de la vitesse pour Google
- Google AMP
- Mesure plus simple que temps d’affichage
- Aspect UX : page commence à s’afficher plus vite
Ce que je retiens, dans la logique de ma présentation du Tekn, c’est l’aspect simplexité, mesure locale :
mesurer la vitesse avec un pseudo navigateur, en chargeant tout, en interprétant le JS, ça prend du temps et des ressources.
Mesurer le TTFB, ça se fait en deux coups de cuillère à pot, sans requête supplémentaire, même avec des bots basiques (la preuve en quelques lignes de code plus bas si vous êtes sage).
Le crawler peut donc utiliser ce signal, même imparfait, dès le crawl, sans ressource particulière, et « décider » déjà à ce moment de suivre ou pas.
Mais en fait, c’est juste le ping, la bande passante de mon serveur ?
Nope.
La bande passante, c’est à quelle vitesse le contenu d’un fichier va être transféré.
Sur un gros fichier, la BP fait la différence. Sur un petit, c’est le temps de latence réseau
(le ping).
Mais le TTFB ce n’est pas juste la latence réseau.
Je peux interroger la machine juste en face de moi, si le serveur apache/php met 2 secondes à faire ses requêtes avant d’envoyer la page, le ping peut être de 1ms, je n’aurais mon premier octet que 2 secondes plus tard.
See the difference ?
Ce que le TTFB ne mesure pas, comme on l’a vu, c’est le temps d’affichage total, qui lui va dépendre, en plus,
de la taille des ressources liées (images,css,js) , de la bande passante, et des requêtes ajax éventuelles.
Ca reste pourtant un indicateur avec un excellent rapport pertinence/cout d’obtention.
Comment je mesure ce machin ?
Une méthode simple, via un site comme webpagetest
Une « bonne » valeur, c’est sous 500ms, mais on peut avoir beaucoup moins.
(cocon.se, moins de 100ms par exemple, mais il y a mieux)
Comment j’optimise ?
Bonne question !
Quelques pistes :
- Allez jeter un coup d’oeil chez Moz [2]
- Utilisez un système de cache « qui va bien » (testez le quoi)
- Utilisez des CMS statiques quand possible
- Php ? pensez au garbage collector qui peut vous mettre dans la panade bien profond [3]
Le préssssieux, où est mon préssssieux ?
Paré pour le code ?
Christian s’est décarcassé pour vous, il a même lu des articles techniques en Anglais [4] et [5]
et vous offre généreusement du code en Bash, en Shell Windows, et en Linux.
Alors là si j’en vois qui râlent encore au fond de la salle, je ne comprends plus rien !
Mesurer le TTFB en bash sous linux
Curl_HTTP_Response_Times.sh
#!/bin/bash # # Mesurer le TTFB d'une requête HTTP # Utilisation: Curl_HTTP_Response_Times.sh http://cocon.se/ # # Rem: Les durées sont exprimées en secondes. # clear curl -w "@Curl_HTTP_Response_Times_Format.txt" -o /dev/null -H "Pragma: no-cache" -H "Cache-Control: no-cache" -s "$@"
Pour formater la sortie, ce script utilise le fichier
Curl_HTTP_Response_Times_Format.txt
Name lookup : %{time_namelookup} sec.\n Connect : %{time_connect} sec.\n App connect : %{time_appconnect} sec.\n Pre transfert : %{time_pretransfer} sec.\n Redirection : %{time_redirect} sec.\n Time to first byte: %{time_starttransfer} sec.\n ----------\n Total : %{time_total} sec.\n \n
Ah oui, on vous on donne plus pour le même prix :
- Name lookup (time_namelookup): Durée de résolution du nom de domaine.
- Connect (time_connect) : Durée d’établissement de la connexion.
- App connect (time_appconnect) : Durée jusqu’à ce que SSL/SSH/ & connect/handshake à l’hte distant soit achevée.
- Pre transfert (time_pretransfer): Durée entre le début de la transaction et le début du transfert de fichiers.
- Redirection (time_redirect): Durée de toutes les étapes de redirection avant que la transaction finale ne soit débutée.
- Time to first byte (time_starttransfer): Durée jusqu’à ce que le premier octet soit sur le point d’être transféré (TTFB).
- Total (time_total): Durée nécessaire jusqu’à la fin de l’opération.
Mesurer le TTFB en batch sous Windows
Curl_HTTP_Response_Times.cmd
@ECHO OFF REM REM Mesurer le TTFB d'une requête HTTP REM Utilisation: Curl_HTTP_Response_Times.sh http://cocon.se/ REM SET current_dir = %~dp0 %current_dir%curl-7.46.0-win64\bin\curl -w "@Curl_HTTP_Response_Times_Format.txt" -o NUL -s %* ECHO. PAUSE
Il vous faudra avoir installé l’exécutable curl dans le sous-répertoire qui va bien (%current_dir%curl-7.46.0-win64\bin\curl dans le code), et vous aurez aussi besoin du fichier de format txt listé au dessus.
Exemple d’utilisation dans un .bat
Exec-Curl_HTTP_Response_Times.bat
@Curl_HTTP_Response_Times http://cocon.se/
Mesurer le TTFB avec PHP
Nous y voilà :
Curl_HTTP_Response_Times.php
<?php $url = $argv[1]; $headers = array( "Cache-Control: no-cache", "Pragma: no-cache" ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $out = curl_exec($ch); $curlInfo = curl_getinfo($ch); curl_close($ch); echo PHP_EOL; echo "Temps de reponse Url: ${url}".PHP_EOL; echo PHP_EOL; printf(" Name lookup : %0.3f sec.%s", $curlInfo['namelookup_time'], PHP_EOL); printf(" Connect : %0.3f sec.%s", $curlInfo['connect_time'], PHP_EOL); printf(" Pre transfert : %0.3f sec.%s", $curlInfo['pretransfer_time'], PHP_EOL); printf(" Redirection : %0.3f sec.%s", $curlInfo['redirect_time'], PHP_EOL); printf(" Time to first byte: %0.3f sec.%s", $curlInfo['starttransfer_time'], PHP_EOL); printf(" ----------%s", PHP_EOL); printf(" Total : %0.3f sec.%s", $curlInfo['total_time'], PHP_EOL); echo PHP_EOL;
Alors, facile non ?
Allez, un complément suite aux questions d’Aurélien (Htitipi, lecture de son blog plus que recommandée si vous l’aviez – je ne sais comment – loupé)
Les CDNs , on en parle ?
Un CDN – Content Distribution Network – ca aide ou pas ?
Si ce que vous avez sur le CDN, ce sont les ressources (média, js, css) : pas d’incidence sur le TTFB.
Le TTFB qui peut jouer sur les rankings, c’est celui de l’url. La page html, qui elle va appeller les resources.
Pour les ressources, là la bande passante et le temps de latence vont jouer.
Si site statique, ou en cache, et que le contenu html peut être servi par un cdn, oui, ça peut jouer.
Attention, en bien comme en mal.
En bien, car CDN = plusieurs caches distribués partout, donc il y a à priori une machine proche du client, donc temps de latence réseau réduit, donc meilleur TTFB.
En mal, car certains CDNs sont tellement parano sur le blocage des bots, la protection Déni de service, les crawls profonds, que même les bots légitimes y laissent des plumes (on en reparlera plus spécifiquement : Cloudflare, je ne t’aime pas !)
Maintenant, le gros du temps de TTFB, c’est de l’applicatif. C’est votre serveur ou script php qui patine avant de se réveiller, et ça, c’est bien plus important que la latence réseau.
Le critère qui semble vraiment important, ce n’est pas tant le TTFB le plus bas possible, qu’un TTFB < 0.5s. Attention, d'autres facteurs vont jouer, indépendamment. Ex la durée avant affichage, qui joue sur l'UX et donc le taux de rebond, elle sera directement impactée par des cdn, même si on n'utilise des CDN que pour les fichiers statiques.
Comment mesurer le TTFB si on utilise un CDN ?
Pareil que si on n’en n’a pas.
C’est une mesure prise coté client. Les sites de mesure de vitesse proposent différents points géographiques de test, on peut prendre des mesures de partout.
Remonter le TTFB dans les logs ?
Aurélien Précise « en faisant un peu de tuning avec Apache (ou Nginx) il est possible d’ajouter à la configuration des access logs les paramètre %t et %D, respectivement TTFB et TTLB (Time To Last Byte). Avec une stack ELK derrière, ça peut donner des trucs sympa. Pour autant, est-ce que l’on peut se fier à ces indicateurs ? »
Je ne pratique pas, et à mon avis ça n’a pas forcément de sens de le faire en temps réel, en continu.
D’une part, il y a plein de facteurs qui peuvent faire que ces mesures, prises coté serveur, ne soient pas vraiment les mêmes que celles mesurées coté client.
Mais surtout : Ce qui impacte le plus ce TTFB, c’est l’applicatif.
Le reste, c’est du réseau.
On a donc une partie réseau, sur laquelle on a vite fait de lister des leviers (changer d’hébergeur, site statique sur cdn, un hébergeur par pays ciblé)
Ce qui reste, c’est donc de l’applicatif, du code.
Ca, ça ne change pas selon l’utilisateur, sa localisation.
Si il y a un problème, il sera présent à priori tout le temps, et le corriger le corrigera durablement.
Mon approche serait plutôt de dire : quand on a une raison de douter, on fait un test ponctuel.
On re-teste périodiquement (cas de fichiers ou bases qui grossissent, et peuvent impacter)
Un test coté client, depuis des localisations clé, suffit à mon avis.
On peut gérer ça soi même via quelques vps judicieusement placés, c’est facile (vous avez le code maintenant) et ça ne coute pas grand chose.
Le mettre d’office dans les logs, ça me semble lourd.
Là où ça pourrait être utile, d’avoir dans les logs, c’est pour un audit ponctuel :
on a parfois des sites avec des sections différentes, et on peut tomber sur des pages spécifiques qui posent problème, alors que le gros du site est ok.
Pour identifier les mauvais élèves, là c’est top.
(l’alternative, c’est d’utiliser un sitemap et de boucler sur toutes les urls, coté client – ça le fait aussi.)
Donc pourquoi pas ?
Si dans ton process habituel, tu as déjà une stack ELK, les alertes qui vont avec;
Si tu vérifies que les TTFB que tu mesure sont du même ordre que coté client,
ça peut être tout aussi simple de surveiller comme ça.
Dans tous les cas, cette mesure du TTFB, c’est tellement facile et rapide, qu’il ne faut pas s’en passer lors d’un audit, lors de la mise en ligne d’un site ou de sa refonte.
C’est là qu’on peut lever un gros lièvre, et corriger au mieux, dès le début.
Sylvain
@SylvainDeaure
Tweeter « Le TTFB : incidence sur le ranking, mesure et optimisation »
D’autres articles techniques ? Avec plaisir :
- Stockage d’un graphe avec FireBase
- Optimisation PHP et passage par référence
- Gagner des 100ms
- Scrapy chez Cocon
- Stockage à froid OVH pour backup low cost : Un tuto
[1] : https://moz.com/blog/how-website-speed-actually-impacts-search-ranking
[2] : https://moz.com/blog/improving-search-rank-by-optimizing-your-time-to-first-byte
[3] : https://tideways.io/profiler/blog/php-session-garbage-collection-the-unknown-performance-bottleneck
[4] : http://www.jonefox.com/blog/2011/10/10/find-the-time-to-first-byte-using-curl/comment-page-1/
[5] : https://josephscott.org/archives/2011/10/timing-details-with-curl/
Merci pour toutes ces ressources 🙂
J’ai quelques questions qui me taraudent : pour speeder l’affichage des pages, et le TTFB, on a de plus en plus recours à des CDN. Comment mesurer dans ces cas la le(s) TTFB d’un serveur sans tomber dans un process usine à gaz ?
Autre détail : en faisant un peu de tuning avec Apache (ou Nginx) il est possible d’ajouter à la configuration des access logs les paramètre %t et %D, respectivement TTFB et TTLB (Time To Last Byte). Avec une stack ELK derrière, ça peut donner des trucs sympa. Pour autant, est-ce que l’on peut se fier à ces indicateurs ?
Bon, ben voilà…
Tu finis un article et Aurélien te pose des bonnes questions qui te donnent envie de recommencer tellement il y a encore de choses à dire.
Je vais éditer l’article pour compléter, je pense que ça y a sa place.
Merci en tout cas !
Juste une remarque: les cdn, pour ce que j’en sais (je ne suis pas webmaster), sont utilisés pour délivrer des ressources secondaires statiques, embarquées dans la page html principale (celle dont on mesure le TTFB).
Ils sont donc de toutes les manières sollicités aprés le chargement complet et il ne me semble donc pas qu’ils aient d’impact sur le TTFB.
Mais je peux me tromper.
Merci;
J’ai complété des choses dans l’article entre deux.
Oui sur le principe,
Le CDN peut toutefois avoir une incidence si (type cloudflare) ça fait cache de la page html en même temps.
A ce propos, ma question sur les CDN n’était pas relative aux « petits » CDN de ressources (images, js, css toussa), mais bien les serveurs type Cloudflare, Akamai (enfin je crois) ou encore Coreye. D’ailleurs, je ne sais toujours pas comment les désigner : proxies ? CDN ? Cache ?
Oui, c’est un peu mixte !
C’est du 3 en 1 reverse-proxy, cache et CDN 😀
Perso, je n’aime pas. Trop de perte de contrôle (et accessoirement, plus possible de cloaker proprement)
Bel article 😉
%t et %D on peut le remonter et le coller dans des graphes munin, ca permet de suivre dans le temps pour vérifier que les perf sont stables ( charge serveur, cron … )
Yep.
Après il faut analyser bien, c’est plus compliqué :
Tu as eu un TTFB important, est-ce à cause du site, du cron en même temps, d’un user particulier au fond de la brousse qui crawle ton site
C’est comme pour tout en SEO, il n’y a pas forcément une réponse unique facile à tout.
Merci 😉
Pour @GPeyronnet , lors du live ixlabs, le TTFB optimal pour Google c’est < 250 ms
Hello !
Déjà merci pour l’article et les codes qui vont bien, j’étais justement en pleine analyse de TTFB quand il est sorti, une synchro parfaite 😉 !
Du coup petite question, je me sers du script PHP, et d’après mes tests les TTFB remontent 0 quand sur des urls https. Une idée du pourquoi du comment ?
Merci.
Affiche les headers/ code retour.
Ca ressemble à une erreur de certificat , curl n’a pas pu négocier TLS.
Tu as une option pour ignorer les erreurs de certificat, sinon mets ta machine à jour.
« -k, –insecure (SSL) This option explicitly allows curl to perform « insecure » SSL connections and transfers. »
Wow là tu dépasses mes pôv connaissances en dev et je suis sur wamp, donc pour maj la machine chaud ^^
Mais ça me donne des mots-clés pour creuser l’histoire. Merci en tous cas.
Et voilou, il suffit de rajouter : curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
Merci encore 🙂
Ben vàlà 🙂 nickel
Dans la suite des curl_setopt,
ajoute les lignes :
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
et tiens moi au courant si ça marche !
Merci pour votre article et le partage de ce script.
Petite question, pensez-vous qu’un flush(); bien positionné puisse avoir un impact?
Même si je ne pense pas, puisque si cela peut avoir un impact sur la vitesse ressentit coté user (début de chargement plutôt des css, voir js , si les js sont dans le header), mais coté bot/crawler je vois pas.
Dans le mêne sens pensez vous que le prefetch, et prerender puisse avoir un impact?
Selon les cas, pas impossible qu’un flush puisse rendre plus rapide le 1er byte.
prefetch et pre-render, ça joue sur vitesse ressentie, pas sur TTFB.