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

SymptomPossible Cause
Miniapp suddenly crashesMemory too high, reclaimed by system
Page gets slower over timeMemory leak; available memory gradually decreasing
Returning to a previous page is slowPage stack too deep, consuming large amounts of memory

Listen for Memory Warnings

Use onMemoryWarning to listen for memory warning events and perform necessary cleanup when a warning is received:

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:

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:

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:

MethodEffectUse Case
navigateToAdds a new page to the stackNavigating to pages you need to return from
redirectToReplaces the current pageNavigating without needing to return
reLaunchClears the page stackPost-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:

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.

Checklist

Check ItemOptimization
Are timers cleaned up on component unmountClean up timers promptly
Are event listeners unbound on component unmountUnbind event listeners promptly
Is page navigation approach appropriateUse redirectTo for scenarios that don't need to return
Is excessively large data being storedUse pagination; keep only current page data