Render Performance Optimization

Rendering performance affects page smoothness and responsiveness. The more complex the page structure and the more frequent the updates, the greater the rendering pressure.

Reduce Page Node Count

Too many nodes on a page increases memory usage and layout computation time. Keep node count below 1000 per page and tree depth below 30 levels.

Common strategies:

  • Remove redundant nesting: Eliminate unnecessary View wrapper layers and keep the structure flat
  • Conditional rendering: Use {condition && ...} to remove nodes that aren't needed rather than display: none; for elements that toggle frequently, use the hidden prop instead to avoid repeatedly creating and destroying nodes
import { View } from '@ray-js/ray';

{/* ✅ Use conditional rendering to remove unneeded nodes */}
{showDetail && (
  <View className="detail-content">...</View>
)}

Use Scroll Event Listeners Carefully

onPageScroll and ScrollView's onScroll events fire at a very high frequency. Each trigger has cross-thread communication overhead.

Notes:

  • Avoid listening to scroll events when not necessary
  • Don't pass an empty onPageScroll handler when you don't need it
  • Avoid calling setState or synchronous APIs frequently inside scroll callbacks

Choose High-Performance Animation Approaches

Animations enhance interaction experience. Choosing the right animation approach ensures good visual effects without performance issues.

ApproachUse CasePerformanceComplexity
CSS animation / TransitionSimple transitions (show/hide, translate, scale)HighLow
GIF / LottieDecorative animations (loading, icon effects)HighLow
RJSHigh-frequency interactive animations (drag, gesture sync)HighHigh
setState-driven—LowLow
  • Prefer transform and opacity for animations — they can leverage GPU acceleration
  • Avoid animating width, height, margin, padding, etc. — these trigger layout reflow
/* ✅ Recommended: use transform */
.slide-in {
  transform: translateX(-100%);
  transition: transform 0.3s ease;
}
.slide-in.active {
  transform: translateX(0);
}

/* ❌ Avoid: use left/right */
.slide-in {
  left: -100%;
  transition: left 0.3s ease;
}

Avoid using setState to update state every frame to drive animations. At 60fps, each frame is only ~16ms; cross-thread communication overhead causes severe frame drops. Use RJS for high-frequency interactive animations (such as drag-follow) to respond to events and modify styles directly in the view layer.

Component-Based Decomposition

Split pages into independent child components. State updates within a component only trigger that component's re-render, not the entire page:

Page
├── Header component (updates independently)
├── ListItem component × N (each updates independently)
└── Footer component (updates independently)

Checklist

Check ItemOptimization
Too many page nodesRemove redundant nesting, simplify structure
Using display:none to hide many nodesSwitch to conditional rendering
Unnecessary scroll event listenersRemove empty callbacks
Laggy animationsSwitch to CSS animation or RJS
Page not decomposed into componentsExtract independent modules as child components