Page Transition and Sliding Scene Optimization

This document provides detailed optimization guidelines for two high-frequency lag scenarios: page transition and page sliding.


Scenario 1: Lag During Page Transition

1. Case Description of Lag

Scenario: In complex business scenarios (such as navigating from product list to detail page, Feed flow to immersive video page), after user clicks navigation button:

  1. Response delay: No immediate feedback after clicking, interface "freezes" for tens of milliseconds.
  2. Animation frame drop: Transition animation (Push Animation) shows obvious lag or jitter (Jank).
  3. Long white screen time: After new page enters, need to wait for a long time to show first screen content.

Technical Attribution:

  • JS thread blocking: New page component tree is huge, Mount phase Reconciliation and Commit computation is too large, blocking JS thread, causing animation frames to not be calculated timely.
  • Main thread load: Large number of Native Views created simultaneously (CreateView), UI thread instantaneous load too high.
  • Resource loading: Large image decoding, Bundle loading occupy transition critical path.

2. Optimization Ideas and Technical Routes

2.1 Infrastructure Layer Optimization

  • Bisheng Compiler: Enable LTO (Link Time Optimization) to reduce binary size; enable PGO (Profile Guided Optimization) to optimize instruction arrangement based on hot code, improving cold start and transition speed.
  • JSVM Virtual Machine: In reload scenarios, JSVM uses JIT technology to compile JavaScript to native machine code, high execution efficiency.
  • React 18 Concurrent Features: Utilize Automatic Batching, RNOH defaults to concurrentRoot: true, merging multiple setState into one Commit, reducing render count.

2.2 Pre-processing Strategy

  • FrameNode Pre-loading RN Page: Use FrameNode and NodeContainer to build native node tree corresponding to RN page in background.
  • Pre-warming RN Instance: For independent Bundle business modules, initialize RNInstance during App startup phase.

2.3 Rendering and Interaction Optimization

  • Interaction Priority (InteractionManager): Use InteractionManager.runAfterInteractions to defer heavy component mounting until after transition animation ends.
useEffect(() => {
  const task = InteractionManager.runAfterInteractions(() => {
    setIsReady(true); // Render complex content after animation ends
  });
  return () => task.cancel();
}, []);
  • Skeleton Screen: When isReady is false, display lightweight skeleton screen. Skeleton screen should use fixed width/height Views to avoid layout jitter after data loading.
  • React Compiler / useMemo: Enable React Compiler for automatic memoization of components and Hooks.
  • Fixed Layouts: Promote components using fixed width/height, reduce Flex layout calculation levels.
  • Native Driver: Enable useNativeDriver: true for transition animation, offload interpolation calculation to UI thread.

3. Best Practice Code Example

Solution: InteractionManager + Skeleton Screen + Deferred Loading

import React, { useState, useEffect } from 'react';
import { View, InteractionManager, StyleSheet } from 'react-native';
import { HeavyContent } from './HeavyContent';
import { Skeleton } from './Skeleton';

export default function OptimizedDetailPage() {
  const [isTransitionFinished, setIsTransitionFinished] = useState(false);

  useEffect(() => {
    // Core optimization: Ensure smooth transition animation
    const task = InteractionManager.runAfterInteractions(() => {
      setIsTransitionFinished(true);
    });
    return () => task.cancel();
  }, []);

  if (!isTransitionFinished) {
    return <Skeleton />;
  }

  return <HeavyContent />;
}