Frontend Development 13 min read

Optimizing UI Rendering Performance in OpenSumi IDE

The article shows how OpenSumi’s UI lag, caused by global‑state re‑renders, redundant props, and repeated menu and tree creation, can be eliminated by memoizing components, splitting views, caching menus, removing unneeded width props, batching icon CSS insertion, and debouncing ResizeObserver events, cutting latency from seconds to smooth responsiveness on both M1 and Intel machines.

DaTaobao Tech
DaTaobao Tech
DaTaobao Tech
Optimizing UI Rendering Performance in OpenSumi IDE

OpenSumi is a React‑based IDE whose UI suffers from frequent re‑renders caused by global state changes, unnecessary props, and repeated creation of menu and tree items.

The article first explains the classic React performance rule of reducing unnecessary re‑renders. It suggests using React.memo and useMemo to memoize components that depend only on stable props, and to split large views into smaller, independent components (e.g., SearchInput, SearchExclude, SearchInclude, SearchResult).

Example service code:

class MyService {
  @Autowried()
  private viewModel: IMyViewModel;

  private updateView(value) {
    // someState is observable, view can use it directly
    this.viewModel.someState = value;
  }
}

For menu rendering, the original implementation recreated menu instances on every render, leading to hundreds of menu items being regenerated. Caching menus solves the issue:

private getInlineMenu(viewItemValue: string) {
  if (this.cachedMenu.has(viewItemValue)) {
    return this.cachedMenu.get(viewItemValue)!;
  }
  // create new menu
  this.cachedMenu.set(viewItemValue);
}

TreeView components often receive unnecessary width props, causing the whole tree to re‑render on panel resize. Removing the prop reduces render cost:

// before
// after

Icon registration for GitLens creates a CSS class per icon and injects it into a <style> tag. When performed thousands of times it triggers massive DOM re‑flows. Batch‑inserting the generated classes eliminates the slowdown.

ResizeObserver is used to broadcast size changes even when a panel is hidden (display:none), causing double renders. The fix caches the previous size with useRef and only emits events when the size actually changes.

All the optimizations are demonstrated in several PRs (e.g., #94, #101, #131, #133, #149, #172, #176). After applying them, UI latency drops from several seconds to a smooth experience on both M1 and Intel machines.

frontendPerformance OptimizationReactideOpenSumimemoization
DaTaobao Tech
Written by

DaTaobao Tech

Official account of DaTaobao Technology

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.