DEV Community

陈杨
陈杨

Posted on

Treasure Case Sharing of HarmonyOS 5 Development — Application Performance Optimization Guide

HarmonyOS Performance Optimization Practical Guide: Make Your App Fly 🚀

Hello everyone! Today, let's talk about practical tips for optimizing HarmonyOS app performance. Based on official documentation and best practices, I've summarized 8 core optimization directions, with code examples and in-depth analysis to help you say goodbye to lag and build a silky-smooth app!


1. Control State Refresh **🔄**

Core Idea: State variables trigger UI refreshes; overuse leads to performance degradation.

Optimization Strategies:

  • Streamline State Variables: Don't use @State for ordinary variables to avoid unnecessary rendering.
// ❌ Redundant state variable  
@State count: number = 0;  

// ✅ Use ordinary variable instead  
private count: number = 0;
Enter fullscreen mode Exit fullscreen mode
  • Minimize State Sharing Scope: Choose decorators as needed:
    • Component exclusive → @State
    • Parent-child sharing → @Prop/@Link
    • Cross-level sharing → @Provide/@Consume
// Parent-child component sharing example  
@Component  
struct Parent {  
  @State message: string = "Hello";  
  build() {  
    Column() {  
      Child({ msg: this.message }) // Pass via @Prop  
    }  
  }  
}  

@Component  
struct Child {  
  @Prop msg: string; // Child component receives  
  build() {  
    Text(this.msg)  
  }  
}
Enter fullscreen mode Exit fullscreen mode
  • Precise Refresh Listening: Use @Watch to monitor data changes and avoid global refreshes.
@State @Watch('onCountChange') count: number = 0;  

onCountChange() {  
  if (this.count > 10) this.updateUI(); // Conditional refresh  
}
Enter fullscreen mode Exit fullscreen mode

2. Control Rendering Scope **🎯**

Core Idea: Reduce unnecessary component rendering and layout calculations.

Optimization Strategies:

  • Lazy Load Long Lists: Use LazyForEach instead of ForEach to render only the visible area.
LazyForEach(this.data, (item) => {  
  ListItem({ item })  
}, (item) => item.id)
Enter fullscreen mode Exit fullscreen mode
  • Component Reuse: Reuse custom components with the same layout using reuseId.
@Component  
struct ReusableItem {  
  @Reusable reuseId: string = "item_template"; // Mark as reusable  
  build() { ... }  
}
Enter fullscreen mode Exit fullscreen mode
  • Frame-by-Frame Rendering: Render large amounts of data in batches to avoid blocking the main thread.
// Load 1000 pieces of data in batches  
loadDataBatch(start: number) {  
  const batch = data.slice(start, start + 20);  
  requestAnimationFrame(() => this.renderBatch(batch));  
}
Enter fullscreen mode Exit fullscreen mode

3. Optimize Component Drawing **✏️**

Core Idea: Reduce layout calculation and property registration overhead.

Optimization Strategies:

  • Avoid Time-Consuming Operations in Lifecycle: Don't perform heavy operations like network requests in aboutToAppear().
aboutToAppear() {  
  // ❌ Avoid  
  heavyNetworkRequest();  

  // ✅ Use async instead  
  setTimeout(() => heavyNetworkRequest(), 0);  
}
Enter fullscreen mode Exit fullscreen mode
  • Fix Width and Height to Reduce Calculation: Components with explicit sizes avoid adaptive layout.
// ✅ Fixed width and height skip Measure phase  
Image($r("app.media.icon"))  
  .width(100).height(100)
Enter fullscreen mode Exit fullscreen mode

4. Use Concurrency **⚡**

Core Idea: The main thread should only handle UI; time-consuming tasks go to sub-threads.

Optimization Strategies:

  • Multithreading: Use TaskPool for CPU-intensive tasks and Worker for I/O-intensive tasks.
// TaskPool example  
import { taskpool } from '@ohos.taskpool';  

@Concurrent  
function computeHeavyTask() { ... }  

taskpool.execute(computeHeavyTask).then((res) => {  
  // Update UI  
});
Enter fullscreen mode Exit fullscreen mode
  • Async Optimization: Use Promise or async/await to avoid blocking.
async loadData() {  
  const data = await fetchData(); // Async request  
  this.updateUI(data);  
}
Enter fullscreen mode Exit fullscreen mode

5. Reduce Layout Nodes **🌳**

Core Idea: Fewer nodes, faster rendering.

Optimization Strategies:

  • Use **`@builder*`* Instead of Lightweight Components**: Stateless components are more efficient with @Builder.
@Builder  
function IconButton(icon: Resource) {  
  Button() {  
    Image(icon)  
  }  
}  

// Call  
IconButton($r("app.media.home"))
Enter fullscreen mode Exit fullscreen mode
  • Remove Redundant Containers: Eliminate unnecessary Stack/Column/Row nesting.
// ❌ Redundant nesting  
Column() {  
  Column() {  
    Text("Hello")  
  }  
}  

// ✅ Flattened  
Text("Hello")
Enter fullscreen mode Exit fullscreen mode

6. Delay Triggering Operations **⏳**

Core Idea: Delay non-critical operations to improve startup speed.

Optimization Strategies:

  • Dynamically Load Modules: Use import() to load resources on demand.
// Load module only on click  
Button("Load Feature")  
  .onClick(async () => {  
    const module = await import("./HeavyModule");  
    module.run();  
  })
Enter fullscreen mode Exit fullscreen mode

7. Optimize Animation Frame Rate **🎞️**

Core Idea: 60fps is the lifeline of smooth animation.

Optimization Strategies:

  • Use System Animation Components: Prefer animateTo over manual frame control.
animateTo({ duration: 300 }, () => {  
  this.rotateAngle = 90; // System auto-interpolates  
})
Enter fullscreen mode Exit fullscreen mode
  • Reduce Animation Complexity: Use transform instead of top/left to avoid reflow.
// ✅ GPU acceleration  
Image($r("app.media.logo"))  
  .transform({ rotate: this.angle })
Enter fullscreen mode Exit fullscreen mode

8. Perceived Smoothness Optimization **✨**

Core Idea: User perception > actual performance.

Optimization Strategies:

  • Preload Key Resources: Preload first-screen images/data at startup.
aboutToAppear() {  
  preloadImages(["/res/image1.png", "/res/image2.png"]);  
}
Enter fullscreen mode Exit fullscreen mode
  • Skeleton Screen Placeholder: Show placeholder UI before data loads.
if (this.isLoading) {  
  LoadingSkeleton() // Skeleton screen component  
} else {  
  RealContent()  
}
Enter fullscreen mode Exit fullscreen mode

Conclusion: Performance Optimization is a Continuous Journey 🛣️

Performance optimization is not a one-time thing, but a process of continuous iteration. Remember the three golden rules:

  1. Precise Refresh: Only refresh what changes, don't touch the whole app.
  2. Lightweight Main Thread: Offload time-consuming operations to sub-threads.
  3. Simplified Nodes: The shallower the layout hierarchy, the better.

Hope these cases help you avoid pitfalls! If you have questions, feel free to discuss in the comments.

Let's build the ultimate smooth HarmonyOS app together! 💪

Top comments (0)