Prix ​​cher des styles. Rapport Yandex

Le chargement de CSS sur une page est une opération de blocage. Si le chargement asynchrone de JavaScript peut ne pas être visible pour l'utilisateur, alors la lenteur de l'apparition des styles peut pousser un invité impatient à quitter le site. Comment charger CSS de manière aussi efficace et transparente que possible pour les utilisateurs? Nikita Dubko essaie de comprendreDarkMeFoDy du groupe d'interface de recherche Yandex à Minsk.


- Bonjour à tous. Je vais vous parler des styles. Tout le monde parle de TypeScript et TypeScript aujourd'hui. Et je vais parler du script de style Cascade.

Peu de temps sur moi. Je suis un développeur biélorusse - après le film Dudya, je le dirai partout. Vous avez peut-être entendu ma voix dans le podcast Web Standards, et si vous voyez des fautes de frappe dans le fil d'actualités Web Standards, c'est probablement moi aussi.

Petit avertissement. Il y aura plusieurs folies dans le rapport - traitez tout ce que je dis avec beaucoup de critiques. Réfléchissez à la raison pour laquelle vous pouvez utiliser ces techniques et pourquoi vous n'en avez pas besoin. Certaines choses seront vraiment folles. Aller.

Pourquoi?


Pour commencer - pourquoi parler d'optimisation CSS?

Si vous commencez à chercher dans les moteurs de recherche des téléchargements JS rapides, il y a beaucoup de résultats. Si vous recherchez un chargement CSS rapide, le haut n'affiche même pas le CSS dont vous avez besoin.



Si vous regardez Google, il y a 111 millions de résultats sur JS et environ CSS sur 26 millions.

Alors peut-être que cela n'a pas d'importance? Pourquoi en parler? Si vous recherchez des rapports de performance JS, vous en trouverez beaucoup. Il y a à propos de React, de toutes sortes d'autres frameworks, de Vanilla, etc. Mais à propos de CSS, je n'ai trouvé qu'un seul rapport. Harry Roberts en 2018 a lu un rapport sympa sur les performances CSS. Je pensais avoir trouvé un deuxième rapportpar Roma Dvornova, «Parsim CSS: conseils et astuces de performance». Mais il s'est avéré être un rapport JS qui analyse CSS. Pas exactement ce dont nous avons besoin.

Il s'avère qu'ils ne pensent pas beaucoup au CSS. C'est dommage.

Mais quand je vais sur le Web, je vois généralement du HTML. Et je vois aussi du CSS qui stylise la page. Mais je ne vois pas JS. JS est une chose qui déplace CSS et HTML sur une page pour que tout soit beau. Ceci est un script. Et si JS ne se charge pas, ce n'est pas aussi mauvais que si CSS ne se charge pas.

Les erreurs dans JS tombent silencieusement dans la console. Et il est peu probable que l'utilisateur moyen entre dans DevTools pour regarder: "Oh, vous l'avez là, une erreur dans la console." Mais si CSS ne se charge pas, vous ne verrez peut-être pas du tout tout ce dont vous avez besoin.

Soit dit en passant, il existe des études sur le fait que l'essentiel est de faire une première impression.38% des utilisateurs peuvent aller sur le site, et s'ils voient que c'est directement dégoûtant, ils partiront immédiatement. Et 88% toléreront, l'utiliseront une fois, puis ils ne reviendront jamais et sont peu susceptibles de conseiller votre site.

Maintenant que nous sommes tous assis à la maison, le trafic Internet a particulièrement augmenté. Et nous devons réfléchir à la manière de fournir efficacement des ressources aux utilisateurs.

Essayons de compter du point de vue de Yandex. Si nous pouvons optimiser chaque livraison Yandex pendant 100 ms et donner, disons, 200 millions de pages par jour (je ne connais pas le nombre exact), alors ce jour nous économiserons 0,1 s * 200 millions = 232 personnes-jours. Juste en optimisant la sortie pour 100 millisecondes. Et CSS le fait aussi.

Jouons un peu aux détectives et découvrons comment tirer le meilleur parti des styles de chargement.

Mesure!


Le tout premier conseil est de toujours tout mesurer. Il est inutile de faire des optimisations théoriquement. Vous pouvez supposer que l'optimisation fonctionne dans votre cas, mais des mesures réelles ne montreront rien de tel. Il s'agit de la règle la plus importante de toute optimisation. Andrei Prokopyuk de l'équipe SERP Velocity sur HolyJS a très bien expliqué comment nous procédons , je ne vais pas me répéter.

Quels outils de mesure existe-t-il?

- Si vous voulez mesurer sur des appareils plus ou moins réels, lents, pas aussi cool que les vôtres, utilisez WebPageTest . J'y prends habituellement des mesures.

- Vous avez Lighthouse si vous utilisez des navigateurs basés sur Chromium. Lui, comme les mesures locales, montre de très bonnes choses.

- Si vous êtes sûr de pouvoir tout faire vous-même, accédez à DevTools, dans l'onglet Performances. Il a beaucoup de détails, vous pouvez démarrer vos propres métriques et les analyser.



Naturellement, dans Performance, il est nécessaire de définir des conditions réelles. Vous êtes assis sur votre ordinateur portable cool avec Internet cool dans le bureau, tout est incroyable ici, mais ils viennent à vous et disent: "Je suis lent." Et vous dites: "Tout fonctionne pour moi." Ne fais pas ça.

Essayez toujours de vérifier comment l'utilisateur dans les conditions du métro ou ailleurs utilisera votre site. Pour ce faire, vous devez configurer un Internet très lent. Il est également conseillé de ralentir le CPU, car quelqu'un peut venir chez vous depuis un Nokia 3110. Il a également besoin de montrer le site.

Le plus important: mesurer sur de vrais utilisateurs. Il existe une telle métrique, plus précisément, tout un ensemble de métriques - RUM, Real User Monitoring. C'est lorsque vous mesurez non pas ce qui se passe synthétiquement dans votre code, mais des mesures sur de vrais utilisateurs en production. Par exemple, du chargement d'une page à une action. Une action est, par exemple, quelque chose qui fonctionne dans le navigateur ou même un clic sur un élément important.

N'oubliez pas que vous ne développez pas pour les robots. Sotka in Lighthouse - c'est super, c'est vraiment bon. Ainsi, vous remplissez au moins les exigences fixées par le phare. Mais il y a de vrais utilisateurs, et si l'utilisateur n'est pas en mesure de voir la page lorsqu'il se soulève dans Lighthouse, alors vous faites quelque chose de mal.



Il y a des paramètres sur lesquels il est important de se concentrer. Il s'agit de First Contentful Paint, lorsque le premier contenu apparaît sur votre page avec lequel vous pouvez faire quelque chose, lisez. Cette métrique est envoyée dans les navigateurs Chromium, vous pouvez l'obtenir.



Récemment, vous pouvez toujours consulter la plus grande peinture riche en contenu. Il arrive souvent que vous ayez une page média, et il est important, par exemple, de regarder une photo dessus. Ensuite, vous avez besoin de cette métrique particulière.

Chargement CSS


Passons enfin au CSS, comment le CSS est chargé. Les réceptions sont connues depuis longtemps. Il existe un chemin de rendu critique, un chemin de rendu critique. Il s'agit de ce que fait le navigateur depuis le moment de l'envoi de la demande de ressource jusqu'au moment où les pixels sont affichés sur l'écran de l'utilisateur. À ce sujet aussi, il y a un tas d'articles et de rapports. Mais jetons un coup d'œil à la façon dont ce navigateur le fait.

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS —  </title>
    <link rel="stylesheet" href="/main.ac74gsac.css">
</head>

Il commence à télécharger du HTML, voit des balises. Il les analyse progressivement, comprend ce qu'il faut en faire. Charges. Entré à travers le lien. Il doit être utilisé. Mais comment? Vous devez d'abord le télécharger. Le téléchargement est lent. Lorsqu'il se charge, il commence à analyser la page davantage.

 <!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS —  </title>
    <link rel="stylesheet" href="/main.ac74gsac.css">
</head>
<body>
    <h1>-!</h1>
</body>
</html>

S'il tombe sur un autre lien, il est à nouveau bloqué et ne permet pas son exécution. Bloque JS, bloque l'analyse. Et jusqu'à ce qu'il démarre, il ne fait rien. Mais ensuite, cela commence à fonctionner davantage.

<link>


Allons plus loin - que se passe-t-il lorsque vous accédez au lien?



L'enregistrement où nous allons est standard. Il y a un style CSS qui se trouve quelque part. Maintenant, il est à la mode de mettre toutes les statistiques sur le CDN.

Où aller?


Tout d'abord, le navigateur doit comprendre où aller.



Il voit l'URL et il doit comprendre cette URL - de quoi s'agit-il? Nous sommes habitués au fait que l'URL est un identifiant de site.



Mais physiquement, nous devons obtenir l'adresse IP de cette URL et accéder à la véritable machine physique à l'adresse IP.



Pour votre CDN, il recevra un enregistrement DNS et ira directement à l'adresse IP. Comment accélérer dans ce cas?



Une idée folle est de réduire la distance entre l'utilisateur et le serveur DNS. Prenez et transplantez l'utilisateur. Par exemple, pour afficher le message: «Asseyez-vous plus près» ou «Rapprochez-vous».

Vous pouvez immédiatement spécifier l'adresse IP dans le lien. Pourquoi devons-nous rechercher le DNS, résoudre les domaines, si vous pouvez donner immédiatement le résultat par adresse IP? C'est une façon folle, mais dans le cas des serveurs DNS mondiaux DDoS, cela peut même vous sauver.

Et nous pouvons nous débarrasser de l'obtention d'une adresse IP.



En vous tournant vers votre index.html ou vers un autre fichier, vous connaissez déjà l'adresse de domaine où vous allez. Voici juste le cas où, au lieu de stocker des statistiques sur un domaine ou sous-domaine séparé, vous pouvez rapprocher les statistiques de votre domaine, à savoir ce domaine lui-même. Le DNS n'a alors pas besoin d'être résolu, il l'est déjà.



Nous avons trouvé où aller. Mais nous pouvons faire de telles choses à l'avance pour le navigateur. Si, par exemple, votre feuille de style est chargée beaucoup plus tard via l'arborescence DOM, vous pouvez dire au navigateur en utilisant <link rel = "dns-prefetch"> que "je n'y vais pas encore, mais vous réchaufferez les ressources, j'en aurai certainement besoin plus tard ".

Avec cette entrée, vous dites au navigateur de descendre et d'obtenir ce DNS. Lorsque le lien apparaît dans le code, le navigateur connaît déjà l'adresse IP de ce domaine. Vous pouvez faire de telles choses préliminaires. La même chose, par exemple, avant d'entrer dans la page suivante, où vous irez certainement.

Ok, le navigateur sait où aller. Il doit comprendre comment s'y prendre.

Comment y aller


Nous observons le protocole. Maintenant, bien sûr, https est une exigence directe. L'inclusion de moteurs de recherche marquera vos sites ne figurant pas sur https avec des formulaires comme n'étant pas entièrement sûrs.

J'ai trouvé une incroyable série de bandes dessinées sur le fonctionnement de la carte https. Mais nous sommes des informaticiens, nous adorons les diagrammes complexes et les bandes dessinées amusantes sont trop faciles.



Ici, j'ai formulé dans mes propres mots comment fonctionne https. Vous obtenez d'abord un certificat SSL de votre serveur. Ensuite, vous devez vérifier le certificat auprès d'une autorité de certification. Ce sont des serveurs spéciaux qui savent ce qui est valide et ce qui ne l'est pas, et peuvent inviter les navigateurs: «oui, tout va bien ici, utilisez ce certificat».

Vient ensuite la génération de clés de communication entre le serveur et le client, le chiffrement, le déchiffrement à l'aide de clés différentes. Le processus est intéressant si vous le regardez en termes de cryptographie. Mais nous voulons accélérer. Comment?



Nous pouvons à nouveau transférer l'utilisateur plus près des serveurs. Nous avons déjà un DNS, maintenant nous pouvons le rapprocher de l'autorité de certification. Et mettre entre ces serveurs sera parfait.

Vous pouvez désactiver https, pourquoi en avons-nous besoin? Nous passons du temps à obtenir un certificat, à chiffrer, à déchiffrer. Pas vraiment. C'est le conseil le plus nuisible du rapport, ne le faites pas. https est la protection des données utilisateur, et http / 2 ne fonctionnera pas sans https, et http / 2 est un autre moyen d'accélérer.



Il existe également la technologie d'agrafage OCSP. Vous pouvez vérifier un certificat sans autorité de certification. C'est probablement plus proche de DevOps. Vous devez configurer votre serveur d'une certaine manière afin qu'il puisse mettre en cache la réponse de l'autorité de certification et émettre à l'utilisateur: "Croyez-moi, mon certificat est vraiment réel." Ainsi, nous pouvons enregistrer au moins l'étape à laquelle nous nous adressons à l'autorité de certification.

Mais il y a une nuance - dans Chrome, cela ne fonctionne pas, et pendant longtemps. Mais pour l'utilisateur d'autres navigateurs, vous pouvez accélérer ce processus.

J'ai déjà dit deux fois qu'il était nécessaire de transplanter l'utilisateur, et l'idée monte en flèche - pour rapprocher le serveur de l'utilisateur. Je n'ai rien découvert de nouveau pour toi. Il s'agit d'un CDN, un réseau de distribution de contenu distribué. L'idée est que vous pouvez utiliser sidienki prêt à l'emploi, créer indépendamment votre propre infrastructure et mettre un tas de serveurs à travers le monde, dans la mesure où l'argent et les opportunités vous le permettent. Mais vous devez organiser le serveur afin qu'un utilisateur australien accède aux serveurs australiens. Ici, la vitesse de la lumière joue sur vous, plus la distance est petite, plus les électrons la traversent rapidement.

Creusons plus profondément. Que se passe-t-il d'autre dans la demande? En fait, https n'est qu'un wrapper sur http. Pas seulement un emballage sympa. Et encore plus profond, http est une telle demande de la famille TCP / IP.



Comment les paquets et les octets sont-ils envoyés sur le réseau afin que tous les navigateurs, clients et serveurs communiquent entre eux? La première chose qu'un client / serveur fait sur une connexion TCP / IP est une poignée de main.

Mais en 2020, l'OMS recommande d'éviter les poignées de main. Il existe une telle technologie TCP Fast Open. Vous pouvez, au moment de la poignée de main, éviter toute la chaîne «Bonjour, je suis un client» - «Bonjour, je suis un serveur» - «Je vous crois» - «Et je vous crois. Aller". Vous pouvez déjà envoyer des données utiles en ce moment. Et si la poignée de main a réussi, une partie des données utiles est passée. Il s'agit de TCP Fast Open.

Que ramasser?


Voyons ce que le client doit retirer du serveur. L'essentiel n'est pas que le client prenne quelque chose du serveur, mais le serveur donne les données au client. Alors vous pourriez penser: User-Agent. Je peux obtenir l'agent utilisateur du client, savoir à quel navigateur l'utilisateur s'est connecté. Découvrez approximativement s'il ne me trompe pas, ce navigateur.

.example {
    display: -ms-grid;
    display: grid;
    -webkit-transition: all .5s;
    -o-transition: all .5s;
    transition: all .5s;
    -webkit-user-select: none;
       -moz-user-select: none;
        -ms-user-select: none;
            user-select: none;
    background: -webkit-gradient(linear, left top, left bottom, from(white), to(black));
    background: -o-linear-gradient(top, white, black);
    background: linear-gradient(to bottom, white, black);
}

Disons qu'il s'est connecté depuis Firefox. Comme d'habitude, j'ai un assemblage dans lequel l'autoprefixeur est ringard, il a généré un tas de code pour moi. Oui, c'est une approche cool que tout fonctionnera partout. Mais je sais déjà que l'utilisateur s'est connecté depuis Firefox.

Pourquoi ne pas désactiver tous les excès? D'accord, il y a beaucoup moins de lignes, nous envoyons moins d'octets, c'est cool.

Nous avons une version allégée de SERP, Granny. Vitaly Kharisov a parlé d'ellevithar, rapport de classe sur les Web Standards Days. Il utilise exactement cette approche. Nous pouvons générer plusieurs bundles et les donner à différents clients de différentes manières. Ils pèsent beaucoup moins, car Firefox obtient le sien, WebKit obtient le sien, et cela fonctionne, c'est vérifié.



Plus loin. Nous traitons très probablement les demandes des utilisateurs, nous savons que la personne est autorisée et utilisons certaines informations personnelles pour elle. Il est logique que nous obtenions quelque chose de la base de données. Mais pas tout! Il y a des choses statiques qui ne diffèrent pour aucun des utilisateurs, elles sont exactement les mêmes.

James Akvuh a lu un rapport sympa à ce sujet«Rendu côté serveur. Fais le toi-même". Dans quel but? Vous savez déjà que vous avez du HTML et une sorte de CSS identique pour tous les utilisateurs. Avant d'aller chercher des données, vous pouvez générer la sortie de ces données statiques, envoyer immédiatement les plus utiles dans un flux depuis le serveur. Et après cela - optez pour les données, recevez-les rapidement, convertissez-les en modèles et donnez-les au client. Et l'utilisateur verra déjà quelque chose d'utile.



Nous l'avons mis en œuvre il y a longtemps. Nous avons sur SERP, sur la page de recherche principale, deux phases - pré-recherche et post-recherche. La recherche préalable consiste à envoyer toutes les pièces qui n'ont pas besoin de savoir quel utilisateur s'est connecté. On peut déjà lui donner, par exemple, un chapeau.

Autrement dit, nous avons une barre de recherche que l'utilisateur peut commencer à utiliser avant que tout le reste ne se charge. Ceci est utile sur une connexion lente. Nous le faisons, cela fonctionne.

Et j'ai aussi parlé de http / 2. Ceci est entièrement pris en charge par les navigateurs modernes, donc si vous ne l'avez pas encore configuré sur votre serveur, essayez au moins de savoir comment le configurer.

Server Push est une technologie géniale qui dit: «Navigateur, je ne vous ai pas encore donné la connaissance que vous avez besoin d'une sorte de CSS. Mais je sais exactement ce qui est nécessaire. Alors tenez-le, préchargez-le. "





C'est pas difficile. Vous devez configurer quelques en-têtes sur le serveur et tout commencera à fonctionner. Si le navigateur ne connaît pas ce titre, rien ne se cassera, c'est le plus beau. Creusons encore plus loin. TCP Nous en avons déjà parlé: une poignée de main, des octets sont envoyés.



Lavez-vous les mains après une poignée de main. Mais en termes de TCP, nous commençons à transmettre des octets, et les algorithmes sont suffisamment optimisés pour que le serveur client ne reste pas inactif.

Par conséquent, un certain segment de données est envoyé en premier. Par défaut, (cela vous pouvez changer dans les paramètres), il est de 1460 octets. Le serveur n'envoie pas d'informations sur un segment. Il envoie des fenêtres.

La première fenêtre est de 14 600 octets, dix segments. Ensuite, si la connexion est bonne, il commence à agrandir les fenêtres. Si la connexion est mauvaise, cela peut réduire la fenêtre. Qu'est-ce qu'il est important de comprendre? Il y a la première fenêtre de dix segments, dans laquelle vous devez adapter l'intégralité du site, si vous le souhaitez. Et puis il y aura une vitesse maximale d'apparition du contenu. Vitaliy Kharisov a également lu un rapport à ce sujet . Et oui, il est possible de regrouper un site avec tout ce dont vous avez besoin dans une seule fenêtre si vous désactivez, par exemple, JS.

Une nuance importante. Lorsque vous remplissez un segment entier, il s'agit d'un seul segment. Mais si vous n'envoyez qu'un octet supplémentaire, le serveur enverra tout de même un segment supplémentaire.



Vous pouvez faire une optimisation intéressante, réduire la sortie d'un kilo-octet entier, mais vous ne verrez rien sur vos mesures - peut-être à cause de cela. Essayez de faire l'optimisation normalement sur plusieurs segments.

Étrange: je suis typographe, et je raconte des choses de serveur si complexes. Rapprochez-vous encore du vrai CSS.

Expédier moins


Donc, nous envoyons moins à l'utilisateur, moins de segments, vient plus vite, l'utilisateur est content.



Minification. Elle était toute installée sur ses projets. Il y a un tas d'outils sympas, de plugins webpack, de paramètres gulp - en général, vous le découvrirez par vous-même. Vous pouvez le personnaliser à la main, mais il ne semble que lorsque vous êtes sûr de pouvoir compresser votre refroidisseur CSS que n'importe quel CSSO.

N'oubliez pas d'activer la compression. Si au moins gzip n'est pas activé en 2020, vous faites certainement quelque chose de mal, car il s'agit d'une ancienne technique de compression. En général, en 2020, il est temps d'utiliser brotli. C'est un bon moyen de réduire légèrement la sortie dans les navigateurs Chromium. Ou, si vous ne souhaitez pas prendre en charge brotli, vous pouvez au moins essayer zopfli.

Il s'agit d'un algorithme de compression assez lent pour gzip, qui donne simplement les meilleurs résultats de compression et décompresse aussi rapidement que gzip normal. Par conséquent, zopfli doit être configuré judicieusement et utilisé uniquement lorsque vous n'avez pas besoin de sortir des données à la volée. Vous pouvez configurer les archiveurs gzip pour qu'ils soient collectés lors de l'assemblage à l'aide de l'algorithme zopfli, et envoyés de manière statique déjà, en fait, ne vont pas à la volée. Cela peut vous aider. Mais mesurez également les résultats.



Tous ces algorithmes utilisent une sorte de dictionnaires: un dictionnaire est construit sur la base de fragments de code répétitifs. Mais parfois ils disent: il faut inline, si on inline, alors on se débarrasse de la demande. Lier tous les CSS en HTML sera très rapide. L'astuce est que gzip fonctionne un peu plus efficacement lorsque vous décomposez les styles et le HTML, car les dictionnaires sont différents, plus efficaces.

Dans mon cas, je viens de prendre la page de bootstrap, d'y relier le bootstrap et de comparer les deux versions. Gzip sur les ressources individuelles est de 150 octets de moins. Oui, le gain est très faible. Ici aussi, vous devez tout mesurer. Mais dans votre cas, cela peut, par exemple, réduire le nombre de segments d'un.

Comment optimiser le code? Je ne parle pas de minification. Retirez ce que vous n'utilisez pas dans le projet. Vous avez probablement du code qui ne s'exécutera jamais sur le client. Pourquoi?



Pour que vous puissiez automatiser cela, des onglets spéciaux sont intégrés dans le navigateur, par exemple, dans Chrome DevTools, c'est Coverage, qui vous dit: "Je n'ai pas utilisé ce CSS ou ce JS, vous pouvez le couper."

Mais vous pouvez avoir un survol, une concentration, une activité, quelque chose installé à l'aide de JS. Vous devez simuler toutes les actions possibles sur le site, alors seulement vous serez sûr que ce CSS peut être coupé. Chris Coyer a un bon article de synthèse sur les outils automatiques qui essaient de tout faire avec le survol et la concentration. Mais il est arrivé à la conclusion qu'il était impossible d'automatiser cela. Cela ne fonctionne pas encore.

Il y a un bon rapport d' Anton Kholkin de Booking.com, où ils ont également essayé de supprimer des tas de code hérité. Mais ils avaient une particularité: un code hérité qui provenait de projets externes. Il fallait le retirer. Découvrez les solutions intéressantes rencontrées.

Vous pouvez vous-même essayer de jouer avec le même Puppeteer, qui est comme Chrome. Vous pouvez faire des tests qui passent automatiquement par tout, essayez de faire du survol, de vous concentrer. Et utilisez cette même couverture.

Mon collègue Vitya Khomyakovvictor-homyakovfait mon propre script , comme trouver des doublons et des styles sur une page. Prenez, copiez et collez. Il vous écrira dans la console: "ce sélecteur, semble-t-il, vous n'en avez pas besoin." Jusqu'au point qui vient d'entrer dans DevTools. C’est génial.



Une fonctionnalité que j'aime beaucoup dans les outils des développeurs Firefox: une opportunité de voir les styles qui semblent être utilisés, mais en fait le navigateur ne les applique pas.

Par exemple, vous pouvez définir display: inline, et il semble que cet affichage: inline n'a pas de sens pour définir des tailles. Ou l'alignement vertical, cela ne fonctionne que pour les cellules en ligne ou de tableau. Jusqu'à présent, je n'ai vu que dans Firefox qu'il peut mettre en évidence: "vous n'avez pas besoin de cette ligne."

Ici aussi, vous devez être prudent: vous utiliserez peut-être ce style pour coller plus tard la classe. Mais à mon avis, une fonctionnalité intéressante.

Posez-vous la question dès maintenant: avez-vous besoin de l'ensemble du Bootstrap sur le projet? Placez n'importe quel framework CSS que vous utilisez au lieu de Bootstrap. Très probablement, vous utilisez Bootstrap pour les grilles et les éléments plus ou moins courants, et la moitié de Bootstrap dont vous n'avez pas besoin.

Essayez d'utiliser correctement l'assemblage. Presque tous les frameworks CSS modernes vous permettent d'utiliser le code source pour l'assemblage et de sélectionner uniquement ce dont vous avez besoin. Cela peut réduire considérablement la taille du bundle CSS.

Ne donnez pas inutilisé. Au lieu de chercher mon héritage, vous pouvez utiliser la compréhension de niveau de construction que cette page n'utilisera pas ce CSS.

Par exemple, une pile BEM complète vous permet de créer l'assemblage de sorte que vous, déjà en donnant la page, puissiez construire une arborescence de tous les composants des blocs BEM qui seront sur la page. BEM vous permet de déterminer que si ce bloc n'est pas sur la page, il n'est pas nécessaire de charger ce CSS. Expédiez uniquement le nécessaire.

Même les gars de Google disent : utilisez BEM, cela peut vraiment vous aider pour l'optimisation.

Je ne pense pas que je le dis à voix haute, mais dans ce cas, CSS-in-JS semble être une bonne approche. Lorsque vous écrivez des composants indépendants indépendants et configurez soigneusement l'assembly ou déterminez en cours d'exécution quels blocs sont utilisés et lesquels ne le sont pas, vous pouvez vous débarrasser du problème de trouver un code hérité en n'envoyant simplement pas ce code au client. Cela semble facile, mais la discipline est nécessaire. Pensez-y à l'avance au début du projet.



Quelle autre option existe-t-il? Un peu fou. Dans ce code, il semble que le style ne soit pas nécessaire, car nous utilisons un div - la valeur par défaut est déjà display: block. Et supprimons tous les paramètres par défaut? Si dans votre projet, vous savez avec certitude que le balisage HTML ne changera plus jamais - parcourez les valeurs par défaut que le navigateur fournit déjà et supprimez-les.

Moins de styles - super! Mais c'est encore une idée folle. CSS n'a pas besoin de connaître HTML, car c'est un style. Il est assez indépendant, vous devez le connecter à un autre projet, il devrait y fonctionner. Et oui, c'est difficile à maintenir. Changez le tag - tout se casse. Idée folle comme promis.

Utilisez des variables. CSS a de très anciennes variables comme currentColor.



Il y a souvent un motif: vous voulez, par exemple, créer un bouton dont le texte et la bordure sont de la même couleur. Et en survolant nous les changeons tous les deux. Pourquoi?



Il existe une variable currentColor qui prend une valeur de couleur, et vous la placez, par exemple, à la frontière, proxy cette propriété et modifiez une seule ligne par survol, par focus, par active, tout ce que vous voulez. Cela semble être pratique et le code est devenu une ligne de moins. Vous pouvez optimiser. Par ailleurs, dans cet exemple, vous ne pouvez pas du tout utiliser la tâche border-color, car par défaut, elle prend déjà une valeur dans la propriété color.

Il est parfois très triste de voir comment la base64 est utilisée. En CSS, il était activement recommandé avant: utiliser base64 pour injecter de petites icônes. S'il tient dans un segment sur TCP, c'est bon pour vous.



Mais Harry Roberts aussiRéalisation d'une étude approfondie sur la façon dont base64 affecte le chargement des pages. Oui, il y a moins de demandes, mais ces styles sont analysés parfois plus lentement.

D'accord, l'analyse est une opération très rapide, l'utilisateur ne le remarquera probablement pas. Mais nous avons une métrique importante - le premier rendu, afin que l'utilisateur voit quelque chose sur la page. Sur les téléphones portables, le premier rendu, selon une étude de Harry Roberts, se produit dix fois plus tard. Réfléchissez si vous avez besoin de base64? Oui, il y a moins de demandes, mais cela a-t-il eu un effet?

Et veuillez ne pas utiliser base64 pour SVG. Parce que SVG est idéal pour utiliser l'encodeur URL. Julia Bukhvalova a un outil sympa: Entrez, collez votre SVG et il distribuera CSS sous une forme prête à coller. Vous remarquerez peut-être qu'il n'y a pas de base64, mais certaines choses sont échappées qui en CSS peuvent ne pas être perçues correctement. C'est beaucoup plus efficace.

En moyenne, base64 donne un avantage de 30% à la taille de ce que vous compressez. Pourquoi?

Utilisez une technologie moderne. Nous devrons peut-être prendre en charge Internet Explorer - les arguments habituels lorsque nous parlons de grilles.



Mais pensez-y: si vous ne disposez pas de la prise en charge d'IE et que vous composez toujours sur des flottants ou des tableaux, vous pouvez utiliser des grilles pour créer une disposition en trois colonnes avec un espace de 20 pixels - c'est la distance entre les colonnes. Trois lignes. Eh bien, cinq, compte tenu de l'annonce elle-même.

Essayez ceci sur un flotteur. Et je veux dire que nous changeons trois lignes, y compris le nom des classes, si vous touchez HTML. Je n'ai pas trouvé le moyen de faire le même cool sur un flotteur. Jetez vos décisions. Mais utilisez la technologie moderne. Ils vous permettent d'indiquer de manière plus compacte le balisage.



Vous pouvez essayer Atomic CSS. Qu'Est-ce que c'est? Vous écrivez ces noms de classe un peu fous. Et après un certain temps, vous commencez à comprendre que c'est vous qui définissez la couleur de fond ou simplement la couleur. Ce sont les «fonctionnalités» pour CSS. Mais vous avez un ensemble CSS fixe que vous utilisez ensuite en HTML comme indication de style. Et CSS devient soudainement plus petit. Pour les grands projets, il deviendra vraiment plus petit, car il y a moins de styles uniques. Mais vous développez du HTML.



Vous pouvez regarder dans la direction de Tailwind CSS, qui gagne maintenant en popularité. Ce n'est pas Atomic CSS, il s'agit de classes utilitaires, similaires à Bootstrap, mais plus utilitaires. Vous pouvez utiliser un ensemble spécifique. Assez vous semble suffisant. Un ensemble de classes qui remplissent leurs fonctions. Vous pouvez également essayer, mais n'en faites pas trop.



Une autre idée folle - pourquoi avons-nous besoin de noms de classe entiers sur le client? Oui, c'est pratique pour le développement et le débogage, mais prenons tous les noms de classe et faisons-les en une seule lettre. Ce sera moins.

Voici un article sur la façon de procéder. Vous pouvez configurer le webpack ou un autre plugin lors de la construction. Mais cela ne nous a pas décollé. Nous avons essayé.

Il s'est avéré que gzip est si cool que tout était assez bien optimisé pour nous, et BEM et gzip sont incroyablement sympathiques. Parce que les constructions de texte sont répétées pour décrire les blocs et les éléments dans le code.

En général, cela ne nous a apporté pratiquement aucun profit. Mais si, par exemple, vous n'avez pas de BEM et un tas de classes différentes, vous pouvez essayer.

Important: mesure. Mesurer toutes ces pièces expérimentales. Peut-être que maintenant ça marche pour vous, et puis vous avez légèrement changé l'architecture du projet, ça a commencé à se monter différemment et tout a ralenti.

Télécharge le!


Jusqu'à présent, je n'ai parlé que de la façon de télécharger un fichier. Nous l'avons téléchargé. Qu'est-ce que l'utilisateur a vu pendant tout ce temps?



Il a vu un écran tellement incroyable. Pendant le téléchargement, l'écran était vide. Nous avons téléchargé et le navigateur commence six autres étapes. Soyez patient un peu, je vais en parler un peu plus vite que du téléchargement.



Commençons par l'analyse. L'analyse est lorsqu'un navigateur a téléchargé un flux d'octets et commence à le diviser en entités qu'il comprend.



Par exemple, il est tombé sur l'importation. Celui-ci doit à nouveau être téléchargé. Relisez la première partie du rapport? l'importation est une opération de blocage. Mais les navigateurs sont intelligents. Ils ont un scanner de précharge. J'ai dit que tout y est bloqué, ce n'est pas vrai. Les navigateurs savent que, par exemple, s'il y a trois balises de lien dans une rangée qui suivent le style, alors lorsque je télécharge la première, vous pouvez commencer à télécharger les deuxième et troisième. Il ne peut pas analyser, car toute la structure de l'analyse se brise. Mais téléchargez à l'avance - c'est possible.



L'importation est donc une mauvaise chose. Si les styles sont cohérents en HTML, le navigateur verra que nous irons plus loin pour un autre fichier.



Et si vous l'insérez directement dans l'importation, il doit d'abord télécharger votre style.css, puis voir l'importer dedans. Il commence à analyser ce CSS ... Ouais, on bloque tout d'une nouvelle façon et c'est parti pour le fichier! Vous pouvez donc faire une cascade fraîche avec désoptimisation sur le site.

Oubliez l'importation ou configurez de sorte qu'il n'y ait pas d'importation après la génération. Pour l'environnement de développement, ok, mais pas pour l'utilisateur.



Ensuite, nous passons par les étapes de la construction d'arbres, en utilisant Cascade.



Tout cela est également décrit depuis longtemps. Le modèle d'objet CSS est construit - un arbre spécial de la façon dont le navigateur mappe les balises, les classes aux styles. Il relie tout cela au DOM et établit ces connexions très rapidement. Lorsque vous changez quelque chose, il lui suffit de le changer à l'intérieur de l'arbre.



Plus le sélecteur est grand, plus il est difficile pour le navigateur de dessiner un arbre. Il doit analyser le sélecteur, le convertir en arborescences. Et si vous avez inséré! Important là-bas, alors il devrait en tenir compte.



Il semble qu'il est temps de reparler de BEM. Mais BEM n'est pas nécessaire si vous savez utiliser des classes utilitaires, si une classe est responsable d'une fonctionnalité et qu'elles n'interfèrent pas entre elles. Construire un arbre est alors très simple. Vous avez une structure assez plate et le navigateur doit alors le lier correctement au DOM.



Si vous faites cela, ils disent que ces sélecteurs ralentissent l'analyse CSS. Mais ce sont des légendes il y a longtemps, la différence est si petite pour le navigateur que dans le projet moyen, vous ne le remarquerez pas si vous optimisez les sélecteurs avec des astérisques. Mais aimeriez-vous développer et maintenir un tel code?



J'entendais des conseils: essayez de tout mettre dans un raccourci. l'arrière-plan est un raccourci pour de nombreuses autres propriétés. Nous mettons tout dans une seule propriété, et cela devient optimal.

Par octets, oui, il diminue. Mais si vous souhaitez optimiser la composition de CSS OM, le navigateur fera toujours toutes ces propriétés en arrière-plan. Les navigateurs pour chaque élément DOM créent une table de toutes les propriétés qu'il peut avoir. Lorsque vous regardez les valeurs calculées par DevTools, elles ne sont pas là car le navigateur les a calculées en fonction de vos besoins. Il le stocke en mémoire, car il est beaucoup plus facile de réécrire une propriété et tout fonctionne.

C'est également un conseil très étrange, mais si vous voulez rendre CSS OM plus rapide, vous pouvez immédiatement définir toutes les propriétés une par une. Ça pourrait marcher. Mais la taille du paquet augmentera considérablement. Vous devez mesurer. Je doute que ça rapporte, mais tout d'un coup!

Lorsque CSS OM est créé, JS est également verrouillé à ce stade. Si la création de OM CSS prend deux secondes, JS échoue. Bien que je ne puisse pas imaginer comment vous avez réussi à écrire autant en CSS que l’arbre est construit pendant deux secondes.



De plus, le navigateur fait la mise en page. C'est l'emplacement de tous les éléments DOM, l'utilisation des positions. Il comprend où l'élément doit être situé et avec quelles dimensions. Il semble qu'à ce stade, l'utilisateur devrait déjà voir une sorte d'image. Mais il voit tout dans la fenêtre, peut regarder à travers une fenêtre limitée. Si quelque chose ne va pas d'en bas, il ne le verra tout simplement pas.



L'idée s'appelle Critical CSS, et elle est également assez ancienne. Vous insérez des éléments importants pour le premier écran au tout début du téléchargement. Par exemple, en ligne dans votre code HTML, supprimez toutes les demandes supplémentaires. L'utilisateur voit d'abord cet écran, puis le télécharge comme vous le souhaitez. Très probablement, il commencera à défiler lorsque vous aurez le temps de le charger.



Cela se fait simplement. Il existe des outils qui automatisent tout cela, y compris des plugins pour webpack et React. Recherchez et configurez correctement.

- github.com/addyosmani/critical
- github.com/pocketjoso/penthouse
- github.com/anthonygore/html-critical-webpack-plugin
- github.com/GoogleChromeLabs/critters



Ayez une bonne approchede Filament Group - comment charger de manière asynchrone sans bloquer CSS. Tout est assez simple.

Lorsque vous mettez <link rel = preload>, dites au navigateur: «J'aurai besoin de ce style, mais maintenant nous ne bloquons rien. Vous le téléchargez maintenant, le cachez et quand je me tourne vers lui, commencez à construire CSS OM. » Et vous avez juste besoin de mettre onload et de traiter cela "ok, depuis que je l'ai téléchargé, faites-le rel = feuille de style, activez l'analyse."

Une approche assez simple, mais utilisez-la judicieusement aussi. Si vous avez trop de précharge, vous pouvez faire pire.



Vous pouvez également jouer avec des expressions multimédias. Collez-les et dites au navigateur: "ce style n'est plus nécessaire maintenant, mais lorsque cette expression multimédia fonctionnera, il sera nécessaire." Le navigateur téléchargera également de manière proactive, mais avec une priorité inférieure et sans blocage.



Une autre approche folle, mais pas si folle - quand vous avez une poussée http / 2. Vous pouvez intégrer CSS juste devant le bloc. Sans CSS, votre bloc ne sera pas très beau. Alors pourquoi ne pas intégrer le CSS dont vous avez besoin pour le bloc suivant avant ce bloc? C'est logique, et http / 2 push vous permettra de l'optimiser.

Une approche simple. Si vous le développez, utilisez le chargement paresseux. Pourquoi un utilisateur devrait-il télécharger quelque chose qu'il n'utilisera pas? Vous pouvez configurer les composants React de sorte que s'il n'a jamais atteint la zone de visibilité de la page, pourquoi devrait-il télécharger des styles pour lui-même?

Explorez l'API Intersection Observer et vous pourrez peut-être accélérer considérablement votre page.



La dernière étape consiste à dessiner et à appliquer des couches composites, à les coller, etc.



Le navigateur crée des couches composites dans un grand nombre de cas. À mon avis, seul un quart du code source de Chrome convient ici . Vous pouvez voir par vous-même quand il crée des couches composites dans le code du navigateur.

La mémoire vidéo est limitée, en particulier sur les téléphones portables. Si vous apportez tout à de nouveaux calques pour optimiser les animations en utilisant Will-Change: Transformer ou autre chose, alors vous pourriez faire pire.

Créez moins de couches - exactement autant que nécessaire pour l'optimisation actuelle.

Génial, nous avons tous analysé.

Et si je reviens?


Et si je reviens à la page? Ce n'est que la première fois que j'y vais.

En revenant à la page, il me semble que je peux tout télécharger instantanément. J'ai déjà téléchargé toutes les ressources, pourquoi ne pas les utiliser une deuxième fois?



Si le serveur ne donne pas l'en-tête Cache-Control, le navigateur tentera de mettre en cache votre fichier afin de le réutiliser. Vous pouvez configurer votre serveur par défaut, par exemple: "mettre ce fichier en cache pendant une année entière". Ne changera pas. Mais si c'est le cas, vous devez traiter le problème d'invalidation du cache global. Mais c'est le sujet d'un rapport séparé.

Utilisez des travailleurs de service! 2020, c'est le moment, Progressive Web Applications! Kirill Chugainov avait un bon rapportsur la façon dont les travailleurs des services peuvent être utilisés pour différentes occasions. Dans ce cas, vous interceptez la demande CSS, l'enregistrez et si le navigateur suit ce style pour la deuxième fois, donnez-la loin du cache.

Mais le navigateur ne vous promet rien. Vous pouvez toujours faire face au fait que le navigateur est à court de mémoire. Il va essayer de mettre en cache, mais il n'y a pas de mémoire. La mise en cache n'est pas à cent pour cent. Gérez toujours de telles situations.

Vous pouvez essayer d'utiliser le stockage local. Mais il est extrêmement lent. Le téléchargement d'un fichier est parfois plus rapide que l'accès à l'API de stockage local.

Vous pouvez essayer la base de données du navigateur intégrée. Mais mesurez-le. Peut-être qu'un voyage vers JS vous prendra plus de temps en raison d'un processeur faible.

Vous pouvez également informer le navigateur à l'avance que vous allez télécharger quelque chose.



<link rel> - découvrez comment fonctionne cet attribut. Il y a preconnect, prefetch, prerender - je veux en parler séparément. Il dit: «Je suis sur cette page maintenant, puis je passerai à la suivante. Téléchargez tout pour cette page dans l'onglet arrière-plan et dessinez. » Truc cool. Ne fonctionne nulle part.



Dans un sens, il est pris en charge dans IE et Edge. Dans Chrome, il ne fait pas vraiment ça, il ne rend pas. Cela fonctionne comme la prélecture: télécharge ces fichiers et caches. Malheureusement, un prérendeur à part entière ne fonctionne nulle part.

Mais vous pouvez développer cette idée. Par exemple, dans l'application Yandex - naturellement, sans utiliser CSS - une pré-rendu est faite. Lorsque vous cherchez quelque chose, il est probable que vous puissiez obtenir vos résultats instantanément. Nous pouvons prédire où vous irez, et à l'avance par nos propres méthodes aller chercher toutes les ressources nécessaires.

Et après? Il y avait beaucoup de liens. Je vous conseille également de regarder une incroyable collection d' optimisation de tout de Vanya Akuloviamakulov. Découvrez comment optimiser HTML, JS et l'assemblage.

Et n'oubliez pas de ranger. Maintenant, mes conseils fonctionnent vraiment, suggérant comment le faire rapidement, mais très probablement, après cinq ans, ils seront même nocifs. Il y aura une sorte de technologie qui leur sera incompatible. Gardez une trace de cela et essayez de garder votre code optimal, y compris après un certain temps. Merci pour l'attention.

All Articles