DEV Community

陈杨
陈杨

Posted on

Hong Mong 5 Development Treasure Case Sharing Performance Experience Design

Here is a developer's practical guide based on the HarmonyOS performance experience design documentation, combining official cases and code implementations, and sharing practical tips in a more approachable language:


🌟 HarmonyOS Performance Optimization Treasure Guide: Make Your App Smooth as Silk!

Hello everyone! Recently, I discovered a "gold mine" of performance optimization in the HarmonyOS documentation—there are actually many practical cases of smoothness design provided by the official team! But many developers might have missed them. Today, I've organized these valuable insights, added code examples, and will help you easily create a 60fps stutter-free HarmonyOS app!


1. Core Principles of Perceived Smoothness

The official documentation emphasizes: Smoothness ≠ High Performance. Instead, it's the perfect combination of operation response, animation, and psychological expectation. For example:

// Incorrect: Loading a large image directly on the main thread
Image($r('app.media.large_img')) // May cause UI freeze

// Correct: Asynchronous loading + placeholder
Column() {
  LoadingIndicator() // Show loading animation first
  Image($r('app.media.large_img'))
    .onAppear(() => {
      // Asynchronous decoding
      asyncLoadImage()
    })
}
Enter fullscreen mode Exit fullscreen mode

💡 Key Point: You must provide visual feedback within 100ms after user interaction (even if the content hasn't finished loading)


2. Practical Cases of Interaction Smoothness

Case 1: List Scrolling Optimization (Solving Frame Drops)

The official documentation requires: Consecutive frame drops ≤ 3 frames

// Before optimization: Recalculating layout on every scroll
@State items: Array<string> = [...]

build() {
  List() {
    ForEach(this.items, (item) => {
      ListItem() {
        Text(item)
          .onAppear(() => this.calculateLayout(item)) // ❌ Source of stutter!
      }
    })
  }
}

// After optimization: Pre-calculation + caching
private layoutCache = new Map<string, number>()

onPageShow() {
  preCalculateLayouts() // Pre-calculate layouts
}

build() {
  List() {
    ForEach(this.items, (item) => {
      ListItem() {
        Text(item)
          .height(this.layoutCache.get(item)) // ✅ Read from cache
      }
    })
  }
}
Enter fullscreen mode Exit fullscreen mode

Officially provided optimization effect comparison


Case 2: Accelerating Click Response (Target ≤ 100ms)

// Button click triggers a complex operation
Button('Start Processing')
  .onClick(() => {
    // ❌ Incorrect: Synchronous execution on main thread
    heavyCalculation() 

    // ✅ Correct: Asynchronous processing + instant feedback
    animateButtonPress() // Give visual feedback first
    taskPool.execute(heavyCalculation) // Offload to background thread
  })
Enter fullscreen mode Exit fullscreen mode

Pitfall Avoidance Guide:

  1. Response latency = Touch event → Screen feedback
  2. Time-consuming operations must use TaskPool or Worker

3. Visual Smoothness Black Technology

Animation Synchronization Principle (Officially Recommended Solution)

// Page transition animation
pageTransition() {
  PageTransitionEnter({ duration: 350 })
    .slide(SlideEffect.Right)
    .interpolator(Curve.EaseOut) // Use smooth curve
  PageTransitionExit({ duration: 300 })
    .opacity(0.8)
}
Enter fullscreen mode Exit fullscreen mode

Official page transition animation example

Animation Design Iron Rules:

  1. Startup animation ≤ 1100ms
  2. Use Bezier curves for property changes (don't use linear!)
  3. Avoid abrupt background color changes (use gradient animation transitions)

4. Performance Detection Tools

Official Easter Egg—ArkUI Inspector:

# Run in terminal
hdc shell arkui_inspector -t your.app.package.name
Enter fullscreen mode Exit fullscreen mode

Real-time monitoring:

✅ Frame rate fluctuations

✅ Memory usage

✅ Thread blocking status


5. Cold Start Optimization (≤ 1100ms Target)

// App entry optimization
export default class SplashAbility extends Ability {
  onWindowStageCreate(windowStage: window.WindowStage) {
    // 1. Load critical resources first
    loadCriticalResources().then(() => {
      // 2. Then create the UI
      windowStage.loadContent('pages/Home')

      // 3. Asynchronously load non-critical resources
      taskPool.execute(loadNonCriticalRes)
    })
  }
}
Enter fullscreen mode Exit fullscreen mode

Segmented Loading Tips:

  1. First screen elements ≤ 15
  2. Use WebP format for images
  3. Avoid network requests during startup

Conclusion: Smoothness is Designed!

After reading these cases, do you realize that HarmonyOS performance optimization actually has its rules? Remember these three key numbers:

🚀 Click response ≤ 100ms

🎯 Startup time ≤ 1100ms

💥 Frame drops ≤ 3 frames

There are even more valuable cases in the official documentation (such as "Optimizing Long List Loading" and "Best Practices for Transition Animations"). I strongly recommend searching for the keyword "performance optimization" in the developer docs!

If you encounter stutter problems in practice, feel free to discuss in the comments~ Also, follow me for more HarmonyOS development tips in the future! ✨

Hope this down-to-earth summary helps you avoid performance pitfalls! If you find it useful, don't forget to like and bookmark 😉 See you next time!

Top comments (0)