Generic First CSS : nouvelle réflexion sur le mobile d'abord
Publié: 2022-03-10Je pense qu'il est prudent de dire que la conception Web réactive d'Ethan Marcotte a été une révélation bienvenue pour les développeurs Web du monde entier. Cela a déclenché une toute nouvelle vague de réflexion sur le design et de merveilleuses nouvelles techniques frontales. Le règne des sites Web m dot souvent méprisés était également terminé. À la même époque et presque aussi influente était la méthodologie Mobile First de Luke Wroblewski - une amélioration solide qui s'appuyait sur les fondations impressionnantes de Marcotte.
Ces techniques sont à la base de la vie de la plupart des développeurs Web, et elles nous ont bien servi, mais hélas, les temps changent et les développeurs itèrent constamment. Au fur et à mesure que nous augmentons l'efficacité de nos méthodes et que les exigences du projet deviennent plus complexes, de nouvelles frustrations émergent.
Le voyage vers le générique d'abord
Je ne peux pas identifier exactement ce qui m'a fait changer ma façon d'écrire mon CSS parce que c'était vraiment une progression naturelle pour moi qui s'est produite presque inconsciemment. Avec le recul, je pense que c'était plus un sous-produit de l'environnement de développement dans lequel je travaillais. L'équipe avec laquelle je travaillais avait un bon flux de travail SCSS en cours avec un petit mixin astucieux pour ajouter facilement des points d'arrêt dans nos déclarations CSS. Vous utilisez probablement une technique similaire.
Ce merveilleux petit mixin SCSS a soudainement facilité l'écriture de requêtes multimédias super granulaires. Prenez un bloc de biographie hypothétique qui ressemble un peu à ceci :
.bio { display: block; width: 100%; background-color: #ece9e9; padding: 20px; margin: 20px 0; @include media('>=small') { max-width: 400px; background-color: white; margin: 20px auto; } @include media('>=medium') { max-width: 600px; padding: 30px; margin: 30px auto; } @include media('>=large') { max-width: 800px; padding: 40px; margin: 40px auto; } @include media('>=huge') { max-width: 1000px; padding: 50px; margin: 50px auto; } }
Fig. 1. Mobile first typique avec requêtes média en cascade
Cela fonctionne bien - j'ai écrit beaucoup de CSS comme celui-ci dans le passé. Cependant, un jour, je me suis rendu compte que l'écrasement des déclarations CSS à mesure que la largeur de l'appareil augmentait n'avait tout simplement aucun sens. Pourquoi déclarer une propriété CSS pour qu'elle ne soit écrasée que dans la déclaration suivante ?
C'est ce qui m'a amené à commencer à écrire des requêtes multimédias compartimentées par opposition à l'approche plus courante des requêtes multimédias qui cascadent vers le haut (ou vers le bas) comme dans l'exemple de la Fig.1.
Au lieu d'écrire des requêtes multimédias qui montent en cascade avec l'augmentation de la taille de l'écran, j'ai commencé à créer des requêtes multimédias ciblées qui encapsuleraient les styles aux largeurs d'écran souhaitées. Le mixin de requête multimédia prendrait vraiment tout son sens ici. Maintenant, mes requêtes multimédia SCSS commencent à ressembler à ceci :
.bio { display: block; width: 100%; padding: 20px; margin: 20px 0; @include media('>=small', ' < medium') { max-width: 400px; margin: 20px auto; } @include media('>=medium', ' < large') { max-width: 600px; padding: 30px; margin: 30px auto; } @include media('>=large', ' < huge') { max-width: 800px; padding: 40px; margin: 40px auto; } @include media('>=huge') { max-width: 1000px; padding: 50px; margin: 50px auto; } }
Fig.2. Un exemple de requêtes média compartimentées
Cette nouvelle approche m'a semblé plus intuitive, elle a réduit la nécessité de réinitialiser les styles à partir du point d'arrêt précédent et a rendu le CSS plus facile à lire. Plus important encore, cela rendait les requêtes des médias auto-documentées de manière plus significative.
Je n'étais toujours pas satisfait à 100% de ce qui précède, il semblait qu'il y avait encore un problème majeur à surmonter.
Le problème avec Mobile First
Le problème avec mobile first est que, par définition, vous devrez très probablement remplacer les styles mobile-first dans les requêtes multimédias suivantes. Cela ressemble un peu à un anti-modèle.
Donc, pour moi, la réponse était évidente : prenons l'idée de la compartimentation des requêtes multimédias jusqu'à sa conclusion logique : nous compartimenterons également les styles spécifiques aux mobiles dans leurs propres requêtes multimédias. Je sais, je sais, cela va à l'encontre de la convention commune que nous avons apprise au fil des ans. « Mobile First » est si omniprésent qu'il s'agit généralement de l'une des questions de « compétences » qu'un responsable du recrutement posera. Donc, toute alternative doit sûrement être fausse, n'est-ce pas? C'est généralement la partie où les gens secouent la tête tout en prononçant mobile first encore et encore.
D'accord, nous allons briser le dogme du mobile first et compartimenter tous nos styles dans les requêtes médiatiques pertinentes. Il ne nous reste plus que des styles génériques purs déclarés sur un sélecteur CSS, tous les autres styles spécifiques à l'appareil étant encapsulés dans des requêtes multimédias qui ne s'appliquent qu'aux dimensions d'écran pertinentes. Nous avons maintenant Generic First CSS :
.bio { display: block; width: 100%; @include media('>=0', ' < small') { padding: 20px; margin: 20px 0; } @include media('>=small', ' < medium') { max-width: 400px; margin: 20px auto; } @include media('>=medium', ' < large') { max-width: 600px; padding: 30px; margin: 30px auto; } @include media('>=large', ' < huge') { max-width: 800px; padding: 40px; margin: 40px auto; } @include media('>=huge') { max-width: 1000px; padding: 50px; margin: 50px auto; } }
Fig.3. Un exemple de Generic First CSS
Oui, il y a un peu plus de requêtes multimédias, cependant, je vois cela comme un avantage, n'importe quel développeur peut maintenant regarder ce CSS et voir exactement quels styles sont appliqués à chaque taille d'écran sans la surcharge cognitive d'avoir à séparer les médias- spécificité de la requête.
Cela peut être formidable pour les personnes qui ne connaissent pas la base de code ou même pour le futur vous !
Quand ne pas compartimenter
Il y a encore des moments où la compartimentation des requêtes multimédias est un fardeau, et dans certains cas, une bonne vieille requête multimédia >= convient. N'oubliez pas que tout ce que nous essayons de faire est d'éviter les écrasements de propriétés.
Le bonheur de l'outil de développement
L'une des principales conséquences involontaires de l'écriture compartimentée de Generic First CSS est l'expérience que vous obtiendrez de votre panneau de style des outils de développement. Sans la cascade de requêtes multimédias, vous aurez désormais un aperçu plus clair des styles appliqués — Vous n'aurez plus de panneau de style plein de déclarations barrées provenant de règles de requêtes multimédias écrasées — Le bruit est parti ! Ceci - pour moi - est l'un des plus grands avantages de la technique Generic First CSS. Cela apporte un peu plus de bon sens à l'expérience de débogage CSS, et cela vaut son pesant d'or. Remercie moi plus tard.
Incidences sur les performances
Donc, tous ces avantages de Generic First CSS commencent à sembler plutôt bons, mais je pense qu'il y a une dernière question clé qui, je pense, doit être abordée. C'est au sujet de l'optimisation des performances. Maintenant, je ne sais pas encore avec certitude, mais j'ai une idée que les requêtes multimédias entièrement compartimentées peuvent avoir un léger avantage en termes de performances.
Les navigateurs effectuent une tâche de rendu appelée calcul de style calculé . C'est la façon dont les navigateurs calculent quels styles doivent être appliqués à un élément à un moment donné. Cette tâche est toujours effectuée lors du chargement initial de la page, mais elle peut également être effectuée si le contenu de la page change ou si d'autres actions du navigateur ont lieu. Tout coup de pouce que vous pouvez donner à la vitesse du processus sera excellent pour le chargement initial de la page, et cela pourrait avoir un effet composé sur le cycle de vie des pages de votre site Web.
Revenons donc au premier CSS générique : y a-t-il des problèmes de performances liés au fait que le navigateur doit travailler sur la spécificité CSS d'une multitude de requêtes multimédia en cascade ?
Pour répondre à cela, j'ai conçu un cas de test qui peut être utilisé pour mesurer les avantages ou les inconvénients de la vitesse.
Le cas test
Le cas de test est composé d'une page HTML de base qui sort un bloc "bio" 5000 fois, le balisage est le même pour chaque bloc, mais les classes sont légèrement différentes (différenciateur numérique), le CSS pour ce bloc est également sorti 5000 fois , les noms de classe étant la seule chose à différer. Le CSS généré est acheminé via un outil appelé CSS MQPacker, ce qui permet de réduire considérablement la taille du fichier CSS qui utilise de nombreuses requêtes multimédias en ligne en combinant toutes les instances distinctes d'une requête multimédia spécifique en une seule. C'est un excellent outil qui bénéficiera probablement. la plupart des bases de code CSS modernes - je l'ai utilisé comme outil cli autonome via une tâche npm dans le paquet de projets de test.json, vous pouvez également l'utiliser comme plugin postcss, ce qui est agréable et pratique !
Le premier cas de test est un exemple de requêtes multimédia en cascade mobile d'abord, le deuxième cas de test est une première variante générique compartimentée du CSS. Le CSS pour ces cas est un peu verbeux et pourrait probablement être écrit en termes beaucoup plus concis, mais il sert vraiment d'exemple approximatif pour tester l'argument.
Le test a été exécuté 20 fois pour chaque variation CSS dans le bureau Google Chrome v70, pas un ensemble massif de données, mais suffisamment pour me donner une idée approximative d'un gain/perte de performances.
Les mesures de test que j'ai choisi d'utiliser sont :
- Temps de chargement global de la page
Une métrique de base pour vérifier le temps de chargement de la page à l'aide des marqueurs de l'API Performance au début de <head> et à la toute fin de <body> - Le style de recalcul
Heure depuis le volet des performances des outils de développement. - Le rendu global de la page
Heure depuis le volet des performances des outils de développement.
Tableau des résultats (tous les temps en millisecondes)
Mobile d'abord | Générique d'abord | ||||||
---|---|---|---|---|---|---|---|
Temps de chargement | Calculer les styles | Temps de rendu total | Temps de chargement | Calculer les styles | Temps de rendu total | ||
1135 | 565.7 | 1953 | 1196 | 536.9 | 2012 | ||
1176 | 563,5 | 1936 | 1116 | 506.9 | 1929 | ||
1118 | 563.1 | 1863 | 1148 | 514.4 | 1853 | ||
1174 | 568.3 | 1929 | 1124 | 507.1 | 1868 | ||
1204 | 577.2 | 1924 | 1115 | 518.4 | 1854 | ||
1155 | 554.7 | 1991 | 1177 | 540.8 | 1905 | ||
1112 | 554,5 | 1912 | 1111 | 504.3 | 1886 | ||
1110 | 557.9 | 1854 | 1104 | 505.3 | 1954 | ||
1106 | 544,5 | 1895 | 1148 | 525.4 | 1881 | ||
1162 | 559.8 | 1920 | 1095 | 508.9 | 1941 | ||
1146 | 545,9 | 1897 | 1115 | 504.4 | 1968 | ||
1168 | 566.3 | 1882 | 1112 | 519.8 | 1861 | ||
1105 | 542.7 | 1978 | 1121 | 515.7 | 1905 | ||
1123 | 566.6 | 1970 | 1090 | 510.7 | 1820 | ||
1106 | 514.5 | 1956 | 1127 | 515.2 | 1986 | ||
1135 | 575,7 | 1869 | 1130 | 504.2 | 1882 | ||
1164 | 545.6 | 2450 | 1169 | 525.6 | 1934 | ||
1144 | 565 | 1894 | 1092 | 516 | 1822 | ||
1115 | 554,5 | 1955 | 1091 | 508.9 | 1986 | ||
1133 | 554.8 | 2572 | 1001 | 504.5 | 1812 | ||
MOY | 1139.55 | 557.04 | 1980 | 1119.1 | 514,67 | 1903.15 |
Fig.6. 20 exécutions de tests mesurant les principales métriques de chargement/rendu du CSS mobile first par rapport au CSS générique first.
D'après mon ensemble de données, certes petit, il semble que ma suspicion initiale soit correcte. En moyenne, je vois que la tâche de recalcul du style prend 42 ms de moins, ce qui représente une augmentation de la vitesse de 7,6 %, et donc le temps de rendu global diminue également. La différence n'est pas époustouflante, mais c'est une amélioration. Je ne pense pas que l'ensemble de données soit assez grand pour être concluant à 100% et le cas de test est un peu irréaliste, mais je suis très heureux de ne pas voir de dégradation des performances.
Je serais très intéressé de voir la première méthodologie générique appliquée à une base de code existante dans le monde réel qui a été écrite de la manière mobile d'abord - les métriques avant après seraient beaucoup plus réalistes pour la pratique quotidienne.
Et si quelqu'un a des suggestions sur la façon d'automatiser ce test sur un ensemble plus large d'itérations, faites-le moi savoir dans les commentaires ! J'imagine qu'il doit y avoir un outil qui peut le faire.
Conclusion
Pour récapituler les bénéfices de cette nouvelle méthodologie de développement...
- CSS qui fait exactement comme prévu, sans hésitation ;
- Requêtes média auto-documentées ;
- Une meilleure expérience des outils de développement ;
- Des pages qui s'affichent plus rapidement.
J'aimerais penser que je ne suis pas la seule personne à adopter l'écriture de CSS dans ce style. Si vous avez déjà adopté le premier état d'esprit générique, hourra ! Mais sinon, je pense que vous aimerez vraiment les avantages qu'il apporte. J'ai personnellement beaucoup profité de l'expérience épurée des outils de développement, ce qui en soi sera un énorme avantage pour de nombreux développeurs. la nature auto-documentée de cette façon d'écrire vos media-queries aura également des avantages pour vous-même et pour l'ensemble de l'équipe (si vous en avez une). Et enfin, ces avantages ne vous coûteront rien en termes de performances, et en fait, il a été démontré qu'ils ont des gains de vitesse marginaux !
Dernier mot
Comme toutes les méthodologies de développement, ce n'est peut-être pas pour tout le monde, mais je suis tombé dans Generic First CSS assez naturellement, je le vois maintenant comme une méthode de travail précieuse qui me donne tous les avantages du mobile first avec quelques nouveaux ajouts positifs qui font le travail difficile du développement frontal qui n'est guère plus facile.
Ressources
Référentiel de cas de test
Si vous souhaitez lancer le cas de test et l'essayer vous-même, vous pouvez le trouver sur GitHub, j'aimerais voir des rapports d'autres personnes.
Outils
- CSS MQPackerComment
- Inclure les médias