---
title: Memory Optimization
docType: default
---

# Memory Optimization

Miniapps run within limited system resources. When memory usage is too high, the miniapp may be destroyed by the system or proactively reclaimed by the client, forcing users to reopen it — a very poor experience.

## Symptoms of Memory Issues

| Symptom | Possible Cause |
| ------- | -------------- |
| Miniapp suddenly crashes | Memory too high, reclaimed by system |
| Page gets slower over time | Memory leak; available memory gradually decreasing |
| Returning to a previous page is slow | Page stack too deep, consuming large amounts of memory |

## Listen for Memory Warnings

Use [onMemoryWarning](/en/miniapp/develop/ray/api/device/memory/onMemoryWarning#onmemorywarning) to listen for memory warning events and perform necessary cleanup when a warning is received:

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

onMemoryWarning((res) => {
  console.warn('Memory warning, level:', res.level);
});
```

## Avoid Memory Leaks

### Clean Up Timers Promptly

Timers associated with a component must be cleaned up when the component unmounts:

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

function fetchLatestData() {}

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

    return () => clearInterval(timer); // auto-cleanup on unmount
  }, []);
}
```

### Unbind Event Listeners Promptly

Registered event listeners should be unbound when the component unmounts:

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

function DevicePage() {
  useEffect(() => {
    const handler = (res) => console.log('Network status:', res.isConnected);
    onNetworkStatusChange(handler);

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

## Control Page Stack Depth

A deep page stack consumes large amounts of memory. Choose navigation methods wisely:

| Method | Effect | Use Case |
| ------ | ------ | -------- |
| `navigateTo` | Adds a new page to the stack | Navigating to pages you need to return from |
| `redirectTo` | Replaces the current page | Navigating without needing to return |
| `reLaunch` | Clears the page stack | Post-login redirect to home page, etc. |

## Control Data Scale

Avoid storing excessively large data in state or global variables. Use pagination to keep only the data needed for the current view:

```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]); // append, not replace
  };
}
```

## Control Package Size

Package size not only affects download time, but also directly impacts runtime memory. The package must be parsed and executed when loaded; the larger the package, the more memory it consumes. Reducing package size is an effective way to lower the memory baseline.

See [Package Size Optimization](/en/miniapp/develop/ray/guide/optimization/startup/package-size).

## Checklist

| Check Item | Optimization |
| ---------- | ------------ |
| Are timers cleaned up on component unmount | Clean up timers promptly |
| Are event listeners unbound on component unmount | Unbind event listeners promptly |
| Is page navigation approach appropriate | Use redirectTo for scenarios that don't need to return |
| Is excessively large data being stored | Use pagination; keep only current page data |
