tirsdag den 3. juli 2012

Levere en god user experience på webben (med AJAX)


Jeg sad netop og tænkte på noget med hvordan man gerne vil lave sin side så den er hurtig og effektiv for brugerne, leverer en god oplevelse med at den ikke blinker eller man skal klikke en masse uden at have behov for det, og samtidigt vil man også gerne have at Google kan indeksere alt dit indhold således at der faktisk kan komme nogle brugere til din side.

Min tanke var et tænkt eksempel, men pludselig kom jeg til at stille mig selv en masse spørgsmål om hvordan man kunne løse det på en pæn brugbar måde som samtidigt var noget Google kunne indeksere og præsentere i sine søgeresultater.

For at levere en god user experience ville jeg starte med at levere en side med 10-20 produkter (eller hvad du nu end skal vise at content på din side - kan være referencer, personer, CV'er, opskrifter, you-name-it).
Når man så scroller ned af siden og når 90% ned så vil Javascript automatisk begynde at hente og indlæse de næste 10-20 resultater for at brugeren ikke skal trykke en masse eller gå til næste side, men blive på siden og få en lækker effektiv og hurtig oplevelse som de kan blive glade for.

Dette virker kun med javascript aktiveret, og problemet er at Google ikke kan afvikle dette og dermed ikke indeksere andet end det din side starter med at vise, hvilket jo ikke er ønskværdigt.

Min løsning efter nogle timers fumlen med flere forskellige løsninger og måder at løse dette på var at den bedste måde var både for brugere, Google og mig selv at lave det således:
Steps:
  1. Man starter med at lave en side der kan levere de 10-20 resultater lige så snart du går ind på siden.
  2. I bunden af disse resultater laver man en knap ("Load more") der sender dig til en ny url som leverer flere resultater.
  3. Man bygger javascript ovenpå der via AJAX kan hente flere data når man er kommet 90% ned på siden. Denne skjuler samtidig den knap for enden af siden.
  4. Javascript modtager de nye data og putter dem ind på siden og viser knappen igen og man kan således scrolle længere ned på siden.
  5. Man indbygger en fail-safe således at når man har fået automatisk loadet x sider så skal man aktivt trykke på knappen for at få loadet flere data, da jeg har oplevet at nogle gange så kan man komme i en situation hvor du altid vil få vist 90% af siden på skærmen og dermed vil din browser nu begynde at blive ved med at loade og loade og loade for evigt indtil der ikke er mere at hente og brugeren kan ikke stoppe det. Dette er ikke en situation man ønsker at være i.
  6. Man bygger nu ovenpå noget javascript som sætter et checkpoint i din browseres historik, og som kan ændre din URL således at når du får vist 60 resultater på din skærm skal du kunne sende dette til en ven og han får vist de samme 60 resultater på sin skærm også. Godt nok vil serveren levere dem til ham når siden vises første gang, hvor du ville ha fået dem lazy-loadet efter at have scrollet ned, men i sidste ende er resultatet det samme.
Det gode ved dette er at den knap for enden af din side vil gøre at Google vil kunne klikke på den knap og få samme resultat vist og indeksere dem selvom deres crawler ikke virker med Javascript og kan få det leveret på den smarte effektive og lækre måde, men de links som Google vil levere vil stadig give det samme for dig når du går ind på dem og have alt dit indhold som det skal.

Et lille eksempel:
Du har en side kaldet DetBedsteIVerden.dk og vil gerne have vist nogle produkter på denne side.  
Dette eksempel bygger udelukkende på ASP.NET MVC.
Step 1: Lave en Controller der kan vise produkter.
Denne skal hedde ProductController, og have et view tilknyttet sin Index() action. Her kan du levere de 20 første produkter som du ønsker at vise på siden.
Dermed kan du nu skrive DetBedstIVerden.dk/Products/
Step 2: Håndtere flere sider.
Nu skal du så udbygge din Controller (ProductController) således den kan håndtere flere sider end kun din nuværende /Products/ som leverer de 20 første produkter.
Dermed skal du lave en ny action kaldet Side og som tager en int som parameter og som er nullable. Nullable kan man gøre ting ved at putte et spørgsmålstegn bagved en type.
Den skal dermed se ud som følger:

public ActionResult Side(int? pagenumber)
        {
            int numberOfResults = 20;
            if (pagenumber.HasValue)
                numberOfResults = numberOfResults * pagenumber.Value;
            return View();
        }
Nu vil du nu kunne skrive: DetBedstIVerden.dk/Products/Side/2

Ovenstående gør at fra standart af vil der ikke stå "Products/Side/1" og pagenumber vil dermed være null, og derfor har vi en default value på 20 som sættes, og hvis der kaldes "Products/Side/1" eller "Products/Side/2" vil denne action nu give et højere antal resultater tilbage - selvfølgelig forudsagt at dit view bruger dette (eventuelt leveret igennem model eller ViewBag-objektet).

Step 3: Lave interaktion for brugeren.
Lige nu kan brugeren gå til side 2 hvis han vil ændre URL'en og tilføje "/Products/Side/" og så det nummer han vil til - det er ikke brugbart.
Så i bunden af siden laver du en knap der kalder næste side.
Step 4: Effektificere dataoverførsel og få en hurtigere side
Da vi nu har lavet knappen kan brugeren nu se alle dine forskellige produkter uden at ændre URL'en. Desværre gør dette at brugeren ret hurtigt skal klikke ret meget (for hver 20 resultat), og serveren skal arbejde ret meget for at levere de samme resultater som før, og så de næste 20 oveni (side 2 har de 20 første fra side 1 og 20 næste fra side 2), plus at brugeren får ikke en god oplevelse ud af at udføre en POST og reloader hele siden igen hver gang de trykker på knappen. Derudover bliver dette også langsommere fordi din side skal hentes med alt igen (alle billeder og andet data ud over dit skiftede indhold), og så skal browseren til at rendere dette igen hver gang du trykker på knappen.

For at effektificere dataoverførselen kan vi derfor sørge for at det eneste der skal sendes er det som der er behov for og som skal ændres - altså de nye data.
Dette kan man gøre med noget AJAX via Javascript som kan hente det nye indhold og kan indsætte dette på vores side. Dette gør at du reelt kun henter de nye data og dermed gør at din side bliver langt mere effektiv da du ikke får at der skal hentes andet end content og det er det vi gerne vil have.

Man kan sikre sig at siden vil virke både med javascript aktiveret og også uden. Ved at du når siden leveres laves til at din knap virker uden javascript kan man via JavaScript ændre dette således at når man klikker på knappen så udfører noget AJAX i stedet. Således at hvis JavaScript ikke virker vil den ikke ændre hvad der sker når man klikker på knappen, men hvis det er aktiveret vil det ændre hvordan tingene skal udføres.

Step 5: Lazy load og god user experience
Det med at brugeren skal trykke på knappen for hver 20 resultater gør at brugeren skal interagere meget med siden for at få det resultat de ønsker.
Så i stedet for at at brugeren skal klikke på en knap hele tiden for at se det indhold din side leverer, hvilket ikke giver brugeren en god brugeroplevelse og user experience.
Dermed vil vi gerne sørge for at javascript automatisk vil udføre det som knappen gør automatisk når man kommer 90% ned på siden, med en lille twist som gør at når siden har gjort dette x antal gange så skal man aktivt trykke på knappen.
Dette er ligesom Google's billedsøgning, og er fordi at der er tilfælde i skærmstørrelse der gør at du hele tiden vil få vist 90% af siden på din skærm så snart den loades og dermed ville gå i en dead-lock og blive ved med automatisk at loade de næste resultater indtil der ikke er flere uden at brugeren kan stoppe dette.
Det er ikke et scenarie man vil udsætte sine brugere for uanset hvad er det slet ikke god brugeroplevelse og user experience.

Efter disse steps har man en side der fungerer med og uden javascript, som er effektiv i datatransport og som er hurtig som Google er glad for samtidigt med dine brugere, Google kan indeksere den og sørge for at brugerne får en god fornemmelse fordi siden er effektiv og smart så de ikke skal trykke og interagere med siden hele tiden for at udføre det formål siden har.

Ingen kommentarer:

Send en kommentar

Kan du lide mit indlæg, har en kommentar, forslag eller andet på hjerte så skriv venligst