Pomaganie przeglądarkom w optymalizacji za pomocą właściwości zawierającej CSS

Opublikowany: 2022-03-10
Krótkie podsumowanie ↬ Własność CSS contain sposób wyjaśnienia układu w przeglądarce, dzięki czemu można dokonać optymalizacji wydajności. Ma jednak pewne skutki uboczne w zakresie układu.

W tym artykule przedstawię specyfikację CSS, która właśnie stała się rekomendacją W3C. Specyfikacja contain CSS definiuje pojedynczą właściwość, include i może pomóc w wyjaśnieniu przeglądarce, które części układu są niezależne i nie będą wymagały ponownego obliczania, jeśli jakaś inna część układu ulegnie zmianie.

Chociaż ta właściwość istnieje w celu optymalizacji wydajności, może również wpływać na układ strony. Dlatego w tym artykule wyjaśnię różne rodzaje zawierania, z których możesz skorzystać, a także rzeczy, na które musisz uważać, stosując contain do elementów w swojej witrynie.

Problem przeliczania układu

Jeśli tworzysz proste strony internetowe, które nie dodają dynamicznie ani nie zmieniają elementów po załadowaniu za pomocą JavaScript, nie musisz się martwić problemem, który rozwiązuje CSS. Przeglądarka musi tylko raz obliczyć układ, gdy strona jest ładowana.

Ograniczanie staje się przydatne, gdy chcesz dodać elementy do swojej strony bez konieczności ponownego ładowania jej przez użytkownika. W moim przykładzie stworzyłem dużą listę wydarzeń. Kliknięcie przycisku powoduje modyfikację pierwszego zdarzenia, dodanie elementu pływającego i zmianę tekstu:

Lista przedmiotów z przyciskiem do zmiany niektórych treści w pierwszym elemencie
(Zobacz początkowy przykład na CodePen)

Gdy zawartość naszego pudełka się zmieni, przeglądarka musi wziąć pod uwagę, że którykolwiek z elementów mógł się zmienić. Przeglądarki generalnie radzą sobie z tym całkiem nieźle, ponieważ zdarza się to często. To powiedziawszy, jako programista będziesz wiedział, czy każdy z komponentów jest niezależny i czy zmiana jednego nie wpływa na inne, więc byłoby miło, gdybyś mógł poinformować przeglądarkę za pomocą swojego CSS. To właśnie daje zawieranie i właściwość CSS contain .

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

Jak ograniczanie pomaga?

Dokument HTML to struktura drzewa, którą można zobaczyć podczas sprawdzania dowolnego elementu za pomocą DevTools. W powyższym przykładzie identyfikuję jeden element, który chcę zmienić za pomocą JavaScript, a następnie wprowadzam pewne zmiany do elementów wewnętrznych. (Oznacza to, że zmieniam tylko rzeczy wewnątrz poddrzewa dla tego elementu listy).

DevTools z pozycją listy polecanego elementu rozwiniętą, aby zobaczyć elementy w środku
Sprawdzanie elementu listy w DevTools

Zastosowanie właściwości include do elementu informuje przeglądarkę, że zmiany są contain do poddrzewa tego elementu, dzięki czemu przeglądarka może przeprowadzić wszelkie możliwe optymalizacje — mając pewność, że nic poza tym elementem się nie zmieni. Dokładnie to, co konkretna przeglądarka może zrobić, zależy od silnika. Właściwość CSS po prostu daje — jako deweloperowi i ekspertowi w tym układzie — szansę na poinformowanie go.

W wielu przypadkach możesz bezpiecznie zacząć używać właściwości include, jednak różne wartości contain pewne potencjalne skutki uboczne, które warto zrozumieć przed dodaniem właściwości do elementów w witrynie.

Korzystanie z powstrzymywania

Właściwość include może ustawić trzy różne typy contain :

  • layout
  • paint
  • size

Uwaga : W specyfikacji poziomu 2 istnieje wartość style . Został usunięty z poziomu 1, więc nie pojawia się w zaleceniu i nie jest zaimplementowany w przeglądarce Firefox.

Układ

Zawężanie układu przynosi największe korzyści. Aby włączyć zawieranie układu, użyj następującego fragmentu kodu:

 .item { contain: layout; }

Po włączeniu zawierania układu przeglądarka wie, że nic poza elementem nie może wpływać na układ wewnętrzny i nic z wnętrza elementu nie może zmienić niczego w układzie elementów poza nim. Oznacza to, że może dokonać wszelkich możliwych optymalizacji dla tego scenariusza.

Kilka dodatkowych rzeczy dzieje się, gdy włączone jest zawieranie układu. To wszystko zapewnia, że ​​to pudełko i zawartość są niezależne od reszty drzewa.

Ramka ustanawia niezależny kontekst formatowania . Gwarantuje to, że zawartość pudełka pozostanie w pudełku — w szczególności elementy pływające będą zawarte, a marginesy nie będą się zwijać przez pudełko. Jest to to samo zachowanie, które włączamy, gdy używamy display: flow-root , jak wyjaśniono w moim artykule „Zrozumienie układu CSS i kontekstu formatowania bloków”. Jeśli element pływający mógłby wysunąć się z pudełka, powodując, że następujący tekst opływałby element pływający, to byłaby sytuacja, w której element zmieniałby układ elementów poza nim, czyniąc go słabym kandydatem do przechowywania.

Pole zawierające działa jak blok zawierający dla dowolnych potomków pozycji bezwzględnej lub stałej. Oznacza to, że będzie działał tak, jakbyś użył position: relative na zastosowanym polu contain: layout .

Pudełko tworzy również kontekst stosu . Dlatego z-index będzie działał na tym elemencie, jego dzieci zostaną ułożone w stos w oparciu o nowy kontekst.

Jeśli spojrzymy na przykład, tym razem z contain: layout , widać, że po wprowadzeniu elementu pływającego nie wystaje on już z dolnej części pudełka. To jest nasz nowy kontekst formatowania bloku w akcji, zawierający element zmiennoprzecinkowy.

Lista elementów, pływający element jest zawarty w granicach pola nadrzędnego
Używanie include: układ zawiera element zmiennoprzecinkowy (zobacz przykład zawierania układu w CodePen)

Farba

Aby włączyć pojemnik na farbę, użyj:

 .item { contain: paint; }

Po włączeniu zawierania farby pojawiają się te same efekty uboczne, co w przypadku zawierania układu: pole zawierające staje się niezależnym kontekstem formatowania, blokiem zawierającym elementy pozycjonowane i ustanawia kontekst stosu.

To, co robi zawieranie farby, to wskazywanie przeglądarce, że elementy wewnątrz bloku zawierającego nie będą widoczne poza granicami tego pola. Zawartość zasadniczo zostanie przypięta do pudełka.

Możemy to zobaczyć na prostym przykładzie. Nawet jeśli nadamy naszej karcie wysokość, element pływający nadal wystaje z dna pudełka, ponieważ pływak jest wyjęty z przepływu.

Pływające pudełko wystające z dna pudełka zawierającego
Element zmiennoprzecinkowy nie jest zawarty w elemencie listy

Przy włączonym przechowywaniu farby pływający przedmiot jest teraz przycinany do rozmiaru pudełka. Nic nie może być pomalowane poza granice elementu za pomocą contain: paint .

Pudełko z pływającym pudełkiem w środku, które zostało odcięte tam, gdzie wydostaje się z pudła
Zawartość pudełka jest przycinana do wysokości pudełka (Zobacz przykład malowania na CodePen)

Rozmiar

Ograniczenie rozmiaru to wartość, która najprawdopodobniej spowoduje problem, jeśli nie jesteś w pełni świadomy, jak to działa. Aby zastosować ograniczenie rozmiaru, użyj:

 .item { contain: size; }

Jeśli używasz ograniczania rozmiaru, mówisz przeglądarce, że znasz rozmiar pudełka i nie zmieni się on. Oznacza to, że jeśli masz pudełko, które ma automatyczne rozmiary w wymiarze bloku, będzie traktowane tak, jakby zawartość nie miała rozmiaru, dlatego pudełko zwinie się tak, jakby nie miało zawartości.

W poniższym przykładzie nie podałem li wysokości; contain: size . Widać, że wszystkie elementy zostały zwinięte, tak jakby w ogóle nie zawierały treści, co sprawia, że ​​lista wygląda bardzo osobliwie!

Lista przedmiotów z przyciskiem do zmiany niektórych treści w pierwszym elemencie
(Zobacz przykład rozmiaru na CodePen)

Jeśli podasz skrzynkom wysokość, wówczas wysokość będzie zachowana, gdy zostanie użyta opcja contain: size . Samo zawieranie rozmiaru nie utworzy nowego kontekstu formatowania, a zatem nie będzie zawierało elementów pływających i marginesów, jak to zrobią zawieranie układu i malowania. Jest mniej prawdopodobne, że użyjesz go sam; zamiast tego najprawdopodobniej zastosowałbyś go wraz z innymi wartościami contain , aby móc uzyskać jak najbardziej możliwe ograniczenie.

Skrócone wartości

W większości przypadków możesz użyć jednej z dwóch skróconych wartości, aby jak najlepiej wykorzystać powstrzymywanie. Aby włączyć blokowanie układu i malowania, użyj funkcji contain: content; , i aby włączyć wszystkie możliwe przechowywanie (pamiętając, że elementy, które nie mają rozmiaru, zostaną następnie zwinięte), użyj contain: strict .

Specyfikacja mówi:

contain: content jest dość „bezpieczna” do szerokiego zastosowania; jego skutki są w praktyce dość niewielkie, a większość treści nie będzie naruszać jego ograniczeń. Jednak ponieważ nie stosuje on zawierania rozmiaru, element może nadal odpowiadać na rozmiar swojej zawartości, co może spowodować, że unieważnienie układu będzie przenikać dalej w górę drzewa, niż jest to pożądane. Używaj contain: strict , jeśli to możliwe, aby uzyskać jak najwięcej powstrzymywania.

Dlatego, jeśli nie znasz z góry rozmiaru elementów, a rozumiesz, że będą zawarte pływaki i marginesy, użyj contain: content . Jeśli znasz rozmiar przedmiotów, oprócz tego, że jesteś zadowolony z innych skutków ubocznych powstrzymywania, użyj contain: strict . Reszta sprowadza się do przeglądarki, zrobiłeś swoje, wyjaśniając, jak działa twój układ.

Czy mogę teraz użyć ograniczania?

Specyfikacja CSS Containment jest teraz Rekomendacją W3C, którą czasami nazywamy standardem sieciowym . Aby specyfikacja dotarła do tego etapu, musiały istnieć dwie implementacje funkcji, które możemy zobaczyć zarówno w Firefoksie, jak i Chrome:

Zrzut ekranu z informacjami dotyczącymi obsługi przeglądarki na temat ograniczania w Czy mogę użyć
Obsługa przeglądarki do przechowywania (źródło: czy mogę użyć)

Ponieważ ta właściwość jest niewidoczna dla użytkownika, jej dodanie do dowolnej witryny jest całkowicie bezpieczne, nawet jeśli masz wielu odwiedzających w przeglądarkach, które jej nie obsługują. Jeśli przeglądarka nie obsługuje powstrzymywania, odwiedzający uzyskuje takie same wrażenia, jak zwykle, a osoby obsługujące przeglądarki uzyskują zwiększoną wydajność.

Sugerowałbym, że jest to świetna rzecz do dodania do dowolnych komponentów, które tworzysz w bibliotece komponentów lub wzorców, jeśli pracujesz w ten sposób, prawdopodobnie każdy komponent jest zaprojektowany jako niezależna rzecz, która nie wpływa na inne elementy na strona, dzięki czemu contain: content użyteczny dodatek.

Dlatego jeśli masz stronę, która dodaje treść do DOM po załadowaniu, polecam spróbować — jeśli uzyskasz jakieś ciekawe wyniki, daj mi znać w komentarzach!

Powiązane zasoby

Poniższe zasoby podają więcej szczegółów na temat implementacji ograniczania i potencjalnych korzyści związanych z wydajnością:

  • contain właściwość CSS”, dokumentacja internetowa MDN
  • „Zatrzymywanie CSS w Chrome 52”, Google Developers
  • „CSS Moduł Ograniczający Poziom 1”, Rekomendacja W3C
  • „Wprowadzenie do ograniczania CSS”, Manuel Rego Casasnovas