---
title: 内存优化
summary: "介绍小程序内存优化方法，包括内存泄漏排查、页面栈管理和数据规模控制。"
docType: default
tags: [内存优化指南, 内存泄漏排查, 页面栈管理, 定时器清理]
questions:
  - 小程序内存占用过高会导致什么问题？
  - 如何监听小程序的内存告警事件？
  - 如何避免定时器导致的内存泄漏？
  - 如何避免事件监听导致的内存泄漏？
  - 如何通过控制页面栈深度来优化内存？
  - navigateTo、redirectTo 和 reLaunch 在内存管理上有什么区别？
  - 控制数据规模对内存优化有什么帮助？
---

# 内存优化

小程序运行在有限的系统资源中。当内存占用过高时，小程序可能被系统销毁或客户端主动回收，导致用户需要重新打开小程序，体验非常糟糕。

## 内存问题的表现

| 表现 | 可能原因 |
| ---- | -------- |
| 小程序突然闪退 | 内存占用过高，被系统回收 |
| 页面越用越卡 | 内存泄漏，可用内存逐渐减少 |
| 返回之前的页面变慢 | 页面栈过深，占用大量内存 |

## 监听内存告警

使用 [onMemoryWarning](/cn/miniapp/develop/ray/api/device/memory/onMemoryWarning#onmemorywarning) 监听内存告警事件，在收到告警时进行必要的内存清理：

```tsx
import { onMemoryWarning } from '@ray-js/ray';

onMemoryWarning((res) => {
  console.warn('内存告警，级别:', res.level);
});
```

## 避免内存泄漏

### 及时清理定时器

页面组件卸载时，必须清理关联的定时器：

```tsx
import React, { useEffect } from 'react';

function fetchLatestData() {}

function DevicePage() {
  useEffect(() => {
    const timer = setInterval(() => {
      fetchLatestData();
    }, 5000);

    return () => clearInterval(timer); // 组件卸载时自动清理
  }, []);
}
```

### 及时解绑事件监听

注册的事件监听在组件卸载时应及时解绑：

```tsx
import React, { useEffect } from 'react';
import { onNetworkStatusChange, offNetworkStatusChange } from '@ray-js/ray';

function DevicePage() {
  useEffect(() => {
    const handler = (res) => console.log('网络状态:', res.isConnected);
    onNetworkStatusChange(handler);

    return () => offNetworkStatusChange(handler);
  }, []);
}
```

## 控制页面栈深度

页面栈过深会占用大量内存，合理选择导航方式：

| 方法 | 效果 | 适用场景 |
| ---- | ---- | -------- |
| `navigateTo` | 新增一层页面栈 | 需要返回的页面跳转 |
| `redirectTo` | 替换当前页面 | 不需要返回的跳转 |
| `reLaunch` | 清空页面栈 | 登录后跳转首页等场景 |

## 控制数据规模

避免在状态或全局变量中存储过大的数据，使用分页只保留当前展示所需的数据：

```tsx
import React, { useState } from 'react';

async function fetchProducts(params: { page: number; pageSize: number }) {
  return { data: [] };
}

function ProductList() {
  const [list, setList] = useState([]);

  const loadMore = async (page: number) => {
    const res = await fetchProducts({ page, pageSize: 20 });
    setList(prev => [...prev, ...res.data]); // 追加而非全量替换
  };
}
```

## 控制代码包体积

代码包体积不仅影响下载耗时，也直接影响运行时的内存占用。代码包在加载时需要被解析和执行，体积越大，占用的内存越多。减小代码包体积是降低内存基线的有效手段之一。

详见[代码包体积优化](/cn/miniapp/develop/ray/guide/optimization/startup/package-size)。

## 检查清单

| 检查项 | 优化方法 |
| ------ | -------- |
| 定时器是否在组件卸载时清理 | 及时清理定时器 |
| 事件监听是否在组件卸载时解绑 | 及时解绑事件监听 |
| 页面跳转方式是否合理 | 不需要返回的场景使用 redirectTo |
| 是否存储了过大的数据 | 使用分页加载，只保留当前页数据 |
