Twee jaar geleden herschreef Facebook hun mobiele apps voor iOS en Android. In plaats van een aparte ontwikkelomgeving, werden ook de mobiele applicaties nu in de ‘native’ omgeving geplaatst, waardoor er meer controle kwam over hoe en wanneer items gedownload werden, gecached en weer vrijgemaakt. Het gaf ook toegang tot diepere integratie in de operating systems waardoor de app volledig getuned kon worden voor het device waar deze op speelde.
Testen is een belangrijk onderdeel van de ontwikkeling van Facebook, maar met de switch naar deze native omgeving was het niet langer meer mogelijk om te A/B-testen. Niet iedere test die opgezet wordt, wordt ook daadwerkelijk uitgevoerd, maar zelfs gefaalde tests helpt Facebook om te begrijpen hoe te verbeteren. Het niet langer meer kunnen testen werd dan ook een uitdaging.
A/B testing
Om de apps voor iOS en Android te kunnen uitbrengen moeten ontwikkelaars van vele verschillende teams elke vier weken een nieuwe binary met nieuwe features en bug fixes coördineren en uitbrengen. Als de update uit is, is het belangrijk om te begrijpen:
- Hoe nieuwe features presteren;
- Hoe de fixes de prestaties en betrouwbaarheid verbeteren;
- Hoe verbeteringen aan de user interface het gedrag van mensen veranderen in hoe zij de app gebruiken en waar zij hun tijd besteden.
Om deze doelen te analyseren, had het team van Facebook een mobiele A/B-test infrastructuur nodig die hun gebruikers verschillende versies van hun app zou tonen. Om dit te kunnen doen creëerden ze Airlock, een test framework dat het mogelijk maakt om metrische data van elke versie van de app en verschillende tests te vergelijken en dan te beslissen welke versie de beste is, of hoe verder te testen.
Van de grond af opgebouwd
Ze begonnen met het simpelst mogelijke experiment: ze veranderden het chat icoon voor het uitgeschreven woord “Chat”. Wanneer de app opstartte, werd een netwerk request verzonden naar de servers met het verzoek om de parameters voor dat experiment. Wanneer de reactie terug kwam werd de knop geupdate en hadden sommige medewerkers een icoontje, en anderen enkel het woord “chat”. De verwachting was dat het alleen effect zou hebben op aantal berichten dat verzonden zou worden, en dan niet eens met heel veel. Er was geen verwachting dat andere metrics ook beïnvloed zouden worden.
Het loggen van de data
Toen deze versie van de app eenmaal live ging voor het publiek, was het wachten op de data om te stabiliseren. De data liet zien dat mensen die het woord “chat” zagen veel meer engaged waren met de app. Had Facebook een geheim ontdekt? Helaas voor hun, nee. Ze hadden te maken met een enorm aantal bugs, waar het grootste probleem was dat een van de vele componenten de waardes incorrect cachete. Met een systeem zo groot als dit moest de infrastructuur solide zijn, anders was de verzamelde data nutteloos.
De data pijplijn begon met de server die besliste welke variant een bepaald persoon kreeg. Die waarde moest dan ingepakt worden en naar het device gezonden worden, welke dan ook weer de reactie opsloeg. Deze waarde werd dan gebruikt om de user interface the herconfigureren en dan was het resultaat eindelijk op het scherm te zien. Het probleem was dat het ontwikkelteam voor hun data analyse te veel vertrouwde op de categorisatie van de server. Één enkele bug leidde er toe dat een groot aantal mensen een andere variant te zien kregen dan was geanticipeerd. De server bleef volhouden dat het signaal goed verzonden was, maar wat daarna gebeurde werd snel onduidelijk (een bug aan de client side).
Inzetgrafiek van een experiment
De bovenstaande rgafiek laat zien hoe een experiment was ingezet. De lichtgroene balk is het aantal mensen dat met het experiment meedeed, en de donkergroene balk is het aantal mensen dat daadwerkelijk een variant te zien kreeg. Zoals je kunt zien is het verschil tussen de data van de server en van de devices aardig groot: op de eerste dag ontvingen de meeste mensen de configuratie, maar zagen de meeste gebruikers het experiment niet.
Dit probleem valt samen met het probleem dat je niet alleen moet bedenken wat het device verteld is, maar dat de data analisten ook moeten weten wanneer het device deze informatie ontvangt en of de veranderingen goed worden weergegeven. Zelfs als de informatie correct ontvangen wordt, is er een vertraging, gedurende welke tijd de user interface incorrect is. Dit werd opgelost door een ‘two-way handshake’ toe te voegen. Het device doet een verzoek voor de data voor een experiment en de server logt de response die het uitzendt. Wanneer de client de data ook daadwerkelijk gebruikt, wordt dit op de server gelogd. Zo kan, zelfs als iemand niet ziet wat je als analist wilt, je toch nog een correcte analyse uitvoeren.
Opschalen
Gedurende een aantal maanden moest het systeem opgeschaald worden van twee experimenten, tot het ondersteunen van vele experimenten door de hele app heen. Het experiment dat de evolutie van Airlock aanjaagde was een project dat Facebook begonnen was met de intentie om het navigatiemodel binnen hun apps te evolueren en te simplificeren. In die paar maanden experimenteerden ze ondermeer met het smaller maken van het linkermenu door alleen icoontjes te gebruiken, een tab-balk onderaan het scherm plaatsen met de timeline, het combineren van friend requests en notificaties in één tab in een tab-balk, om uiteindelijk te komen tot het tab-balk design van de huidige Facebook iPhone app. Ze hebben verschillende versies van een user interface gemaakt die uiteindelijk niet gebruikt worden, maar dat is nu eenmaal wat er gebeurt met testen.
Het bouwen van Airlock heeft Facebook geholpen om een navigatiemodel te vinden dat afgewerkter aanvoelt, makkelijker te gebruiken is met een hand en beter je status bijhoudt in de app. Deze tool gaf ze de mogelijkheid om het framework te schalen om 10 of 15 verschillende variaties in een enkel experiment te ondersteunen en het op miljoenen gebruikers te testen. Ze moesten de regels opnieuw leren dat ze niet een experiment het andere lieten vervuilen, waar sommige experimenten afhankelijk waren en anderen exclusief. Ze moesten ook opnieuw leren dat de data correct gelogd werd in de controle groep, wat lastig was omdat een controle groep soms betekend dat een bepaalde gedeelte van de user interfacte niet bestaat. Hoe log je dat iemand niet naar een plek ging die niet bestaat? Ze leerden dat je in zo’n geval zowel de keuze voor de user interface moet loggen, en daarnaast de interactie met de UI.
Terwijl het framework geschaald werd om meer experimenten te ondersteunen, begon het aantal parameters requests, data logging en client-side berekeningen heel snel toe te nemen. Het framework moest snel op de client draaien om de experimenten klaar te hebben zonder dat dit het opstartproces in de weg zat. De keuze werd gemaakt om de prestaties vanuit een koude start te verbeteren zodat de kritische basisconfiguraties geladen konden werden tijdens het opstarten, en het zwaardere werk pas werd opgepakt als de UI van de app werd getoond. Ook de interactie tussen het device en de server moest afgesteld worden zodat de data flow en de data die aan beide kanten verwerkt moest worden geminimaliseerd werd.
Airlock heeft het voor Facebook mogelijk gemaakt om in een native omgeving te testen en de apps sneller dan ooit te verbeteren. Met de vrijheid om te testen, hertesten en de resultaten te evalueren, kunnen er steeds betere tests en gebruikerservaringen gebouwd worden.