Generic First CSS: nowe myślenie w pierwszej kolejności na urządzenia mobilne

Opublikowany: 2022-03-10
Szybkie podsumowanie ↬ Wraz z pojawieniem się responsywnego projektowania stron internetowych i podejścia mobile-first minęło siedem wspaniałych lat, odkąd jakiekolwiek nowe koncepcje zmusiły nas do dostosowania sposobu, w jaki piszemy CSS na poziomie podstawowym. Cóż, nie mam ci do zaoferowania nic przełomowego, ale mam małą niespodziankę. Oto: ogólny pierwszy CSS.

Myślę, że można śmiało powiedzieć, że Responsive Web Design Ethana Marcotte'a był mile widzianą rewelacją dla twórców stron internetowych na całym świecie. Wywołało to zupełnie nową falę myślenia projektowego i wspaniałe nowe techniki front-endowe. Skończyło się również panowanie często pogardzanych stron internetowych m dot. W tej samej epoce i prawie tak samo wpływowa była metodologia Luke'a Wróblewskiego Mobile First — solidne ulepszenie, które zbudowano na imponujących fundamentach Marcotte'a.

Techniki te są podstawą życia większości programistów internetowych i dobrze nam służyły, ale niestety czasy się zmieniają, a programiści nieustannie iterują. W miarę jak zwiększamy wydajność naszych metod, a wymagania projektowe stają się coraz bardziej złożone, pojawiają się nowe frustracje.

Najpierw podróż do generyków

Nie potrafię dokładnie określić, co spowodowało, że zmieniłem sposób pisania CSS, ponieważ był to dla mnie naturalny postęp, który wydarzył się niemal podświadomie. Patrząc wstecz, myślę, że był to bardziej produkt uboczny środowiska programistycznego, w którym pracowałem. Zespół, z którym pracowałem, miał fajny przepływ pracy SCSS z fajnym małym domieszką do łatwego dodawania punktów przerwania w naszych deklaracjach CSS. Prawdopodobnie używasz podobnej techniki.

Ten wspaniały mały mixin SCSS nagle ułatwił pisanie bardzo szczegółowych zapytań o media. Weź hipotetyczny blok biografii, który wygląda mniej więcej tak:

 .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; } }

Rys.1. Typowe pierwszeństwo dla urządzeń mobilnych z kaskadowymi zapytaniami o media

Działa to ładnie — w przeszłości napisałem wiele CSS w ten sposób. Jednak pewnego dnia dotarło do mnie, że nadpisywanie deklaracji CSS wraz ze wzrostem szerokości urządzenia po prostu nie ma sensu. Po co deklarować właściwość CSS, aby została nadpisana tylko w poniższej deklaracji?

Więcej po skoku! Kontynuuj czytanie poniżej ↓

To właśnie skłoniło mnie do pisania podzielonych na sekcje zapytań o media , w przeciwieństwie do bardziej powszechnego podejścia do zapytań o media, które kaskadowo wznoszą się (lub spadają), jak w przykładzie na ryc. 1.

Zamiast pisać zapytania o media, które rosną kaskadowo wraz ze wzrostem rozmiaru ekranu, zacząłem tworzyć ukierunkowane zapytania o media, które zawierałyby style przy pożądanej szerokości ekranu. Mieszanka zapytań o media naprawdę przydałaby się tutaj. Teraz moje zapytania o media SCSS zaczynają wyglądać tak:

 .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; } }

Rys.2. Przykład podzielonych na sekcje zapytań o media

To nowe podejście wydawało mi się bardziej intuicyjne, ograniczyło konieczność resetowania stylów z poprzedniego punktu przerwania i sprawiło, że CSS był łatwiejszy do odczytania. Co ważniejsze, sprawiło to, że media zapytują o autodokumentację w bardziej znaczący sposób.

Mimo to nadal nie byłem w 100% zadowolony z powyższego. Wydawało się, że nadal istnieje poważny problem do przezwyciężenia.

Problem z telefonem komórkowym?

Problem z mobile first polega na tym, że z definicji najprawdopodobniej będziesz musiał zastąpić style mobile-first w kolejnych zapytaniach o media. To trochę jak anty-wzorzec.

Tak więc — dla mnie — odpowiedź była oczywista: doprowadźmy do logicznego zakończenia idei podziału zapytań o media — podzielimy również style specyficzne dla urządzeń mobilnych na ich własne zapytania o media. Wiem, wiem, to jest sprzeczne z powszechną konwencją, której nauczyliśmy się przez lata. „Najpierw mobilność” jest tak wszechobecna, że ​​zwykle jest to jedno z pytań „umiejętności”, które zadaje menedżer ds. rekrutacji. Więc z pewnością każda alternatywa musi być zła, prawda? Zwykle jest to część, w której ludzie kręcą na mnie głowami, podczas gdy najpierw w kółko wypowiadają telefon komórkowy .

OK, więc zamierzamy przełamać dogmat mobile first i podzielić wszystkie nasze style na odpowiednie zapytania medialne. Pozostały nam teraz czyste style ogólne zadeklarowane w selektorze CSS, a wszystkie inne style specyficzne dla urządzenia zawarte w zapytaniach o media, które mają zastosowanie tylko do odpowiednich wymiarów ekranu. Mamy teraz 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; } }

Rys.3. Przykład Generic First CSS

Tak, jest nieco więcej zapytań o media, jednak uważam to za zaletę, każdy programista może teraz spojrzeć na ten CSS i zobaczyć dokładnie, jakie style są stosowane przy każdym rozmiarze ekranu bez narzutu poznawczego związanego z koniecznością oddzielenia mediów- specyfika zapytania.

Może to być świetne dla osób niezaznajomionych z bazą kodu, a nawet dla Ciebie w przyszłości!

Kiedy nie kompartmentalizować?

Ciągle zdarza się, że podział zapytań o media jest uciążliwy, a w niektórych przypadkach stare, dobre zapytanie >= jest w porządku. Pamiętaj, że jedyne, co staramy się zrobić, to unikać nadpisywania własności.

Narzędzie deweloperskie Bliss

Jedną z głównych niezamierzonych konsekwencji pisania podzielonego na sekcje Generic First CSS jest doświadczenie, jakie uzyskasz z panelu stylów narzędzi programistycznych. Bez kaskady zapytań o media będziesz miał teraz jaśniejszy przegląd zastosowanych stylów — nie będziesz mieć panelu stylów pełnego przekreślonych deklaracji z nadpisanych reguł zapytań o media — szum zniknął! To — dla mnie — jedna z największych zalet techniki Generic First CSS. Wprowadza trochę więcej zdrowego rozsądku do debugowania CSS, a to jest na wagę złota. Podziękujesz mi później.

Przed i po zrzucie ekranu pokazującym, jak ogólne pierwsze podejście CSS wpływa na panel stylów narzędzi programistycznych Chrome.
Rys.4. W jaki sposób ogólny, podzielony na sekcje CSS może pomóc w przyniesieniu radości i zdrowego rozsądku na konsoli deweloperskiej. (duży podgląd)

Implikacje dotyczące wydajności

Tak więc wszystkie korzyści wynikające z Generic First CSS zaczynają brzmieć całkiem nieźle, ale myślę, że jest jeszcze jedno kluczowe pytanie, które moim zdaniem wymaga odpowiedzi. Chodzi o optymalizację wydajności. Teraz nie wiem jeszcze na pewno, ale mam przeczucie, że w pełni podzielone zapytania o media mogą mieć niewielką poprawę wydajności.

Przeglądarki wykonują zadanie renderowania zwane obliczaniem stylu obliczonego . Jest to sposób przeglądarki obliczania, które style należy zastosować do elementu w danym momencie. To zadanie jest zawsze wykonywane przy początkowym wczytaniu strony, ale można je również wykonać w przypadku zmiany zawartości strony lub innych działań przeglądarki. Każde przyspieszenie tego procesu będzie świetne przy początkowym wczytywaniu strony i może mieć złożony wpływ na cykl życia stron internetowych.

Wracając więc do ogólnego pierwszego CSS: Czy są jakieś problemy z wydajnością związane z tym, że przeglądarka musi rozpracować specyfikę CSS wielu kaskadowych zapytań o media?

Aby odpowiedzieć na to pytanie, opracowałem przypadek testowy, który można wykorzystać do pomiaru korzyści lub wad prędkości.

Przypadek testowy

Przypadek testowy składa się z podstawowej strony HTML, która generuje blok „bio” 5000 razy, znaczniki są takie same dla każdego bloku, ale klasy są nieco inne (różnicownik liczbowy), CSS dla tego bloku jest również generowany 5000 razy , przy czym jedyną rzeczą, która się różni, są nazwy klas. Otrzymany CSS jest przesyłany przez narzędzie o nazwie CSS MQPacker, które pomaga radykalnie zmniejszyć rozmiar pliku CSS, który wykorzystuje wiele wbudowanych zapytań o media, łącząc wszystkie oddzielne wystąpienia konkretnego zapytania o media w jedno — to świetne narzędzie, które prawdopodobnie przyniesie korzyści większość nowoczesnych baz kodu CSS — używałem go jako samodzielnego narzędzia cli za pośrednictwem zadania npm w testowych projektach package.json, możesz też używać go jako wtyczki postcss, co jest miłe i wygodne!

Pierwszy przypadek testowy to przykład kaskadowych zapytań o media dla urządzeń mobilnych, drugi przypadek testowy to generyczny pierwszy podzielony na przedziały wariant CSS. CSS dla tych przypadków jest trochę gadatliwy i prawdopodobnie mógłby być napisany w znacznie bardziej zwięzły sposób, ale tak naprawdę służy tylko jako przybliżony przykład do przetestowania argumentu.

Test został przeprowadzony 20 razy dla każdej odmiany CSS w przeglądarce Google Chrome v70 na komputery, nie jest to ogromny zestaw danych, ale wystarczająco dużo, aby dać mi przybliżone pojęcie o zwiększeniu/utracie wydajności.

Wybrane przeze mnie metryki testowe to:

  • Całkowity czas ładowania strony
    Podstawowa metryka do sprawdzania czasu ładowania strony za pomocą znaczników Performance API na początku <head> i na samym końcu <body>
  • Przelicz styl
    Czas z poziomu panelu wydajności narzędzi deweloperskich.
  • Ogólne renderowanie strony
    Czas z poziomu panelu wydajności narzędzi deweloperskich.
Tabela wyników z profilu wydajności Google Chrome
Rys.5. Kluczową miarą mierzoną jest „Przelicz styl”. (duży podgląd)

Tabela wyników (wszystkie czasy w milisekundach)

Najpierw mobilny Najpierw ogólne
Czas ładowania Oblicz style Całkowity czas renderowania Czas ładowania Oblicz style Całkowity czas renderowania
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
AVG 1139,55 557,04 1980 1119.1 514,67 1903.15

Rys.6. 20 testów mierzących kluczowe wskaźniki wczytywania/renderowania dla modelu Mobile First w porównaniu z ogólnym First CSS.

Z mojego, przyznaję, małego zestawu danych, wydaje się, że moje początkowe podejrzenie może być poprawne. Widzę, że zadanie przeliczania stylu zajmuje średnio 42 ms mniej czasu, co oznacza wzrost szybkości o 7,6%, a zatem ogólny czas renderowania również się skraca. Różnica nie jest oszałamiająca, ale jest poprawą. Nie sądzę, aby zestaw danych był wystarczająco duży, aby był w 100% rozstrzygający, a przypadek testowy jest trochę nierealny, ale bardzo się cieszę, że nie widzę spadku wydajności.

Byłbym bardzo zainteresowany, aby zobaczyć ogólną pierwszą metodologię stosowaną do rzeczywistej istniejącej bazy kodu, która została napisana w sposób mobilny — metryki „przed” byłyby znacznie bardziej realistyczne w codziennej praktyce.

A jeśli ktoś ma sugestie, jak zautomatyzować ten test w szerszym zestawie iteracji, proszę o informację w komentarzach! Wyobrażam sobie, że musi istnieć narzędzie, które może to zrobić.

Wniosek

Podsumowując korzyści płynące z tej nowej metodologii rozwoju...

  • CSS, który działa dokładnie tak, jak zamierzano, bez drugiego zgadywania;
  • Samodokumentujące zapytania medialne;
  • Lepsze wrażenia z narzędzi deweloperskich;
  • Strony, które renderują się szybciej.

Chciałbym myśleć, że nie jestem jedyną osobą, która opowiada się za pisaniem CSS w tym stylu. Jeśli już przyjąłeś ogólny, pierwszy sposób myślenia, hurra! Ale jeśli nie, myślę, że naprawdę polubisz korzyści, jakie przynosi. Osobiście bardzo skorzystałem z uporządkowanego doświadczenia z narzędziami deweloperskimi, co samo w sobie będzie ogromnym pozytywem dla wielu deweloperów. samodokumentowanie tego sposobu pisania zapytań medialnych przyniesie korzyści także Tobie i szerszemu zespołowi (jeśli go posiadasz). I wreszcie, te korzyści nie będą Cię kosztować nic pod względem wydajności, a w rzeczywistości wykazano, że mają marginalny wzrost prędkości!

Ostatnie słowo

Podobnie jak wszystkie metodologie programowania, może nie być dla wszystkich, ale wpadłem w Generic First CSS w sposób naturalny. Teraz postrzegam to jako wartościowy sposób pracy, który daje mi wszystkie zalety mobile first z kilkoma pozytywnymi nowymi dodatkami, które sprawiają, że ciężka praca z rozwojem front-endu, która nie będzie prostsza.

Zasoby

Repozytorium przypadków testowych

Jeśli chcesz odpalić test i sam spróbować, możesz go znaleźć na GitHub, chciałbym zobaczyć raporty od innych.

Narzędzia

  • CSS MQPacker
  • Uwzględnij multimedia