及时做APP开发实战(十一)-性能优化实践

及时做APP开发实战(十一)-性能优化实践

本文将详细介绍HarmonyOS应用性能优化的关键实践,包括定时器销毁和不可变数组操作。

一、性能优化概述

1.1 为什么需要性能优化

复制代码
┌─────────────────────────────────────┐
│          性能问题影响                │
├─────────────────────────────────────┤
│  内存泄漏 → 应用卡顿、崩溃           │
│  UI不刷新 → 数据不同步、体验差       │
│  长列表卡顿 → 滑动不流畅            │
│  后台耗电 → 用户投诉、卸载           │
└─────────────────────────────────────┘

1.2 优化目标

优化项 目标 效果
定时器销毁 杜绝内存泄漏 后台无无效计时
不可变数组 UI正确刷新 数据实时同步
懒加载 减少渲染开销 长列表流畅

二、定时器销毁优化

2.1 问题分析

【图1:定时器泄漏场景】

复制代码
┌─────────────────────────────────────┐
│          定时器生命周期              │
├─────────────────────────────────────┤
│  [页面进入]                          │
│      ↓                              │
│  [启动定时器] setInterval()          │
│      ↓                              │
│  [用户退出页面]                       │
│      ↓                              │
│  ❌ 定时器未销毁 → 后台持续运行       │
│      ↓                              │
│  ❌ 内存泄漏 + 耗电                   │
└─────────────────────────────────────┘

2.2 正确实现方式

typescript 复制代码
@Entry
@Component
struct PomodoroPage {
  // 定时器ID
  private timerId: number = -1;
  
  // 启动计时器
  startTimer() {
    if (this.timerId === -1) {
      this.timerId = setInterval(() => {
        // 计时逻辑
      }, 1000);
    }
  }
  
  // 停止计时器
  stopTimer() {
    if (this.timerId !== -1) {
      clearInterval(this.timerId);
      this.timerId = -1; // 重置ID
    }
  }
  
  // 页面销毁时清理
  aboutToDisappear() {
    this.stopTimer(); // ✅ 确保定时器被销毁
  }
}

2.3 关键要点

复制代码
┌─────────────────────────────────────┐
│          定时器销毁规范              │
├─────────────────────────────────────┤
│  1. 使用timerId追踪定时器            │
│  2. 销毁后重置timerId为-1            │
│  3. 在aboutToDisappear中调用销毁     │
│  4. 避免重复启动定时器               │
└─────────────────────────────────────┘

三、不可变数组操作

3.1 问题分析

【图2:可变vs不可变操作】

复制代码
可变操作(❌ 不推荐):
┌─────────────────────────────────────┐
│  this.todoList.push(todo)           │
│  this.todoList[index] = todo        │
│  item.completed = !item.completed   │
└─────────────────────────────────────┘
         ↓
  直接修改原数组/对象
         ↓
  ❌ UI可能不刷新

不可变操作(✅ 推荐):
┌─────────────────────────────────────┐
│  this.todoList = [...this.todoList, todo]  │
│  this.todoList = this.todoList.map(...)    │
│  this.todoList = this.todoList.filter(...) │
└─────────────────────────────────────┘
         ↓
  创建新数组/对象
         ↓
  ✅ 触发UI刷新

3.2 优化前后对比

添加待办
typescript 复制代码
// ❌ 优化前:直接push
async addTodo(text: string): Promise<TodoItem> {
  const todo = createTodoItem(text);
  this.todoList.push(todo); // 直接修改原数组
  return todo;
}

// ✅ 优化后:创建新数组
async addTodo(text: string): Promise<TodoItem> {
  const todo = createTodoItem(text);
  this.todoList = [...this.todoList, todo]; // 创建新数组
  return todo;
}
更新待办
typescript 复制代码
// ❌ 优化前:直接修改索引
async updateTodo(todo: TodoItem): Promise<void> {
  const index = this.todoList.findIndex(item => item.id === todo.id);
  if (index !== -1) {
    this.todoList[index] = todo; // 直接修改
  }
}

// ✅ 优化后:使用map创建新数组
async updateTodo(todo: TodoItem): Promise<void> {
  this.todoList = this.todoList.map(item => 
    item.id === todo.id ? todo : item
  );
}
切换完成状态
typescript 复制代码
// ❌ 优化前:直接修改对象属性
async toggleTodoComplete(todoId: number): Promise<void> {
  const todo = this.todoList.find(item => item.id === todoId);
  if (todo) {
    todo.completed = !todo.completed; // 直接修改
  }
}

// ✅ 优化后:创建新对象
async toggleTodoComplete(todoId: number): Promise<void> {
  this.todoList = this.todoList.map(item => {
    if (item.id === todoId) {
      // 创建新对象
      const newItem: TodoItem = {
        id: item.id,
        text: item.text,
        completed: !item.completed,
        pomodoroCount: item.pomodoroCount,
        createdAt: item.createdAt
      };
      return newItem;
    }
    return item;
  });
}

3.3 不可变操作方法总结

操作 可变方法 不可变方法
添加 arr.push(item) arr = [...arr, item]
删除 arr.splice(i, 1) arr = arr.filter(...)
更新 arr[i] = item arr = arr.map(...)
修改属性 obj.prop = val 创建新对象

四、性能监控工具

4.1 PerformanceUtil实现

typescript 复制代码
import hilog from '@ohos.hilog';

export class PerformanceUtil {
  private static instance: PerformanceUtil | null = null;
  private timers: Map<string, number> = new Map();
  
  // 获取单例
  public static getInstance(): PerformanceUtil {
    if (!PerformanceUtil.instance) {
      PerformanceUtil.instance = new PerformanceUtil();
    }
    return PerformanceUtil.instance;
  }
  
  // 开始计时
  public startTimer(key: string): void {
    this.timers.set(key, Date.now());
  }
  
  // 结束计时
  public endTimer(key: string): number {
    const startTime = this.timers.get(key);
    if (startTime) {
      const duration = Date.now() - startTime;
      this.timers.delete(key);
      hilog.info(0x0000, 'Performance', `[${key}] 耗时: ${duration}ms`);
      return duration;
    }
    return 0;
  }
}

4.2 在业务代码中使用

typescript 复制代码
import { PerformanceUtil } from '../utils/PerformanceUtil';

export class TodoViewModel {
  private performanceUtil: PerformanceUtil = PerformanceUtil.getInstance();
  
  async addTodo(text: string): Promise<TodoItem> {
    this.performanceUtil.startTimer('addTodo');
    
    // 业务逻辑...
    this.todoList = [...this.todoList, todo];
    
    this.performanceUtil.endTimer('addTodo');
    return todo;
  }
}

五、最佳实践总结

5.1 定时器管理规范

【图3:定时器管理清单】

复制代码
┌─────────────────────────────────────┐
│          ✅ 定时器管理规范           │
├─────────────────────────────────────┤
│  □ 使用成员变量追踪timerId           │
│  □ 销毁后重置timerId                 │
│  □ 在aboutToDisappear中清理          │
│  □ 避免重复启动                      │
│  □ 使用性能监控记录耗时              │
└─────────────────────────────────────┘

5.2 数组操作规范

【图4:数组操作规范】

复制代码
┌─────────────────────────────────────┐
│          ✅ 数组操作规范             │
├─────────────────────────────────────┤
│  □ 添加:使用展开运算符 [...arr, item] │
│  □ 删除:使用filter创建新数组         │
│  □ 更新:使用map创建新数组            │
│  □ 修改属性:创建新对象               │
│  □ 避免直接修改原数组/对象            │
└─────────────────────────────────────┘

六、总结

本文介绍了HarmonyOS应用性能优化的两个关键实践:

  1. 定时器销毁:确保页面退出时清理定时器,避免内存泄漏
  2. 不可变数组操作:使用创建新数组的方式触发UI刷新

这些优化可以显著提升应用的稳定性和用户体验。


相关推荐
lvv13 小时前
不会被渲染的组件,为什么让我的首屏白屏了?(一次前端问题总结)
前端·webpack·性能优化
烬羽13 小时前
《memo 明明加了,为什么子组件还是渲染了?》
react.js·性能优化·全栈
张龙68721 小时前
Node.js 内存泄漏排查实战:从内存曲线到堆快照,一条可复用的定位路径
性能优化·node.js
爱喝水的鱼丶2 天前
SAP-ABAP:SAP性能分析核心工具入门——ST05/SAT/ST12等常用事务码的基础用法解析
性能优化·sap·abap·性能分析·开发交流·交流学习
FungLeo2 天前
Flutter 带 TTL 的多级缓存设计:内存+磁盘+网络三层实战
网络·flutter·缓存·性能优化
人间凡尔赛2 天前
React Compiler 1.0 正式落地:告别 useMemo / useCallback,2026 前端性能优化的新范式
前端·性能优化·react
肥胖小羊3 天前
企业微信机器人系统:架构设计、多场景应用与性能优化实战
性能优化·企业微信
云端漫步19873 天前
HarmonyOS NEXT AI 智能生活助手:性能优化
华为·性能优化·生活·harmonyos
做好一个小前端3 天前
ECharts 折线图大数据量性能优化参考
前端·性能优化·echarts
UWA3 天前
隐藏视频变“常驻刺客”,VideoPlayer与“N/A”纹理该怎么查
人工智能·性能优化·音视频·memory·cpu·游戏开发