V Heurece jsme nedávno zapracovali nový facelift našeptávače, na kterém jsem jako frontend developer spolupracoval. A protože se komponenta zobrazuje na všech našich stránkách, byla potřeba, aby byla rychlá. Proto jsme se rozhodli jsme pro React.
O React Hooks je toho napsáno hodně, ale málo se dozvídáme o tom, jak ve skutečnosti správně optimalizovat a profilovat React komponenty. Spousta vývojářů se drží ESLintu a chybně používá React Hooks. Zejména se dopouští chybné předčasné optimalizace. Poradím vám způsoby, jak tomu předejít a jak vůbec zjistit, že je někde performance problém. Sdílím také několik poznatků, díky kterým jsme získali hlubší znalost Reactu.
Toto téma jsem mluvil na nedávné konferenci Frontendisti. Podívejte se na přednášku s prezentací nebo si přečtěte shrnutí níže.
Co nás ovlivnilo při výběru?
- rozhodující pro nás byla performance optimalizace
- našli jsme nástroje pro měření performance v React aplikacích
- našli jsme techniky pro optimalizaci výkonu v React aplikacích
- díky tomu jsme vyloučili předčasnou optimalizaci výkonu
Rychlost Reactu je klíčová
- React je rychlý díky virtuálnímu DOMu, když se používá správně
Přístup k optimalizaci
Při vývoji nové změny nebo featury zjistíme, jestli potřebujeme optimalizovat výkon a pak ji provedeme. Neděláme předčasné optimalizace, pokud si nejsme jisti, že je to opravdu potřeba na základě měření.
Vhodný přístup zahrnuje:
- vývoj
- performance test
- optimalizace, pokud je nutná
- test
- deployment
React Devtools
- můžeme přecházet v rámci commitů Reactu
- jaká změna nastala a proč dostalo ke změně?
React Profiling API
- umožňuje přístup k metrikám, které nám knihovna poskytuje (actual duration, base duration)
- umožňuje takto měřit render komponent, které touto komponentou obalíme
Why did you render?
- doplněk k React DevTools
- podrobněji vypisuje změny mezi rendery
Definice performance problému
Neeliminovat zbytečné rendery komponent, které nejsou náročné na vykreslení, protože to má svou cenu ( přehlednost v kódu a případně zhoršení performance).
React functional components
Každý render má vlastní stav, props, handlery a efekty.
Optimalizační strategie
Je třeba se snažit optimalizovat spíše architektonicky než pomocí memoizace.
Architektonické techniky:
- move state down
- Lift content up - kompozice
- React.useReducer
- virtualizace dlouhých seznamů
- uncontrolled forms
Memoizační techniky:
- pro efektivní využití je potřeba často kombinovat (React.memo + useCallback)
- React.memo
- memoizace komponent
- useMemo
- memoizace výpočetně náročných hodnot
- useCallback
- memoizace funkce
- memoizace funkce
ReactHooks
- věřit ESLintu - eslint-plugin-react-hooks
- nevynechávat závislosti (může vést k zacyklení nebo problémům renderu)
FAQ:
Může předčasná optimalizace škodit?
při použití React.memo u komponenty, která má hodně props a často se re-renderuje, dochází k častým porovnáváním props a to zpomaluje render.
S jakými problémy jsi se tam setkal?
Snažil jsem se lhát ESLintu a docházelo k zacyklení aplikace, to mě vedlo ke správnému použití Hooku a změně architektury aplikace v kontextu našeptávače.
Kdy lhát useEffectu?
Pouze v případě, že opravdu víme, co děláme (závislost je statická, memoizovaná a nemění se nám).
Co nás čeká v budoucnu v Reactu?
Novinky souvisí s novými featurami Reactu:
- Concurrent Mode - suspense
- React server komponenty
Zajímavé zdroje
- The last guide to the useEffect Hook you’ll ever need
- A Complete Guide to useEffect
- Optimize Props References and Improve Rendering in React Native
- Premature Optimize the Heck Out of Your React Apps Using Memoization
- Solved React [ESLint] Feedback for 'exhaustive-deps' lint rule
- Open Replay Blog
- Demo premature optimization
- React docs
- Konference React Geekle