influxdata / influxdata/ui

Proposal to address the sluggishness of certain parts of the UI

Open
#2,703 16 comments 4 reactions 1 assignee Claimed by @hralexander View on GitHub
performance team/automation
Dominant language
TypeScript
Stars
117
Forks
51
Avg merge
2d 15h
Merged PRs (30d)
4

Description

## The Problem:

This video illustrates the issue. In a dashboard with a single graph, there is a noticeable and perceptible delay between typing a character and the character being rendered by the app. The cursor moving around is meant to illustrate the lag in typing - by the time the cursor has been moved, the typing has finished, but the UI hasn't updated the Monaco editor. This problem scales with dashboard cells - the more cells in a dashboard, the slower it takes between keystroke being entered and the UI updating.

https://user-images.githubusercontent.com/146112/134727962-040a255d-eeb5-4395-a6f6-47097957e4bb.mov

### The Cause
The main cause of this problem isn't the Monaco language server, but in how the application handles changes to its state. A single keystroke changes the active query, which is a part of the redux state that a large portion of the application above the code editor depends on. This means that on every keystroke that changes the active query, a large part of the application re-renders. It's this re-rendering and recalculation of props and the state of the redux store that causes the slowdown.

## Proposal to solve the problem
We'll need to address the core problem mentioned above, namely that a large portion of the app changes when a single reducer's state changes.

Unfortunately, there isn't a quick fix, or a single linchpin that needs to be modified to ameliorate this. It will take work throughout the application. We can start addressing some of the pain points to enable some minor relief while the big changes get worked on however.

The easier, quicker work will be effective on a small scale, but likely won't be able to affect the entire app; however, the effectiveness will still be applicable after we make big changes, so it's worthwhile to take them on.

### Smaller, tactical changes
1. memoize function components whose props don't change. (Example: [InnerView](https://github.com/influxdata/ui/blob/master/src/visualization/components/View.tsx#L30) can be memoized [like so](https://gist.github.com/hoorayimhelping/73bd7d019e5faa575d3b6e6c32671cef))
1. make class components with props that don't change pure. (Example: [Cell](https://github.com/influxdata/ui/blob/master/src/shared/components/cells/Cell.tsx#L49) can be made pure [like so](https://gist.github.com/hoorayimhelping/0ea21efed993658f730389249c115ba6))
1. use the reselect library (which we already have installed as a dependency to our codebase) as a way of making our selectors more effecient, while at the same time using these memoized selectors more frequently. (Example: [getCells](https://github.com/influxdata/ui/blob/master/src/cells/selectors/index.ts#L3) can be memoized using reselect [like so](https://gist.github.com/hoorayimhelping/165eee1480c881c787c63a626b639da6))
1. address wasteful reducers that change the state needlessly (e.g. nothing in the state has changed, but the reducer still returns a new copy of state). (Example:[`SET_ACTIVE_QUERY_TEXT`](https://github.com/influxdata/ui/blob/master/src/timeMachine/reducers/index.ts#L273) can be changed to [only return new state when there's a difference](https://gist.github.com/hoorayimhelping/3f4875ad96b276f0d0401d61d8ada78f))
1. educate the engineers on the UI team about why the code we write is a problem and how to address those problems with new code we write so that we don't have a large inefficient pile of spaghetti. Essentially explain the previous tactical steps to them, while keeping a critical eye turned towards code reviews so that we continue with good habits.

**Note**: Using the [why did you render](https://www.npmjs.com/package/@welldone-software/why-did-you-render) library is extremely helpful in tracking down code to apply the above tactical changes to.

### Larger, strategic changes
1. refactor/re-architect the app from a high level from the perspective of the redux store - different sections of the app should have different and independent redux stores. We currently have a single store for the entire application, and it's very difficult to refactor any part of it to address issues like this one.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.