Webontwikkeling vroeger
Vroeger was het web een stuk simpeler. Websites bestonden grotendeels uit enkel HTML en afbeeldingen. Had je een gaaf menu nodig voor je site, was dit waarschijnlijk een afbeelding met daarop klikbare onderdelen. Wilde je graag een agenda tonen op een pagina, was dit waarschijnlijk een tabel. Alles bestond uit tabellen. Een animatie? Dat was een .gifje. De meeste sites hadden niet eens dynamische content via een database, laat staan een uitgebreid CMS zoals WordPress.
Deze (inmiddels archaïsche) manier van webontwikkeling had wel één groot voordeel: snelheid. Als je geen tientallen libraries en foefjes hoeft in te laden maar alleen een paar kilobytes aan HTML naar de gebruiker hoeft te sturen, is de website bijzonder snel geladen.
Webpagina’s worden steeds groter.
Bron: HTTP Archive, 2017; Pinto, 2015; Tech Attitude, 2010
Webontwikkeling nu
Nu zijn CSS en JavaScript niet meer weg te denken uit de web wereld. Animaties werken met CSS, pagina-layouts worden gemaakt met CSS, en zelfs afbeeldingen kunnen met pure CSS gemaakt worden. Webapplicaties zijn tegenwoordig tientallen keren fancier en sturen meer data over en weer. En dan hebben we het nog niet eens over JavaScript, wat tegenwoordig de basis is van bijna iedere SaaS oplossing. JavaScript is dé basis van het afhandelen van logica aan de kant van de gebruiker (client-side).
Hier enkele voorbeelden van bekende SaaS producten en waar ze op ontwikkeld zijn:
- Spotify: Electron (JavaScript)
- Discord: Electron (JavaScript)
- Facebook: React (JavaScript)
- Netflix: React (JavaScript)
- AirBnB: React (JavaScript)
- …
We hebben het geluk dat technologie niet heeft stil gestaan, en dat de snelheid van het internet met een factor van 1000x beter is geworden in de tijdspanne van zo’n 20 jaar. Toch blijft snelheid een erg belangrijk punt op het web. Is je website langzamer, worden gebruikers eerder gefrustreerd en zullen ze je verlaten voor een snellere concurrent. Bovendien geeft Google je een hogere positie in de zoekresultaten als je site snel is. Érg belangrijk dus.
Een online platform als AirBnB ziet er gaaf uit, maar op de achtergrond is de homepage goed voor meer dan 8MB aan data, of 323 verzoeken naar de webserver. Daarvan zijn er ongeveer 100 JavaScript bestanden. Dat is best veel, als je bedenkt dat oude(re) websites vaak niet eens boven 1MB uit kwamen. Dus, hoe houden we een SaaS oplossing op deze manier snel?
Tips voor een razendsnelle SaaS oplossing
1. Denk na over de structuur van de code
Bij het opzetten van een SaaS oplossing is het dus erg belangrijk om de performance in acht te nemen. Dit gaat van micro-optimalisaties zoals het hergebruiken van variabelen (data) i.p.v. deze keer op keer te herinitialiseren, tot slim nadenken hoe je database structuur in elkaar zet om het aantal queries zo laag mogelijk te houden.
Database calls
Als voorbeeld: stel je bouwt een simpel forum waarop gebruikers met elkaar kunnen discussiëren. Om de hoofdpagina aan je gebruikers te kunnen tonen moet je ten minste een lijst hebben van categorieën en de bijbehorende posts. Ga je eerst alle categorieën ophalen, en dan per categorie de bijbehorende posts? Of alle categorieën in één keer, met alleen de titels van de meest recente posts? Of zelfs categorieën non-dynamisch maken, zodat dit niet eens langs de database laag hoeft te gaan. Deze vraag heeft geen globaal antwoord, de uiteindelijke keuze die je maakt hangt af van wat jij wil tonen aan je gebruikers. Hoe minder data(base calls), hoe beter.
Design patterns
Een ander voorbeeld is het singleton patroon. Een design pattern betekent simpel gezegd een patroon (methode) om een stuk code te designen. In het geval van singleton betekent dat dat je een klasse of functie éénmalig aanmaakt, en dat deze vervolgens overal in de code hergebruikt kan worden. Hier kunnen meerdere redenen voor zijn, waaronder snelheid. Als je bijvoorbeeld iedere minuut moet verbinden met een externe API voor het ophalen van data – ga je dan steeds dezelfde authenticatiestappen door, of doe je dit eenmalig en hergebruik je dat iedere keer?
Server-side vs client-side
Nog een afweging om hierin te maken is server-side vs client-side. Als je berekeningen client-side (in de browser van de gebruiker) afhandelt, betekent dit minder hoeven wachten op de server, en het internet. Zijn die berekeningen te zwaar, dan wordt de hele browser van de gebruiker langzaam (of zelfs de hele computer). De keuze om hier te maken is dus: kan een oude PC deze logica aan, of moeten we dit naar de server trekken?
Dit zijn maar enkele voorbeelden van de zaken waar je over na moet denken als je een SaaS oplossing ontwikkelt. De kern blijft: zo min mogelijk database requests, zo min mogelijk data over en weer sturen.
2. Maak gebruik van caching
Een van de belangrijkste en grootste gamechangers is caching. Caching is simpel gezegd een opslag-laag waarin data wordt gezet, zodat deze een volgende keer sneller aan de gebruiker kan worden gegeven. Zie het als een helpdesk: kom je met een vraag die ze niet eerder hebben gehad, moet er over nagedacht worden en volgt er misschien zelfs een verzoek naar een collega. Stel je een vraag die ze net nog beantwoord hebben voor een andere klant, dan hebben ze hetzelfde antwoord al klaar liggen. Zij kunnen dan verder met andere vragen, en jij bent razendsnel geholpen.
Hier zijn enorm veel manieren voor, dus ik zal de focus leggen op de technieken die wij bij Scrumble gebruiken om onze applicaties vliegensvlug op jouw scherm te krijgen.
OPCache
Dit zit ingebouwd in PHP (en dus Laravel), en hoeven we niet veel voor te doen om op te zetten. De werking is simpel, wanneer een (non-dynamisch) script wordt uitgevoerd, slaat OPCache het op in de cache. De eerstvolgende keer dat het script weer aangeroepen wordt, hoeft hij minder te berekenen omdat hij het rechtstreeks uit de cache kan halen.
Browser cache
Iedere keer als je browser een bestand ophaalt, zoals een afbeelding of een JavaScript bestand, vraagt hij hoe lang hij deze mag onthouden. Wij geven aan dat hij deze maximaal X uur mag onthouden, en de volgende keer dat je de site bezoekt hoeft je browser dit niet eens van de server op te vragen maar laadt hij het vanaf je eigen computer in.
Redis
Zoals al kort belicht zijn database calls een belangrijke factor in de performance van je SaaS oplossing. Hoe minder hoe beter. Een manier om dit in je (Laravel) applicatie nog verder toe te passen, is via Redis caching. Data die niet 100% realtime hoeft te zijn, kun je dan bijvoorbeeld cachen. Dit werkt simpel: zit het nog niet in de cache, haal het dan op uit de database. Geef anders de data die in je Redis cache stond. Oh, en Redis is snel.
Echt snel.
Bron: ByteRot
3. Implementeer een CDN
Deze hangt een beetje samen met de caching in ons geval. Een CDN staat voor Content Delivery Network. Dit zorgt ervoor dat jouw content (afbeeldingen, HTML, JavaScript, alles) zo snel mogelijk aan de gebruiker geleverd kan worden, over de hele wereld. Stel je website draait vanaf één server, die in Amsterdam staat. Dan zal een bezoeker uit Amerika dus eerst een verzoek moeten sturen naar Amsterdam, en wanneer de server het heeft verwerkt, de data weer helemaal terug sturen. Het internet is snel maar niet instant, en hoe groter de afstand hoe langzamer.
Wij gebruiken hiervoor CloudFlare (grote fans!). CloudFlare doet een aantal dingen voor ons:
- Minification en compression: het verkleinen van alle bronbestanden zodat er minder data over en weer gestuurd hoeft te worden.
- Caching: als iemand een keer content heeft opgevraagd, slaat CloudFlare deze op, en de volgende gebruiker heeft de content een stukje sneller.
- CDN: niet alleen mensen in de buurt van onze servers kunnen snel de content opvragen, maar juist mensen over de hele wereld.
Minified code (bovenste) is totaal onleesbaar, maar zorgt voor veel kleinere bestanden. Bron: TILCode