CSS och webb

CSS-gradienters prestanda: gör de en webbplats långsammare?

En statisk CSS-gradient är nästan gratis. Kostnaderna kommer av vad folk gör med gradienter: enorma oskärpor, bakgrunder som ritas om vid scroll och animationer som aldrig slutar. Så ser du skillnaden.

GradientlyVerifierat Gradiently-konto··6 minuters läsning
Omslag: Burnt Mist · GR·3M7T·BR

Kortversionen

  • En statisk CSS-gradient kostar nästan ingenting att ladda, eftersom den är en rad text i stället för en fil som ska laddas ned och avkodas.
  • Gradienter kostar ritningstid, som växer med den målade ytan och antalet lager, men en statisk gradient målas en gång och återanvänds sedan.
  • De verkliga prestandarisikerna är stora oskärpefilter, bakgrunder som ritas om vid scroll och gradientanimationer som ritas om varje bildruta.
  • Att animera transform eller opacity på ett gradientlager är oftast mycket billigare än att animera background-position eller färgstopp.
  • Det enda pålitliga svaret för en specifik sida är att mäta, med paint flashing och en Performance-inspelning i webbläsarens utvecklarverktyg.
På den här sidan

God prestanda för CSS-gradienter är det normala: en statisk gradient gör inte en webbplats långsammare på något sätt du skulle märka. Den är en rad text, så det finns ingenting att ladda ned, ingenting att avkoda och ingenting att vänta på. Gradienter kostar lite ritningstid, som varje annan färg på sidan. Långsamma sidor kommer av några specifika mönster som byggs ovanpå gradienter: stora oskärpor, omritning vid scroll och animationer som ritas om varje bildruta. Den här guiden visar vad som är vad och hur du kontrollerar din egen sida.

Laddning: gradienter mot bilder

background: linear-gradient(135deg, #1e1b4b, #7c3aed 55%, #f472b6); är 67 tecken. Den kommer med i din stilmall, behöver ingen extra förfrågan och renderas skarpt i vilken storlek och pixeltäthet som helst. En bildbakgrund behöver en egen förfrågan, måste avkodas innan den kan ritas och måste vara tillräckligt stor för stora skärmar med hög täthet.

67 tecken CSSlinear-gradient(135deg, #1e1b4b, #7c3aed 55%, #f472b6)
Hela den här bakgrunden, i vilken storlek som helst, kostar mindre än en mening text att ladda.
BakgrundNedladdningAvkodat minne vid 1920×1080
CSS-gradientNågra dussin byte i din CSSIngen bitmapp att behålla, målas vid behov
Komprimerad bild (AVIF, WebP, JPEG)En separat fil, ofta tiotals till hundratals kilobyteCirka 8,3 MB (bredd × höjd × 4 byte)
Samma bild i 3840×2160 för skarp 4KÄnnu störreCirka 33 MB
Avkodade bilder hålls som fullständiga bitmappar, oavsett filstorlek. Minnessiffrorna är enkel aritmetik: pixlar gånger fyra byte.

För enkla och måttligt lagerlagda bakgrunder vinner alltså CSS på laddning varje gång. Bilder är fortfarande rimliga när bakgrunden verkligen är komplex, som en målerisk mesh-gradient med många färgpunkter eller en fotografisk textur. Då är avvägningen filvikt mot visuell rikedom, och den är ofta värd det.

Ritning: vad en gradient kostar på skärmen

För att visa en gradient räknar webbläsaren ut en färg för varje pixel den täcker: det är ritning. Arbetet växer med den målade ytan, antalet staplade gradientlager och eventuella effekter ovanpå. För en statisk bakgrund sker det en gång, och resultatet återanvänds medan du scrollar eller interagerar, såvida inte något gör det ogiltigt.

Målas en gång

  • En statisk gradient på ett kort eller en hero
  • Flera lagerlagda radiella sken som inte rör sig
  • En kaklad brustextur över en gradient
  • En gradientram ritad med bakgrunder

Målas om och om igen

  • Animerad background-position eller animerade färgstopp
  • background-attachment: fixed vid scroll
  • backdrop-filter-oskärpa över rörligt innehåll
  • Ett element med en gradient som ändrar storlek hela tiden

De verkliga riskerna: oskärpa, fasta bakgrunder och animation

Stora oskärpor. filter: blur() och backdrop-filter samplar många omgivande pixlar för varje pixel, och arbetet växer med både oskärperadien och ytan. En suddad gradient som målas en gång är oftast bra. Ett backdrop-filter över innehåll som scrollar under måste räknas om när innehållet rör sig, och det är där glasmorfism-gränssnitt tenderar att hacka på enklare telefoner.

Fasta bakgrunder. background-attachment: fixed håller en bakgrund stilla medan sidan scrollar, vilket kan tvinga den att ritas om vid varje scrollsteg. Om du vill ha en gradient som stannar på plats är ett position: fixed-element bakom innehållet oftast billigare, eftersom webbläsaren kan flytta det som ett separat lager.

Animation. Att flytta background-position eller animera färgstopp via @property ritar om elementet varje bildruta. På en knapp är det försumbart. På en helskärmshero är det ständigt arbete så länge sidan är öppen, vilket syns som värme och batteriåtgång på telefoner.

css
/* repaints the whole hero every frame */
.hero--costly {
  background: linear-gradient(120deg, #1e1b4b, #7c3aed, #f472b6);
  background-size: 300% 300%;
  animation: pan 12s ease-in-out infinite alternate;
}

/* the browser can usually just move a finished layer */
.hero--cheap::before {
  content: "";
  position: absolute;
  inset: -50%;
  z-index: -1;
  background: conic-gradient(#1e1b4b, #7c3aed, #f472b6, #1e1b4b);
  animation: turn 40s linear infinite;
}

@keyframes pan { to { background-position: 100% 50%; } }
@keyframes turn { to { transform: rotate(1turn); } }
Två animerade hero-ytor. Den andra animerar transform, som webbläsare oftast kan hantera i sammanfogaren utan att rita om.

Guiden om animerade gradienter i CSS har hela uppsättningen tekniker, från billigast till mest flexibel.

Lager och will-change

Att lyfta ett element till ett eget sammanfogningslager, med will-change: transform eller en aktiv transformanimation, är det som gör billig animation möjlig. Det är inte gratis: varje lager håller sin egen bitmapp i grafikminnet, ungefär bredd × höjd × 4 byte i enhetspixlar. Ett överdimensionerat lager för en hero-bakgrund är bra. Dussintals lyfta kort, var och ett med sitt eget gradientlager, kan använda mer minne än de sparar i ritningstid. Lägg will-change på de element som faktiskt animeras, inte som en generell regel.

MönsterWebbläsarens arbeteBilligare alternativ
Animerad background-position på en heroOmritning varje bildrutatransform på ett överdimensionerat gradientlager
background-attachment: fixedOmritning vid scrollEtt gradientlager med position: fixed bakom innehållet
backdrop-filter över scrollande innehållOskärpan räknas om när innehållet rör sigEtt i förväg suddat statiskt lager, eller en mindre suddad yta
Levande SVG-brusfilter på ett stort elementFiltret körs över varje omritad pixelEn liten kaklad brusbild
will-change på varje kortMånga lager hålls i grafikminnetwill-change bara på det som animeras
Vanliga gradientmönster, vad de får webbläsaren att göra och det lättare sättet att få samma look.

Så mäter du gradientprestanda

  1. 1

    Slå på paint flashing

    Öppna panelen Rendering i Chrome DevTools och aktivera Paint flashing. Allt som blinkar grönt när inget borde förändras ritas om.

  2. 2

    Spela in ett Performance-spår

    Spela in några sekunder scroll eller vilande animation i panelen Performance. Titta på hur stor del av varje bildruta som går åt till ritning och om bildrutor tappas.

  3. 3

    Strypa processorn

    Använd CPU-strypningen i panelen Performance för att simulera en långsammare enhet. En hero som är mjuk på en snabb bärbar dator kan kämpa på en telefon i mellanklassen.

  4. 4

    Kontrollera panelen Layers

    Se hur många sammanfogningslager som finns och hur mycket minne de använder. Oväntat många lager betyder oftast att will-change överanvänds.

  5. 5

    Testa den riktiga enheten

    Avsluta på en verklig telefon. Värme och batteriåtgång från ständig animation är lätta att missa på en dator.

web.devs guide till renderingsprestanda förklarar kedjan bakom de här verktygen: stil, layout, ritning och sammanfogning. Om du vet vilket steg din gradient utlöser vet du om den är billig.

En prestandachecklista för gradienter

  • Använd CSS-gradienter för enkla och lagerlagda bakgrunder, bilder bara när looken verkligen kräver dem.
  • Håll oskärperadierna måttliga och undvik backdrop-filter över stora scrollande ytor.
  • Ersätt background-attachment: fixed med ett lager med fast position.
  • Animera transform eller opacity, inte background-position, på stora ytor.
  • Långsamma, stillsamma animationer kan stanna helt för användare som vill ha reducerad rörelse.
  • Lägg till korn som en liten kaklad bild, inte som ett levande SVG-filter på ett stort element, se brustextur i CSS.
  • Mät före och efter med paint flashing och en Performance-inspelning.

Vanliga frågor

Gör CSS-gradienter en webbplats långsammare?

Statiska CSS-gradienter gör det inte på något märkbart sätt. De behöver ingen nedladdning och målas en gång. Stora oskärpor, fasta bakgrunder och ständig animation är det som kostar prestanda.

Är en CSS-gradient snabbare än en bakgrundsbild?

Oftast ja. En gradient är några dussin byte CSS utan förfrågan eller avkodning, medan en bild kräver nedladdning och hålls i minnet som en fullständig bitmapp.

Är animerade gradienter dåliga för prestandan?

Att animera background-position eller färgstopp ritar om varje bildruta, vilket spelar roll på stora ytor. Att animera transform eller opacity på ett gradientlager är oftast mycket billigare.

Varför är min suddiga gradientbakgrund långsam?

Oskärpa samplar många grannpixlar för varje pixel, så kostnaden växer med radie och yta. Den är värst med backdrop-filter över innehåll som scrollar eller animeras.

Hur kontrollerar jag om min gradient ritas om?

Aktivera Paint flashing i panelen Rendering i Chrome DevTools. Ytor som fortsätter blinka medan sidan är stilla ritas om.

Dela den här guiden

Skriven av GradientlyVerifierat Gradiently-konto

Teamet bakom Gradiently, ett designverktyg byggt kring Marks: levande gradienter som får allt du gör att kännas som ditt.

Se vår profil