Vorig jaar startte Aviva Solutions met het ontwikkelen van Mercury e-commerce, een generieke e-commerce oplossing op basis van Sitecore & Commerce Server. Over de jaren heen deden wij al veel ervaring op met het realiseren van e-commerce oplossingen. En één van de verbeterpunten voor e-commercesites was een intensiever gebruik van front-end technologieën in combinatie met de kracht van de browser. Hiervoor moesten we op zoek naar een geschikte front-end technologie. Na een grondige analyse kozen we uiteindelijk voor React van Facebook.
React
React is een Javascript framework voor het ontwikkelen van user interfaces. Dit framework is ontwikkeld door Facebook en heeft de afgelopen tijd ontzettend veel momentum gekregen. De eerste versie van React werd als open source vrijgegeven in 2013 en wordt tegenwoordig gebruikt door sites als Netflix, AirBNB, Twitter en natuurlijk Facebook zelf. Waarom kiezen steeds meer grote sites voor React?
Onafhankelijke en herbruikbare componenten
In tegenstelling tot veel Javascript frameworks zoals Angular en Ember, richt React zich alleen op het View deel van MVC. In MVC is de logica verdeeld over een Model, View en een Controller. Het model vertegenwoordigt de data, de controller bevat de logica die acties doet op het model (zoals het ophalen hiervan) en de view vertaalt in het model een presentatie. In dit geval is dat de HTML. Daarnaast bieden frameworks zoals Ember en Angular allerlei andere faciliteiten zoals Dependency Injection, services voor communicatie met de server enzovoort.
React richt zich zoals gezegd alleen op het View aspect van MVC. De views worden in React geïmplementeerd door middel van componenten, waarbij een component niets anders doet dan het transformeren van data naar HTML. In MVC-frameworks worden de logica en de markup gescheiden. De logica zit namelijk in de controller en de markup wordt vaak geïmplementeerd door middel van templates. Volgens de React filosofie zijn deze echter te sterk aan elkaar gekoppeld en horen deze dus bij elkaar. Doordat zowel de logica als de markup in het component zitten, hebben de componenten in principe geen andere afhankelijkheden dan de data die zij transformeren en zijn zij dus uitstekend herbruikbaar.
Eenvoudige updates
Het doen van updates is één van de zaken die user interfaces zo complex maken. Denk aan updates zoals het verwijderen of toevoegen van een record in een lijst. Met React hoeft de ontwikkelaar zich hier geen zorgen over te maken. Wanneer het record namelijk wordt toegevoegd of verwijderd uit de data zal React dit detecteren en zichzelf opnieuw renderen. De ontwikkelaar hoeft alleen de logica te schrijven voor het presenteren van de complete lijst en wijzigingen alleen te doen op de onderliggende data.
Normaal gesproken zijn dit soort operaties in de browser echter heel duur en zou dit performance problemen opleveren. React heeft hier echter wat slims op bedacht, waarover meer in de volgende paragraaf. Dit geeft wel aan hoe makkelijk React bepaalde complexe operaties voor de ontwikkelaar maakt. En dit is nou precies de reden waarom ontwikkelaars graag met React werken.
Geen performance problemen door virtuele DOM
De Document Object Model (DOM) is de Javascript API waarmee je een HTML pagina aan kunt passen. De DOM is echter regelmatig de performance bottleneck van Javascript applicaties. Dit komt vooral doordat er inefficiënt gebruik van wordt gemaakt. Zeker omdat React bij elke wijziging alles opnieuw rendert met behulp van de DOM, zou dit gigantische performance problemen moeten veroorzaken. React heeft hier echter wat handigs voor verzonnen, namelijk een virtuele DOM. Deze verzamelt alle DOM wijzigingen, vergelijkt deze met de vorige versie en voert alleen de noodzakelijke DOM bewerkingen uit. In één bewerking. Deze virtuele DOM heeft nog een ander voordeel, de componenten kunnen namelijk ook op de server uitgevoerd worden!
Zowel op client als op server
React is ‘Isomorphic’. Dit is een nieuw buzzword in de Javascript wereld en betekent dat zowel de client als de server het kunnen gebruiken. Deze nogal onconventionele methode zorgt ervoor dat de javascript componenten op de server uitgevoerd worden en de server initieel al HTML naar de browser stuurt. Dit heeft als voordeel dat de HTML doorzoekbaar is door zoekmachines. Zoekmachines kunnen tegenwoordig al steeds beter javascript interpreteren, maar toch is dit nog geen best practise.
Een ander voordeel is dat dit de zogenaamde Flash Of Unstyled Content (FOUC) voorkomt. FOUC is het fenomeen waarbij er eerst een flikkering is waarin een onopgemaakte pagina wordt getoond. Dit komt doordat de client eerst onopgemaakte HTML binnen krijgt, pas daarna wordt de javascript uitgevoerd die de pagina opmaakt. Zeker op tragere machines zoals mobile devices is dit een probleem.
Sitecore
Sitecore is het content management systeem waarop Mercury is gebaseerd. Om te begrijpen waarom we nu uiteindelijk voor React hebben gekozen, zal ik eerst een beeld schetsen van de technische werkwijze van Sitecore.
Alles is een item
Sitecore is vooral data georiënteerd. Als je de content-editor van Sitecore opent, dan zie je een hiërarchische boom van items. Items zijn weer gebaseerd op templates en een template is ook weer een item. Volg je het nog? Templates zijn de blauwdruk voor een item en definiëren de velden van het item. Per item kun je vervolgens definiëren hoe je deze wilt presenteren.
Presentatie
Voor de presentatie van een item kun je een layout kiezen en een set van renderings. Een layout definieert de globale opmaak (HTML) van de pagina. Binnen deze layout bevinden zich zogenaamde placeholders. Dit zijn in de HTML gedefinieerde locaties waarin renderings worden geplaatst. Een rendering bevat de presentatie logica die data transformeert naar HTML. In afbeelding 1 zie je bijvoorbeeld een pagina met twee renderings: FullPage & Wishlist. FullPage is geplaatst in de body placeholder. FullPage bevat zelf ook weer een placeholder, namelijk content, waarin de Wishlist rendering wordt geplaatst.
Wanneer je een rendering toevoegt aan de pagina, kun je een in een scherm zien hoe de rendering wordt geconfigureerd. Renderings zijn dus configureerbaar en herbruikbaar. Nu we weten hoe Sitecore in grote lijnen werkt, kijken we waarom React hier zo goed bij past.
Sitecore <3 React
Sitecore renderings transformeren data naar HTML. Als we kijken naar MVC javascript frameworks dan zit de logica hiervoor in de view en de controller. In afbeelding 2 zie je hoe dit samenwerkt. De gebruiker heeft interactie met de view, de view geeft dit door aan de controller en de controller communiceert eventueel met de server om data op te halen. Daarna geeft de server dit weer terug aan de view in de vorm van een model. Hier komen dus meerdere objecten bij kijken. In het geval van een Sitecore rendering hebben we de data al en dus moeten we die op de een of andere manier in de controller krijgen. Uiteindelijk kun je dit met allerlei hacks wel aan de praat krijgen, maar de concepten passen niet lekker.
Als we kijken naar React dan heeft een React component eigenlijk precies dezelfde verantwoordelijkheid als een Sitecore rendering: het transformeren van data naar HTML. En in het geval van een React component zijn er geen andere afhankelijkheden, we hoeven dus alleen dit component aan te spreken met de data die we al hebben. In Mercury ziet dit er dan ook als volgt uit:
@Html.React ("Mercury.components.RecentlyViewedProducts", Model.Products)
Hier roepen we een specifieke React component uit voor het renderen van recent bekeken producten en geven de lijst van recent bekeken producten mee. Het React component transformeert deze producten vervolgens in de gewenste HTML. Meer code zit er niet in de Sitecore rendering. In Mercury zijn de renderings dan over het algemeen alleen maar doorgeefluiken naar de React componenten. En bevatten ze doorgaans niet meer dan enkele regels code.
Bovendien zijn Sitecore websites over het algemeen front-facing websites, waarbij search engine optimization (SEO) en performance een belangrijke rol spelen. Met het open source project ReactJS.net kun je de React componenten zeer eenvoudig op de server uitvoeren, waarbij de website ondanks de complexe UI toch performant en volledig geoptimaliseerd voor zoekmachines kan zijn.
Rozengeur en maneschijn
Alhoewel de combinatie van Sitecore en React een hoop voordelen met zich meebrengt, zijn er natuurlijk wel wat aandachtspunten. Zo is de learning curve van React vrij hoog. Het kost vaak wat tijd voordat mensen de React filosofie begrijpen, wat nodig is om op een goede manier React componenten te schrijven. Ook is het serverside debuggen van javascript errors erg lastig. Op dit moment is hier nog geen goede tooling voor en moet je het doen met een stack trace. Wij ontwikkelen de Mercury componenten in een apart UI project waarbij we ze rechtstreeks testen in de browser. Hierdoor zien we bijna geen server-side Javascript fouten.
Conclusie
Tegenwoordig wordt er steeds meer verwacht van de user experience van websites. Hiervoor is het gebruik van moderne Javascript frameworks onontkoombaar. React componenten zijn uitermate geschikt voor het implementeren van Sitecore renderings. Dankzij de mogelijkheid om de componenten ook op de server te renderen, is er geen negatieve invloed op de SEO-waarden van je site.
Ook voorkom je de zogenaamde Flash of Unstyled Content waardoor de site performant blijft, zelfs op mobile devices. Hou er wel rekening mee dat React ook de nodige learning curve en complexiteit met zich meebrengt. Als een site geen complexe UI nodig heeft, zou ik dan ook niet adviseren om React te gebruiken. Is er echter wel een complexe UI nodig, dan lijkt React me op dit moment te beste keuze voor het Sitecore platform.
Verder praten over deze technologie?
Of ben je benieuwd wat wij voor je kunnen betekenen? Bel ons op 071 710 74 74 of stuur mij een mailtje (jonne.kats@avivasolutions.nl).