I have been working on an optimization of the online game app. It is a large React app with a big code base and it is very laggy (mostly on mobile version).
Some of the problems I've encountered are:
- a lot of inline functionalities
- no memoization
- a lot of unnecessary inline styles
- a lot of state copies
- state mutations
- unnecessary for loops
- nested mapping
- code duplicates
My task was to improve performance but only for one part of the app for now (the game part) and what I did for the start was to remove inline functionalities and put them in useCallbacks. Then I played with Profiler and noticed which components are the laggiest. Then I concentrated on only one component (in agreement with my employer) and what I did there is:
- divided the code into smaller components
- removed unnecessary for loops and nested mapping
- removed unnecessary code, functionality, state copies and state mutations
- removed all inline styles and put them into css
After checking the profiler again, component's performance was much better but now the whole game part of the app is working significantly worse than before - it became noticeably laggy even on the desktop. Is there any advice or explanation why is this happening? What can I do to make this better?
CodePudding user response:
It's not easy to say explicitly what's causing the lag since there is no code but I would recommend addressing the following issues:
Code-splitting: If your game part of the app is big, consider code splitting to load only the necessary parts of your code when a user visits the game section of your app.
Virtualized list: If you are using lists that are large, using a virtualized list can improve performance as it only renders visible items and reduces the number of DOM nodes that need to be managed. I recommend using react-window.
Optimization techniques: Make use of
useMemo
andshouldComponentUpdate
to prevent unnecessary re-renders. Also make sure to use lazy loading where it's possible.Refactoring: Refactor your code to make it more efficient. Consider using a library such as ImmutableJS to keep your state immutable and reduce the number of re-renders.
Debugging: Use React DevTools to see what's causing the lag, for example which components are constantly re-rendering.
Web Worker: Make use of Web Workers to offload computationally expensive tasks, reducing the number of API calls. You would also minify your code with such workers.
CodePudding user response:
In my experience React MUST have hooks if functional components are used. This allows React to "memorize" and not re-create functions or pieces of data that have not been changed, if you don't do that then the memory is quickly clogged and hence the slower performance - especially if it's a large application.
Removing redundant code is also very important - if there are parts of the application that use the same functionality write a Context or use a State Management tool such as Redux, Zustang and there are many to choose from.
State mutations create a lot of bugs and it should never be done in React - "state is a reference to the component state at the time the change is being applied. It should not be directly mutated." That's why they provide a callback function
The thing is you did nothing wrong, you have to cover the entire application in best practices to make it work and state mutations create bugs that are hard to identify such as mysterious dissapearence of data, weird sorting behaviour and so on. The same is with the key, for example if you use index on the key - you delete something with filter in the app the key will change because index changed and that makes React "confused" about it and creates bugs that are also hard to identify.
Everything you did is a step in the right direction - the problem is if there are other state mutations, components without hooks and so on that make the app perform way under the Reacts famous speed