Word beter in Javascript: 4 extra tips vanop React Amsterdam

Op door Thorr Stevens

Het React-ecosysteem is omvangrijk. Dat blijkt na het bezoek van Thorr & Nico aan React.js Amsterdam. Daarom delen ze nog 4 extra tips om je React skills naar ‘the next level’ te brengen.

Begrijp de abstracties die je dagelijks gebruikt

Hoe word je beter in het gebruiken van een tool of framework, zoals React.js? Met "Requisite React", een talk door Kent C. Dodds, kregen we een beter inzicht in wat er precies voor ons geabstrageerd wordt.

Er zijn verschillende manieren om dit te doen. Om te weten wat React voor ons under the hood doet, kunnen we dit gemakkelijk nagaan door te experimenteren met hoe Babel deze transpiled:

Transpile door Babel

Kent benadrukte dat het minstens even belangrijk is om de fundamenten te verstaan. Je kan dan beter afwegen of een bepaalde abstractie echt een meerwaarde biedt of niet. Een paar voorbeelden:

  • JQuery heeft tegenwoordig weinig nut aangezien de meeste features intussen door alle browsers in Vanilla js ondersteund worden.

  • Het heeft geen zin om Lodash / Underscore toe te voegen als je er maar 1 of 2 functies van gebruikt.

Bij Marlon streven we ernaar om, waar het kan, zelf een utility te schrijven en geen npm package te downloaden. Zo worden we als team en als bedrijf beter in het gebruik van Javascript. Er zijn natuurlijk gevallen waar dit niet zo evident is, maar dan krijgen we de tijd om die abstractie verder te bestuderen, zoals bv. tijdens een bezoek aan een React-conferentie.

Het resultaat? Code die zoveel mogelijk in eigen handen is en geschreven of gebruikt wordt door mensen die een diepere kennis hebben. We denken hierbij aan developers die makkelijker een eigen abstractielaag kunnen bedenken. Kent’s talk heeft ons getoond dat we zeker goed zitten met onze aanpak.
 

Vermijd pitfalls en performance problemen met serverside rendering

Håkon Gullord Krogh wierp een licht op de mogelijke ‘Uncanny Valley’ die zich kan voordoen bij React server side rendered pagina’s. Eén van de voordelen van SSR mag dan wel zijn dat de ‘time to first meaningful paint’ sneller bereikt wordt, maar doordat de React bundle ingeladen moet zijn om interactie te voorzien, kan er een timeframe ontstaan waarbij buttons zichtbaar zijn, maar nog niet werken. En dat kan een groter probleem vormen dan langer wachten op je pagina. Gebruikers zouden kunnen denken dat de pagina of website defect is en afhaken.

Een mogelijke oplossing is dat je alles wat aan de serverkant kan gebeuren, ook daar laat gebeuren. Is dat niet mogelijk? Dan kan code splitting per pagina ervoor zorgen dat de tijd in de ‘Uncanny valley’ verminderd wordt. Maar je zorgt er best voor dat buttons en dergelijke nog niet volledig interactief lijken tot de interacties effectief beschikbaar zijn.

Server side rendering

David Mark Clements had het over het versnellen van het server side renderen zelf. React SSR gebeurt dankzij Node, waarbij de enige Javascript thread geblokkeerd kan raken als er te veel requests/seconde zijn, wat kan leiden tot problemen zoals een servercrash. Conclusie? Hoe sneller je SSR afgehandeld wordt, hoe stabieler de server draait.

Het versnellen van SSR kan volgens David gebeuren dankzij esx, een tagged template literal die tegengaat dat React de volledige object tree gaat opbouwen, wanneer we eigenlijk enkel maar de stringified html representatie van het component nodig hebben. Zo hou je de "tree" zo goed als plat in plaats van diep genest in elkaar, wat een enorme performance boost kan betekenen.

esx kan voorlopig enkel gebruikt worden vanaf React versie 16.8 en Node v10. Het project staat ook nog wat in zijn kinderschoenen en wordt dus nog niet wijd verspreid. Dus zeker iets om in het oog te houden!

Weet wat niet te delen bij cross platform React & React Native apps

In "Sharing Code Between React and React-Native: What Not to Share" doorliep Ben Ellerby het traject dat zijn team, samen met MADE.COM, heeft afgelegd om hun website uit te breiden van web naar iOS en Android aan de hand van React Native.

Ben gaat vooral in op de verschillende types code die er bestaan binnen een project en welke al dan niet deelbaar zijn.

UI code

De views met de render methodes van een component zijn de grootste boosdoener in shared platform codebases. Zo zijn zaken als een <div> niet hetzelfde als een <View/> en staat ook een <ul/> niet 1 op 1 gelijk met React Natives <FlatList/>. React en React Native hebben verschillende render omgevingen. Er zijn projecten zoals React Native Web (Twitter), ReactXP (Microsoft) en styled-components/universal die UI code delen makkelijker willen maken. Elk heeft echter zijn minpunten. Zo zijn deze oplossingen niet altijd even intuïtief of ideaal om serverside te renderen.

Na veel Proof of Concepts heeft Bens team dan ook beslist om dit gedeelte toch apart te houden. Web, mobile en desktop apps hebben elk hun eigen specifieke design patronen en user experiences die gerespecteerd moeten worden.
 
 
 

Controller files

Controller files, het deel van de componenten met de business logica, kunnen het makkelijkst gedeeld worden. Hou er wel rekening mee dat er Platform specifieke API's bestaan. Deze hoeven dus niet persé op dezelfde manier te werken. In de gevallen waarbij je je controllers toch opsplitst, kan een groot deel van de logica nog steeds gedeeld worden aan de hand van Higher Order Components of de iets nieuwere React Hooks.

Code sharing

Configuratie files

Configuratie files, met bijvoorbeeld constanten, vertalingen en API endpoints, kunnen meestal ook zonder problemen gedeeld worden tussen React & React Native-projecten. Hoe de API zelf opgeroepen wordt, of dit nu aan de hand van GraphQL of REST gebeurt, doet er doorgaans weinig toe. Beide technologieën hebben op zich niks platform specifieks en zijn daarom ook makkelijkst deelbaar.

React Native voor desktop

De volgende spreker, Wouter van den Broek, nam met "Building for a Bigger World Than Mobile" het concept van code delen per platform een niveau hoger. In zijn talk verkenden we hoe React Native ook voor Desktop apps kan gebruikt worden. Ook hier werden React Native Web en ReactXP aangehaald als mogelijke oplossingen. Wie specifieke Windows of MacOS API's wil gebruiken heeft echter pech, want de React Native packages hiervoor staan nog niet bepaald op punt. Uiteindelijk blijft het dus een goed idee om voor Desktop nog steeds gewoon te grijpen naar React of React Native Web in combinatie met Electron.

Onze algemene conclusie?

Er gaat veel aandacht naar code sharing binnen de React-community, maar niet alles is deelbaar. Een ideale productieklare oplossing laat voorlopig nog op zich wachten. Wie naast het web, iOS en Android, ook Windows wil targeten, heeft misschien meer geluk. Microsoft kondigde recent React Native for Windows aan.
 

Performance optimalisatie in React Native

Het gewoonlijke antwoord op problemen met performantie in React (Native) apps is shouldComponentUpdate. Anna Doubkova (Hive) vertelde in "Practical Performance for React (Native)" waarom dat net voor meer problemen kan zorgen. Heel wat wijd verspreide theorieën en guidelines om performante React code te schrijven kunnen net een omgekeerd effect hebben.

De React Native app die Anna als voorbeeld gebruikte had zo'n 100 reducers voor data management en kampte met problemen zoals trage opstart en time to interaction, alsook bibberende animaties en trage respons van user interactie. Anna’s team focuste op een oplossing voor de trage user interaction.

Voor je aan app-performantie kan sleutelen, moet je wel wel weten wat er aan de hand is. Zo is het belangrijk dat je weet dat in react Native de Native UI thread bij interactie een event doorstuurt naar de JS thread waar React overneemt. Het interactieproces gaat meestal als volgt:

Er zijn dus een heleboel stappen die zich voordoen voor de gebruiker effectief een visuele verandering te zien krijgt. Ondanks dat Anna's team initieel dacht dat het probleem bij de UI / Native thread lag, bleek dit uiteindelijk niet het geval. Het js-gedeelte handelt de meeste stappen af en de problemen en mogelijke oplossingen doen zich dus het vaakst hier voor. Bij Hive wisten ze dat het grootste probleem lag aan de update frequentie van UI views. De meest impactvolle oplossing bleek om geen anonieme functies in jsx te gebruiken. Een voorbeeld:

Dit probleem kan je makkelijkst vermijden door je code editor hints te laten geven wanneer je dit patroon toepast. Een mogelijke oplossing is het gebruik van de "react/jsx-no-bind" eslint regel in je eslint config. 

  • Bij class based React componenten schrijf je best je functie als een methode op je klasse.
  • Bij functionele componenten verplaats je best de functie die je doorgeeft buiten het component of kan je gebruik maken van React.useCallback(), React.useMemo() of React.useRef() om het herdefiniëren van props per render te vermijden.

Door de honderden reducers en sagas, bleek de manier waarop ze redux toepasten allesbehalve performant. De andere grote boosdoener was het gebruik van de functie varianten van mapStateToProps, mapDispatchToProps en mergeProps. Dat betekent dat per low level connect al deze functies tegelijkertijd uitgevoerd werden telkens de redux state geupdate werd. Anna’s team loste het probleem op door waar mogelijk telkens de redux object variant te gebruiken. Zo blijven de referenties van de props telkens hetzelfde en vermijd je rerenders.

Ken je tools

Performance optimalisaties zijn best ook effectief meetbaar. Zowel bij Hive als bij Marlon bleek de Chrome profiler een grote hulp te zijn op dit vlak. Deze geeft je bovendien ook een flame chart met meer inzicht in welke functies allemaal opgeroepen worden en hoeveel tijd er per stap/functie gespendeerd is. Je vindt de profiler in de performance tab van de react-native debugger voor mobile of diezelfde tab in Chrome developer tools voor het web.

Je eigen developer skills naar the next level brengen?

Ben je al helemaal thuis in JS? En heb je al ervaring met React en React Native? Maar ben je klaar om een stapje verder te gaan? Dan ben je bij ons aan het juiste adres! Spring zeker eens binnen voor een babbel.

Check onze vacatures

Vacature Javascript Developer