Grensesnittsytelse
Etter fem artikler om webstandarder sett i lys av en sjekkliste for grensesnittsimplementasjon av høy kvalitet er det på tide å skifte tema og snakke om ytelse.
Bakgrunn: Sjekkliste for grensesnittsutivkling
Yahoo! har gjort glimrende arbeid på ytelsesfronten, og jeg skal ikke gjenta alle deres poenger her. Men, for kompletthetens skyld ønsker jeg alikevel å oppsummere de viktigste punktene, sammen med enkelte andre poenger som ikke kommer frem i Yahoos analyser.
Nettverkstrafikk og caching
Mange av punktene jeg vil gå igjennom i denne artikkelen dreier seg om å begrense hva og hvor mye brukerne dine laster ned. Mange fnyser av den type optimalisering, og begrunner påstander om at det ikke er viktig med at "de fleste" surfer med nettleser-cache alikevel. Dette kan så være, men Yahoo! har ihvertfall undesøkt hva deres brukere driver med, og der viste det seg at hele 40-60% hadde en "tom-cache-opplevelse", og ~20% av sidevisningene ble gjort på tom cache.
Hvorfor er det så høye tall? Det kan være mange grunner:
- Brukerne surfer uten cache (kan gjelde brukere på bedrifter med standardoppsett hvor caching er redusert eller fjernet for å tilrettelegge for interne proxyer osv)
- Brukerne tømmer cache ofte
- Brukerne surfer mye, noe som gjør at nettleseren ofte tømmer eldre ting i cachen fordi det kommer så mange nye elementer. Ved hver retur til ditt nettsted har brukeren surfet nok til at nettleseren har "glemt" dine elementer
- Elementene dine er kanskje ikke godt nok tilrettelagt for caching (les videre!)
Optimerte png/gif/jpg
Bruk av optimert grafikk er et av de punktene der det er mulig å hente mye. Giffer med mange farger som ukritisk lagres "as is" kan fort la seg komprimere til en tiendel bare med minimalt med bevisst arbeid.
Hvorfor?
- Ukomprimerte grafikkelementer er dødvekt som brukerne dine må bruke tid på å laste ned
- Å komprimere grafikkelementer er enkelt
- Ved å minimere antall eksterne grafikkelementer kan ytelsen forbedres ytterligere
Hvordan?
Grafikkbruken kan optimeres både ved å optimere grafikken som lastes ned, men også ved å minimere mengden grafikk brukeren må laste ned.
- Bruk "save for web"-dialogen dersom du bruker Photoshop ( Save for web-plugin finnes også til Gimp)
- Eksperimenter med formater (gif, jpg, png8/png24), antall farger og komprimeringsnivå
- Bruk CSS sprites (flere bilde-elementer i ett og samme bilde i kombinasjon med bakgrundsplassering i CSS) der det er mulig
- Bruk kombinasjoner av bakgrunnsfarger,
outlineogborderi CSS fremfor grafikkelementer der det er mulig
"Minifiserte" filer/komprimert CSS og JavaScript
En praksis som har blitt populær i nyere tid er å komprimere CSS og JavaScript. Her er det rom for store besparelser uten noen form for kvalitetsforringelser, annet enn et ekstra steg i utviklingsfasen (eventuelt prodsettingsfasen).
CSS
CSS komprimeres ved at man fjerner alle kommentarer og all unødvendig white-space og andre tegn slik at den resulterende CSS-en blir en lang og uleselig linje. For nettleserne betyr dette ingenting, men for nettverkstrafikken kan dette bety besparelser på opptil 30-40%, noe som betyr mer snappy grensesnitt for dine besøkere.
Hvordan?
- CSS Tidy - verktøy som optimerer og komprimerer CSS
- YUI Compressor - verktøy fra Yahoo! for å komprimere både CSS og JavaScript
- CSS Drive CSS compressor
JavaScript
Komprimering av JavaScript kan fungere på samme måte som CSS - ved å fjerne unødig white space og kommentarer. Men, i tillegg til dette er det mulig å gjøre "destruktiv komprimering" ved å forkorte variabel- og metode-navn, og å gjøre andre "plassoptimeringer" av koden.
En tredje mulighet er å bruke et verktøy som Dean Edwards' Packer som pakker sammen scriptet og legger ved litt JavaScript for å pakke det ut igjen. Selvom dette ofte resulterer i veldig små filer, så oppnås best resultat når YUI Compressor brukes sammen med gzip.
Grunnen til dette er rett og slett at gzips komprimeringsalgoritmer er bedre enn Packer sine, men resultatet av Packers komprimering er ikke like godt egnet for komprimering med gzip (det er allerede komprimert). I tillegg er det en overhead i Packer fordi den bruker JavaScript til å dekomprimere på hver sidevisning.
Hvordan?
- YUI Compressor - verktøy fra Yahoo! for å komprimere både CSS og JavaScript
- Packer
- Dojo Shrinksafe
- JsMin
Minimer antall HTTP-requests
En stor tidstyv kan være antall HTTP-requests. Det er stort sett bedre/raskere å laste ned én fil på 10kB enn 10 filer på 1kB. Dette skyldes flere ting:
- Nettleseren slipper å starte så mange nye requests
- Nettleserne er ofte begrenset til et lavt antall samtidige nedlastinger fra samme domene (2-3)
- Nettleseren må sjekke etter cachede elementer flere ganger
Ved å minimere antall requests vil sidene dine lastes raskere.
Hvordan?
- Kombinér komprimerte CSS-filer
- Kombinér komprimerte JavaScript-filer
- Bruk nevnte " CSS sprites" for å minimere antall grafikkelementer
Rydd i CSS og JavaScript
Når et prosjekt har gått lenge nok ender man ofte opp med en viss mengde CSS og JavaScript som rett og slett ikke er i bruk. Dette er særlig sant i store prosjekter og store organisasjoner der samme designbase brukes i mange prosjekter. Man har ofte ikke god nok oversikt til å kunne riste av seg ubrukte elementer.
Bruk en prototype
Et av de aller viktigste hjelpemidlene for å holde oversikt over klientkoden din er å ha en prototype som er funksjonskomplett. Den trenger ikke å være en statisk kopi av hele nettstedet ditt, men den bør ha en representant for hver av de unike sidene i prosjektet, og den bør inneholde alle elementene som er tilgjengelig i CSS- og JavaScript-filene dine.
Ved å ha en fullstendig prototype oppnår du (minst) to interessante mål:
- Enklere å teste
- Enklere å rydde/holde oversikt
...i tillegg til fordelene man har under utvikling og mye mer. Men det er en annen historie...
Det første punktet er spesielt viktig fordi testing er nøkkelen til rydding. Dersom du har identifisert kode som sannsynligvis ikke lengre er i bruk er det svært betryggende å kunne klikke gjennom alle malene og verifisere at de fungerer når du har fjernet den.
Hvorfor?
Ved å fjerne kode som ikke er i bruk får brukerne dine mindre å laste ned = raskere opplevelse.
Hvordan?
- Som sagt, bruk en prototype så du har et minimalt (men komplett) sett med sider å teste endringer i
- Fjern duplikate script og CSS-filer
- CSSTidy kan optimere selectorer og andre ting i CSS-filer. CSSTidy har flere nivåer. Bruk de mest drastiske forsiktig ettersom den kan rearrangere så mye at enkelte ting ikke lengre fungerer.
- Dust Me Selectors kan hjelpe deg å identifisere velgere som ikke er i bruk. Du er avhengig av å surfe alle sidene som bruker CSS-en det skal ryddes i, så en prototype vil være svært behjelpelig her
Cache-Control, Expires og andre triks: Tilrettelegg for caching
Cache-Control og Expires er to HTTP-headerne som kan brukes til å kontrollere hvordan brukerens nettleser cacher innholdet ditt, og kan potensielt spare deg for masse (unødvendig) nettverkstrafikk.
Statiske elementer så som grafikkelementer, CSS og JavaScript kan vanligvis caches "hardt" siden disse ikke endres ofte. Dette kan gjøres ved å sette en Expires-header som alltid ligger foran i tid. Når filene en gang endrer seg kan man tvinge nye versjoner til brukerne gjennom nye filnavn. Ettersom det sannsynligvis er litt pes å gi nytt navn til filene hver gang du endrer dem gjelder det å finne andre måter å fornye stien på. En enkel måte er å sette inn timestamp for sist endret dato på selve fila som GET-parameter på URL-en til filene. Det gjør ingen forskjell på filen, men nettleseren oppfatter det som nye URL-er og henter de fra serveren. Rammeverk som Ruby on Rails gjør dette automatisk.
Les også en mer dyptgående diskusjon av hvordan Apache kan konfigureres til å være cache-vennlig for detaljer på selve oppsettet.
For dynamisk innhold er det viktig å konfigurere serveren/CMS/applikasjon til å svare med en Expires-header som er tilpasset innholdet. Mange systemer kommer default med cache- uvennlige innstillinger for å unngå at brukere opplever at systmet ikke endrer seg når det skal. Dette er et greit utgangspunkt, men som en del oppsettet må utviklerne huske å tilpasse dette til siten.
Ajax må også caches
Det er fort gjort å glemme at også trafikk via XmlHttpRequest (med andre ord: "Ajax") må caches skikkelig. De samme reglene som over gjelder også for
HTML,
XML,
JSON,
YAML og annet, både i bruddstykker og som hele dokumenter.
YSlow/Firebug
Som jeg nevnte innledningsvis er mye av stoffet i dette innlegget ikke noe nytt dersom du allerede kjenner arbeidet Yahoo! har gjort rundt disse tingene, og ikke minst boka på temaet.
Gjengen har også sluppet en extension til Firefox (eller, nærmere bestemt Firebug), YSlow, som sjekker nettsider opp mot de viktigste kravene de har indentifisert og gir deg en score. Du bør alltid streve etter å score så bra som mulig på denne testen. Ikke bare hjelper den deg med ytelse, men den gjør det morsomt å tweake implementasjonen!
Flere punkter fra Yahoo!
Avslutningsvis ønsker jeg igjen å vise til artiklene fra Yahoo! som har mange punkter som ikke er diskutert i denne artikkelen. Ytelse på webapplikasjoner er et område der det fortsatt gjøres mye forskning, og det dukker stadig opp nye løsninger, så dette innlegget bør bare ses på som noen av de viktigste punktene; det er langt fra en komplett liste. Yahoo!s liste blir også stadig vekk lengre, så her gjelder det å følge med!