Arkiv

Idlæg Tagged ‘guide’

Sådan laver du hurtigere websider

13 april, 2010 dinbror 2 kommentarer

Efter påpegelse af Niels Gamborg og i forlængelse af mit forrige indlæg Sådan laver du perfekt CSS kommer her en tilføjelse, som omhandler performance aspektet. Selvfølgelig skal man ikke være ligeglad med performance, hvorfor man skal huske at optimere sine websider. Hvis det ikke er for din egen skyld og/eller pengepung, så for at brugerne får en bedre (og hurtigere) oplevelse. Ligeledes tyder det desuden på, at Google vil (og til dels allerede gør) vægte hurtigere hjemmesider højere.
Jeg har opstillet nogle simple punkter, som gerne skulle hjælpe med at opnå hurtigere indlæsningstider på dine websider.

0: Minimer HTTP-requests

Jo færre requests jo bedre. Den største og nok nemmest måde at reducere dine indlæsningstider på dine websider ligger i antallet af HTTP-requests, hvorfor du skal eliminere unødvendige requests.

Hvorfor
Browsere bruger i dag cirka 80% af deres tid på at hente eksterne filer såsom stylesheets, scripts, billeder etc. Hver fil er lig med et request, dog henter browsere disse requests parallelt (på nær script-filerne), og alt afhængig af browser, kan de have x antal forbindelser kørende på samme host på samme tid.  Herunder er opstillet nogle eksempler på, hvor mange forbindelser per host samt max forbindelser de mest benyttede browsere kan håndtere:

    Browser           |   Connection per hostname   |   Max connections
Internet Explorer 8                   6                        57
Chrome 4                              6                        55
Chrome 5                              6                        40
Firefox 3.5+3.6                       6                        30
Safari 4                              5                        60
Opera 10                              4                        20
Internet Explorer 7                   2                        60
Internet Explorer 6                   2                        56

Andre browsere og flere detaljer omkring de enkelte browsere kan findes på browserscope, som er et open source projekt startet af Steve Souders og Lindsey Simon.

Hvordan
Ja nu ved vi, hvorfor det er en god ide at minimere HTTP-requests, men hvordan gør vi det egentlig i praksis?
Der findes flere måder at gøre det på. Jeg vil her præsentere 2 måder, som jeg selv finder nyttige, brugbare og bruger til dagligt.

a) Kombinerede filer: Så snart det er muligt, skal man kombinere sine scripts og stylesheets således, at alle ens stylesheets bliver samlet i en fil og ligeledes med sine scripts. På denne måde kan man spare requests.
Det kan dog være svært, hvis scripts og stylesheets varierer meget fra side til side. Her må man gå ind og vurdere den enkelte situation, og kigge på hvad der mest gavner indlæsninghastigheden. Man skal være opmærksom på, at fx billeder i stylesheets også generer requests, så hvis tendensen på din side ikke er, at brugeren besøger mange sider, og du har meget forskelligt styling fra side til side, kan man spare requests ved at benytte sig af en side-modulær CSS opbygning. Men som tommelfingerregel skal man samle sine stylesheets samt scripts i en fil.

b) CSS Sprites: CSS Sprites reducerer antallet af billede requests. Kort fortalt går det ud på, at man samler flere af sine billeder i et billede, og vha. background-position styre hvilken sekvens af billedet, man vil vise. Hvis du ikke kender til sprites, kan du læse mere omkring emnet her:

CSS Sprites: Image Slicing’s Kiss of Death af David Shea

The Mystery Of CSS Sprites af Sven Lennartz

CSS Sprite: What they are … af Chris Coyier

Eller kigge nærmere på hvordan jeg har lavet min top menu.

1: Placerer stylesheets i toppen

Der er to grunde til at placerer stylesheets i toppen.

  1. W3 dikterer, at stylesheets skal være i toppen (head), medmindre det er inline-styling.
  2. Ved at placere stylesheets i toppen opnår man, at ens side loader progressivt, hvilket er vigtigt, hvis din side har meget indhold, eller brugeren sidder bag en langsom forbindelse. Siden viser indholdet så snart, det er klart, og brugeren har en indikation af, at siden er ved at loade. Denne indikation er meget vigtig for brugervenligheden. Hvis man derimod indsatte stylesheets nær bunden, ville man i mange browsere (eksempelvis Internet Explorer) miste den progressiv hentning og stå tilbage med en hvid blank side, da browsere blokerer renderingen for at forhindre at skulle gentegne elementer, der måtte ændre sig.

2: Placerer scripts i bunden

Grunden til at scripts skal være i bunden er, at scripts blokerer for den parallelle hentning, hvorfor resten af dit indhold må vente til scriptet er færdighentet. Derfor placerer altid dine scripts i bunden, når det er muligt. Der findes selvfølgelig situationer, hvor du ikke kan, fx hvis du indsætter markup via document.write, hvilket jeg dog ikke er den store fan af eller initialisere ting i dit script i den øvre del af dit HTML dokument.

3: Stylesheets og scripts skal være eksterne

Nu kommer jeg til at modsige mig selv, men der er en mening med galskaben. I første punkt fik du at vide, at du skulle spare på HTTP-requests, og undgå dem så snart det var muligt, men nu fortæller jeg dig, at du skal gemme dine stylesheets samt scripts eksternt frem for at gemme dem inline, og dermed generer et ekstra request per fil. Igen kommer det an på situationen, men oftest er der mest at hente ved at gemme dem eksternt. Ved at gemme dem eksternt bruger du som sagt et ekstra request per fil, men da browsere cacher filerne, kan det være en fordel, hvis du eksempelvis bruger de samme filer på flere sider. Ved at gemme dem inline spare du det ekstra request, men HTML dokumentet bliver tungere, og filerne bliver indlæst ved hver page load. Når dine filer derimod er cachet generer de ikke et ekstra request og HTML dokumentet er ligeledes lettere.

4: Minify

Ved at minify sine stylesheets og scripts fjerner man unødvendige tegn og luft, og gør dem derved lettere at hente. Der findes forskellige værktøjer til at minify med:

  1. YUI Compressor: YUI er et af de mest kendte og mest effektive minify værktøjer. Det er skrevet i Java, og man skal afvikle det på sin computer. Det gode ved YUI er selvfølgelig den effektive algoritme som minifyer, men også at den kan minify scripts såvel som stylesheets.
  2. CSS Compressor: Online værktøj, som kan minify dit CSS ud fra forskellige indstillinger.
  3. Closure compiler: Googles svar på et script minify værktøj, som eftersigende skulle være bedre end YUI. Compileren kan både downloades eller benyttes online samt indstilles efter behov og temperament.

5: Fjern duplikater

Punktet burde egentligt ikke have været med på listen, da det giver sig selv. Men jeg har set steder, hvor de stadig forekommer, duplikater af scripts. Ved at have duplikater forøges indlæsningstiden. Internet Explorer laver et ekstra unødvendigt request, hvorimod Firefox godt kan se, at det er det samme script. Dog spilder begge browsere tid på at evaluere scriptet to gange, så undgå at have duplikerende scripts.

6: Reducer DOM-elementer

En tommelfingerregel er, at jo flere elementer du har på en side, jo tungere er den at renderer. Sørg derfor altid for at have så ren og meningsfuld markup som muligt. Mange elementer på en side gør det ligeledes sværere for JavaScript at tilgå dem. En måde du kan undersøge, hvor mange elementer en side har, er ved hjælp af Firebug. Skriv blot følgende i konsol vinduet:

document.getElementsByTagName('*').length

7: Brug dine subdomæner

HTTP 1.1 specifikationen anbefaler, at browsere ikke downloader mere end 2 komponenter parallelt per host. Ved at gemme dine billeder på flere forskellige hosts, kan du opnå mere end 2 parallelle downloads ad gangen, og dermed gøre din side hurtigere. Steve Souders har lavet et lille eksempel, hvor han illustrerer forskellen på at gemme sine billeder på et host kontra to.

8: Undgå @import

Brug <link /> frem for @import. Internet Explorer opfatter filer indsat ved hjælp af @import som link-tags, der er indsat i bunden af siden.

9: Undgå filters

Hvis du vil have transparente png billeder i Internet Explorer 6, kan du bruge Microsofts eget filter, AlphaImageLoader. Dette er dog ikke anbefalingsmækværdi! Problemet ligger i at filteret blokerer rendering af siden og fryser browservinduet, mens billedet bliver hentet. Filteret forøger ligeledes brugen af computerens hukommelse. Undgå derfor at bruge dem, og brug i stedet gif eller png8 billeder eller nogle af de andre alternativer der findes, hvis du vil understøtte semi-transparente billeder i IE6.

10: Undgå tomme billede referencer

Tomme billede referencer resulterer i ekstra og nytteløse serverkald:

<img src="" alt="Tomt billede reference" />

Nicholas C. Zakas har skrevet en udmærket artikel, der beskriver problemet rigtig godt.

11: Komprimerer dine billeder

Hvis du som jeg ikke altid selv klipper dit grafik og dermed gemmer det, kan der opnås store besparelser ved selv at genkomprimerer billederne. Uden at slå alle designer over en kam, så tænker de ikke på størrelsen.

12: Komprimerer dine komponenter

GNU zip eller også kaldet gzip er en komprimeringsmetode, som kan spare dig adskillige kilo bytes og dermed minimere svar tiderne. Vel og mærket hvis server samt klient understøtter det. Fra og med HTTP/1.1 er web-klienter begyndt at understøtte komprimering med Accept-Encoding i headeren af HTTP-request’et, fx:

Accept-Encoding: gzip, deflate

CSS: Sådan laver du perfekt CSS

27 februar, 2010 dinbror 7 kommentarer

Igennem mit arbejde og efter kraftig inspiration af Andy Clarke har jeg fundet den “perfekte” måde at lave CSS og markup på. I denne artikel vil jeg forsøge kun at koncentrerer mig omkring CSS delen og give dig opskriften, som tager udgangspunkt i solskinsdage. Til den dovne læser har jeg lavet et kort resume til sidst under hvert punkt.

0: Markup

Lav altid dit markup før du begynder at style. Sørg for at den er valid, og at den er semantisk opbygget. En god tommelfingerregel er, at ens markup skal give mening uden brug af CSS.

Resume: Markup før CSS!

1: Validering

Ligesom med dit markup skal dit CSS være valid. Hvis du er i tvivl, kan du validere dine stylesheets via W3’s CSS validator. Mange undervurderer vigtigheden af valid kode, så længe det bare ser ud, som det skal. Men ved ikke at have valid kode, kan man ikke være sikker på, at ens websider vil blive vist rigtigt i fremtiden, og at mindre og alternative fremvisere kan vise dit indhold. Hvis ingen fulgte en vis standard ville khaos regerer.

Resume: Lav valid kode!

2: Normalisering

Normaliserer altid dit stylesheet inden du går i gang. Forskellige browsere har forskellige default værdier til de forskellige elementer, hvorfor det til tider kan være umuligt at lave en side, der opfører sig ens cross-browser uden brug af reset. Hvor meget eller hvor lidt der skal resettes er en temperamentssag. Herunder er listet nogle eksempler:

  1. CSS Reset Reloaded by Eric Meyer
  2. Yahoo! UI Library: Reset CSS
  3. CSS Global Styles Reset by Kyle Neath

Være opmærksom på at det korte og brugte reset: * { margin: 0; padding: 0; } er et misforstået reset. Det er tungere at renderer (især med store websider), da det definerer regler for hvert enkelt element i ens dokument og nulstiller alt, hvorfor det ikke er anbefalingsværdigt.

Resume: Reset dit stylesheet før start!

3: Navngivning

Navngivning er utrolig vigtig og desværre også utrolig undervurderet. Uanset hvad du vælger så vær konsekvent. Hold dig evt. til engelsk, brug camelCaseMedLilleBegyndelsebogstav og giv strukturelle navne frem for præsentationsmæssige.
Et strukturalt navn beskriver, hvad det er for et element, du vil henvise til frem for et præsentationsmæssigt navn, som beskriver, hvor elementet befinder sig på siden eller hvordan det ser ud.

Præsentationsmæssige navne:

topNav, leftTopLogo, footer, leftContent, redBoldLink

Strukturelle navne:

primaryNav, branding, siteInfo, mainContent, externalLink

De præsentationsmæssige navne låser elementet fast, hvorfor de skal undgås. Hvad nu hvis din top menu (#topNav) pludselig skal ligge til venstre for dit indhold?

Resume: Vær konsekvent og brug camelCaseMedLilleBegyndelsebogstav samt strukturelle navne i din navngivning.

4: Struktur

Ens struktur kan virke utrolig ligegyldig og spild af tid hos mange, men er faktisk et af de vigtigste punkter i perfekt CSS. For din egen skyld, for kundens skyld og for fremtidige udvikleres skyld sørg for at have struktur i dit CSS. Som med navngivningen er det vigtigt at være konsekvent.

a) Inddel dit stylesheet i afsnit, fx via sektioner eller selectors.

/****** STRUCTURE  ******/
#branding, #primaryNav, #mainContent...
/****** HEADERS  ******/
h1, h2, h3 ...
/****** ANCHORS  ******/
a, a:hover ...
etc

b) Et element pr. linje.

#element 1 { egenskab 1, egenskab 2 ... egenskab n }
#element 2 { egenskab 1, egenskab 2 ... egenskab n }

Mange vil måske være uenige, og hælder til den mere fyldige og måske mere overskuelige-ved-første-blik-måde; en egenskab pr. linje:

#element 1 {
    egenskab 1;
    egenskab 2;
    ...
    egenskab n
}

Men her må jeg insister. Min erfaring er, at ved større projekter bliver stylesheets hurtigt store og uoverskuelige ved en egenskab pr. linje, også selvom man deler det op og har et stylesheet pr. side.

c) Undlad hierarkier i niveauer

Jeg har set folk anbefale, at man inddeler sit stylesheet i et niveau-hierarki, som afspejler sit markup:

div#element { egenskab 1, egenskab 2 ... egenskab n }
  ul { egenskab 1, egenskab 2 ... egenskab n }
    li { egenskab 1, egenskab 2 ... egenskab n }
      a { egenskab 1, egenskab 2 ... egenskab n }

Ideen er rigtig god, men forvirrer mere end den gavner. Desuden kræver det mere vedligeholdelse. Hver gang du ændre det mindste i dit markup, skal du ind og opdatere dit CSS, så de afspejler hinanden.

d) Opstil dine egenskaber i alfabetisk rækkefølge for at få et hurtigere overblik:

#element { float: left; height: 250px; width: 250px; }

e) Vis type på dit element (unikke), igen for overblikkets skyld:

div#element 1 { egenskab 1, egenskab 2 ... egenskab n }
ul#element 2 { egenskab 1, egenskab 2 ... egenskab n }

f) Kombinere elementer med samme regler. For at undgå redundans skal man samle elementer med samme egenskaber:

div#element 1, p#element 2 { egenskab 1, egenskab 2 ... egenskab n }

Resume: Vær struktureret og konsekvent. Inddel i afsnit, et element pr. linje, sortere egenskaber alfabetisk, illustrer type på dit element og kombinere elementer med samme egenskaber.

5: Shortcase

Brug shortcase. Du kan formindske din kode betydeligt og derved få et bedre overblik. Et eksempel illustrer guleroden meget bedre:

div#element 1 { margin-bottom: 15px; margin-left: 5px; ...
                ... margin-right: 20px; margin-top: 10px; }

bliver til

div#element 1 { margin: 10px 20px 15px 5px; }

Du kan bruge shortcase hos følgende egenskaber; background, border, font, list, margin, outline og padding. Dustin Diaz har skrevet en fremragende guide til emnet.

Resume: Brug shortcase!

6: Spring mellemledet over

Som i den virkelige verden er det oftest bedst for forbrugeren, at mellemledet bliver fjernet, og det er det også hos CSS. Mellemledet er ofte ubrugeligt og fylder kun ekstra i dit stylesheet, hvorfor det skal fjernes. Der findes dog situationer, hvor du kan blive tvungen til at inkluderer det men som udgangspunkt; fjern det:

div#element ul li a span.class

bliver til

.class eller div#element .class hvis man har behov for at specificere det lidt

Resume: Undgå unødvendige elementer hos en regel!

7: Flere stylesheets

Det kan være en god ide at have flere mindre stylesheets end kun et samlet, specielt når man udvikler. Udover at det giver et bedre overblik, kan man også undgå at skulle indlæse alle regler på sider, de ikke vedkommer, og have muligheden for at overskrive en regel, som ellers ville forstyrre ens underside eller kræve ekstra og unødvendig markup.
Nogle deler desuden deres stylesheets op i selectors, hvorfor de har et til headers, et til links, et til billeder etc. men det er en smule overkill og gavner ikke just overskueligheden. Desuden resulterer det i en masse ekstra http-requests og dermed længere load time, medmindre man samler og eventuelt minify‘er sit stylesheet, inden man skubber det live. Igen skal opdelingen kun ske, når det giver mening og eventuelt kun i udviklingsøjeblikket.
Ved større projekter har jeg et generelt stylesheet, hvor der defineres de generelle regler inklusiv reset, og så et pr. underside med de specifikke regler. Selvfølgelig alle i et strutureret stylesheet.

Resume: Adskil i flere stylesheets, men kun når det giver mening!

8: !Hacks

Hold dig fra at bruge hacks! Hvad enten det er * hack, _ hack eller lignende. Brug i stedet Conditional Comments til fx at indsætte et Internet Explorer 6 specifikt stylesheet.

<!--[if IE 6]>
<link type="text/css" href="ie6styling.css" rel="stylesheet">
<![endif]-->

Resume: Undgå hacks, brug conditional comments i stedet.

9: Adskillelse

Markup og CSS er som Batman og Robin. De er fantastiske sammen, dog kan Batman fint klare sig alene, hvorimod Robin er ubrugelig uden Batman.
Man må aldrig begynde at sammensmelte markup og CSS og lave noget så uhyggeligt som inline styling. For at sikre fleksibilitet og overblik er det vigtigt at alt styling adskilles fra markup og kun styres fra sit stylesheet. Der er dog situationer, hvor inline-styling kan være eneste løsning, men brug det kun som sidste udvej, og ikke fordi du er doven.

Resume: Markup og CSS skal adskilles!

10: Divitus, classitis og idikus

Undgå at få divitus, classitis eller idikus. Generelt for alle 3 sygdomme er, at man overforbruger. Man kan sammenligne det med et sønderjysk kaffebord, hvor der minimum er 14 forskellige kager, 7 bløde og 7 hårde, hvilket er helt unødvendigt. Derimod ville 1-2 kager fra hver kategori have været rigeligt.
Divitus er når man bruger for mange div‘er. Mange nybegynder har en tendens til at smide en div rundt om alt:

<div id="mainHeader"><h1>Min overskift</h1></div>

Div‘en er ikke nødvendig, og man kan i stedet skrive

<h1>Min overskrift</h1>

og så style på h1 i stedet for #mainHeader.
Classitis og idikus minder meget om divitus:

<ul id="unsortedList">
  <li class="listItem">Item 1</li>
  <li class="listItem">Item 2</li>
  <li class="listItem">Item 3</li>
</ul>

Det er ikke nødvendigt at overklistre alle selectors med klasser og id’er:

<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>

Resume: Minimer dit markup!

11: Centrer med margin

Centrer med margin: 0 auto; i stedet for fx at hardkode en fast padding i venstre side. For at centrer med margin skal du definerer en bredde:

div#element { margin: 0 auto; width: 800px; }

Resume: Brug margin: 0 auto; til at centrer

12: Position og floats

Brug position og float rigtigt! Lær dem at kende, og brug dem når det passer ind. Lad være med at låse dig fast, hvor du kun bruger float eller position.

Resume: Brug position og float når det giver mening.

13: Vær doven

Sidste punkt som i øvrigt gælder programmering generelt er, at man skal være doven. Hvorfor opfinde den dybe tallerken igen og igen, når den nu er opfundet? Genbrug dine komponenter medmindre du ønsker eller mangler træning i at forstå eller lave dem.
Man støder på mange ens og lignende problemstillinger i CSS, hvorfor det vil være uhensigtsmæssigt, at skulle gennemtænke samt lave samme løsning gang på gang, og da man selvfølgelig har en strukturel navngivning, er det ikke noget problem at genbruge sin kode.

Resume: Genbrug dit veludviklet kode!

< SLUT / >

Det var mit bud på, hvordan man, ved hjælp af nogle simple principper, opnår bedre og mere overskueligt CSS. Vigtigst af alt er, at man er konsekvent hele vejen igennem og tro mod kode standarderne. Sammen kan vi gøre verden til et bedre sted. Kom gerne med en kommentar, hvad enten det er ris eller ros.