Et billede siger mere end tusind ord...
- Næppe hvis dine billeder blokerer dit websites loadtid så dine brugere mister tålmodigheden. Store billedfiler har en betydelig effekt på hvor hurtigt dine websider loades. Heldigvis er der mange metoder til at komprimere billeder så de fylder en brøkdel af deres oprindelige størrelse. Når det drejer sig om billeder der løbende bliver uploadet til et website må man nok affinde sig med en script baseret løsning og de fleste CMS har også indbygget billedkomprimering helt automatisk. Men tænk på de billeder du bruger i dit tema design såsom logoer bannere, ikoner sliders og som du har måske har brugt timer på at redigere, rendere, colour grade osv. Disse billeder fortjener også manuel komprimering så de fremstår i bedst mulige kvalitet.
Valg af billedformat
Når du udgiver et billede på nettet nå du selvfølgelig anvende et understøttet format. Billeder som består af pixels Bliver kaldt raster- eller bitmap-formater. Disse billeder er de mest almindelige digitale billedformater og de raster-filtyper der kan læses af webbrowsere er GIF, PNG(8/24/32) eller JPEG. Disse billedformater har hver deres fordele og ulemper så det er vigtigt at analysere det enkelte billede for at afgøre hvilket format der er optimalt. De mest afgørende faktorer er:
- Hvor mange individuelle farver/nuancer kræves for at gengive billedet?
- Indeholder billedet bløde farveovergange/ gradienter eller slørede områder?
- Indeholder billedet gennemsigtige eller delvis gennemsigtige pixels?
Indekserede billed formater (8 bit)
For billeder med få farver og skarpe farveovergange kan man opnå særdeles gode resultater med 8 bit formater. De 8 bit filtyper som understøttes af webbrowsere er PNG-8 og GIF. Formatet kan indeholde 256 farver og to værdier for gennemsigtighed (100% eller 0). PNG-8 kan gemmes med tabsløs kompression og fylder næsten altid mindre end GIF. Den eneste grund til at vælge GIF i stedet for PNG-8 er faktisk hvis billedet er animeret.
True colour formater (24 bit)
For billeder med mere end 256 farver og med "bløde" farveovergange, bør man bruge true colour formats som JPEG eller PNG-24/32. Disse formater har 3 kanaler til farveværdier henholdsvis rød, grøn og blå. Hver kanal har 256 mulige værdier og de tre kanaler kan blandes og derved producere millioner af farver. Sammenlagt bruger de tre kanaler 24 bits hvilket betyder at et ukomprimeret true colour billede er 3 gange større end et 8 bit billede. JPEG er udviklet til at komprimere fotografier og giver gode resulter med betydelig reduktion af filstørrelserne. JPEG komprimering er ikke tabsløs og vil generere tydelige kvalitetstab hvis billedet komprimeres for meget. PNG-24/32 er derimod tabsløs og PNG-32 har desuden 8 bit allokeret til en kanal for gennemsigtighed (256 grader af transparens) men true colour PNG filer bliver typisk meget store sammenlignet med JPEG og bruges derfor ofte kun til billeder med transparente pixels. Som tommelfingerregel bør man bruge JPEG til farvefoto og PNG-8 til simple grafiske elementer (med mindre man har en SVG fil til rådighed).
256 shades of grey
For sort/hvid-fotografier (eller rettere gråtone billeder) er valget af format ikke altid indlysende. Både 8 bit og 24 bit formaterne har 256 mulige værdier for gråtoner. De tilbageværende bits i et 24 bit format er reserveret til farver og vil, ganske simpelt, ikke blive brugt. Så man får ikke bedre kvalitet ud af 24 bits. Dog håndterer JPEG-komprimering gråtone-gradienter særdeles godt så JPEG kan ofte være det bedste format til at optimere disse billeder, især hvis billed-materialet indeholder bløde eller slørede overgange.
Komprimering vs. opløsning
Dengang websider blev designet med en fast bredte i pixels var det anbefalet at billeder blev vist i et 1:1 forhold. Dvs. et billede ikke burde have højere opløsning end dets width og height attributter. Men i med nutidens retina displays og flydende, responsive layouts giver denne tankegang ikke rigtig mening mere. Det bør også bemærkes at nogle browsere skalerer hele websiden op (incl. billeder) hvis brugeren har forøget operativ-systemets skriftstørrelse. Så du bør altid have lidt opløsning at "give af" og ønsker du fuldt at udnytte retina displays bør billederne have dobbelt så høj opløsning som de vises i. Heldigvis kan du tillade dig at komprimere billeder med høj opløsning lidt mere da defekterne ikke er så synlige når billedet bliver skaleret ned.
Værktøjer til billedkomprimering
Populære billedbehandlingsprogrammer som PhotoShop kan exportere billeder til web med PNG eller JPEG komprimering. Men der er værktøjer med langt bedre komprimerings-algoritmer, oven i købet gratis. Et af de bedre værktøjer til PNG komprimering jeg har set er TinyPNG. Dette program kan allokere en række indexerede farver præcis som et 8 bit billede men farverne er ikke begrænset til 256 og komprimeringen bevarer en fuld 8 bit alpha kanal. Med andre ord er det kun de brugte farver og alpha værdier i billedet der optager hukommelse. Andre værktøjer som Image Optimizer fra http://www.xat.com/io/ tillader dig at komprimere udvalgte områder af billedet så du f.eks. kan bevare høje detaljer i billedets fokus område og blot komprimere baggrunden.
Bulk processing og automatisering
At optimere billeder manuelt er en tidskrævende proces og, som nævnt, vil det for jævnligt uploadede billeder, eller sites med store arkiver af eksisterende billeder, ofte være en umulig opgave. Men mens du udvikler et site kan du bruge forskellige automatiserings værktøjer til at optimere hele billedarkiver på en gang. Populære task runners som Grunt har plugins designet til formålet og mange applikationer har indbygget bulk processing af grupper af billedfiler. For billeder der bliver uploadet til en PHP web server kan du drage fordel af af PHPs indbyggede imagejpeg funktion, der tager komprimering som et af parametrene. Desværre er algoritmen ikke så god som i de manuelle værktøjer nævnt tidligere.
HTML picture elementet
HTML5 specifikationen har introduceret et nyt tag for for billeder. Picture elementet tillader dig at angive forskellige billedfiler til forskellige skærmopløsninger. Browser loader det source billede som bedst passer til skærmstørrelsen baseret på en angivet media attribut. På den måde kan håndholdte små enheder som ofte benytter langsommere mobile forbindelser nøjes med at hente et meget mindre billede end f.eks desktop PCere. Her ses et eksempel på hvordan picture elementet kan bruges:
Læs mere om picture elementet her
Reducering af HTTP requests med sprite-sheets
Udover selve billedfilernes størrelse, påvirker antallet a HTTP anmodninger også en sides load time hver gang du bruger et billede skal klienten anmode serveren om billedet og vente på at serveren svarer. En løsning på dette problem kan være at lave et såkaldt sprite-sheet. Et sprite-sheet er et enkelt billede som indeholder en mængde mindre billeder. Teknikken er særlig effektiv til UI elementer og ikoner. For at bruge sprite-sheetet ændrer du simpelthen billedets position med CSS for forskellige elementer således at hvert enkelt element kun viser den ønskede del af billedet. Da det store billede bliver lagret i browserens cache kan du have lige så mange HTTP anmodninger til billedet som du vil uden at påvirke sidens load time.
Gentagne "fliselægbare" billeder
Denne teknik er særdeles effektiv til baggrunds-teksturer. Idéen består I at gentage et lille billede over et stort område. For at undgå synlig "fliselæging" må du sikre dig at billedets hjørner flydende passer sammen. Der findes en del online-ressourcer for denne slags teksturer men du kan også prøve at lave dine egne. Tag et billede af et stykke stof, en betonmur eller hvad du nu finder på. Brug PhotoShops eller Gimps Offset funktions til at flytte billedet 50% på hver akse. Dette vil resultere i at billedets kanter mødes i midten af billedet og danner et kors. Brug klonings-værktøjet til til at fjerne korset. Hvis det lykkes har du nu et billede der kan gentages uendeligt. Husk at skalere billedet til en fornuftig størrelse.
Optimering af baggrundsbilleder med media queries
For CSS baggrundsbilleder kan du specificere forskellige billeder til forskellige opløsninger og dermed begrænse eller helt udelade billeder til mindre enheder. Hvis du designer efter Mobile First princippet bliver ingen af dine style propperties til store skærme (incl. store baggrunds-billeder) indlæst på mobiler eller tablets og og loadtiden for et site på disse enheder reduceres.
Vektor grafik
SVG kan bruges i img tags, som CSS baggrunds-billeder eller indlejres direkte i din mark-up med et svg tag. Sidstnævnte metode vil spare dig for en HTTP request og tillade dig at ændre fill og stroke farver med CSS, men indlejret SVG kode vil selvfølgelig gøre din mark-up mere uoverskueslig. Vektor grafik kan skaleres til hvilken som helst størrelse uden tab. Efterhånden er SVG rigtig godt understøttet i alle browsere, men ikke implementeret i IE8 og browsere i ældre Android enheder. Du kan dog nemt lave et inline bitmap fallback hvis du vil understøtte disse browsere vha. en onerror attribut:
(Det er vigtigt at sætte onerror attributten til null efter at have ændret src attributten. Ellers vil error eventen gentages ustandseligt i tilfælde af at image.png ikke kan findes/loades)
Illustrator og InkScape kan exportere optimerede SVG filer men du kan også åbne dine SVG filer i en tekst-editor og manuelt fjerne uønskede kommentarer, attributter og white space men dine SVG tags bør indeholde width -og height- attributter med 100% som værdier for begge og ligeledes en viewbox attribut Hvor billedets originale proportioner er angivet. Hvis du udelader disse attributter kan det give problemer i visse browsere.
Lazy load af billeder
Lazy loading er en teknik til at loade billeder efterhånden som de er i brugerens viewport. Metoden er særlig brugbar på lange sider med mange billeder. I tilfælde af at brugeren aldrig scroller ned på siden er der jo ikke grund til at loade de nederste billeder. Chris Coyier og Lorenzo Giuliani har publiceret dette script så man relativt nemt kan implementeres lazy loading. Idéen er at starte med at angive et lille usynligt placeholder-billede som src attribut på alle billeder og derefter bruge JavaScript til at registrere om billedet er i brugerens viewport. I så fald udskiftes billedet med det "rigtige" billede som er blevet angivet i en data-attribut. Man kan betvivle hvorvidt søgemaskiner vil registrere billederne. Så hvis du vil have dine billeder indexeret kan det godt være du skal undlade at bruge denne teknik.