---
title: Code Injection Optimization
docType: default
---

# Code Injection Optimization

Code injection is the critical phase after package download in the miniapp startup flow. The base library loads developer JS code into the JavaScript engine, completing parsing, compilation, and execution in sequence. The key characteristic of this phase is that **all top-level code in loaded modules is executed immediately** — including `App()` definition, global variable initialization, and `App.onLaunch` / `App.onShow` lifecycle callbacks.

The core strategy for optimizing code injection time is: **minimize the amount of code that must run at startup, and defer non-urgent work until it's actually needed**.

## Minimize Top-Level Execution

Top-level module code (code outside function bodies) executes immediately at injection time. Performing complex computations, large data initialization, or synchronous reads at the top level adds directly to injection time.

```javascript
// Top-level transform call executes immediately at injection
const processedList = rawList.map(item => heavyTransform(item));

// Defer processing until actually needed
function getProcessedList() {
  if (!_cache) _cache = rawList.map(item => heavyTransform(item));
  return _cache;
}
```

## Reduce Synchronous API Calls

Frequent TTT capability calls during startup may block the JS thread and slow code execution. Minimize or eliminate synchronous API calls (most synchronous APIs end with `Sync`).

**Caching mechanism:**

- The base library caches the following APIs to avoid repeated calls:
  - `getLaunchOptions`
  - `getLaunchOptionsSync`

- The following APIs are called frequently but contain dynamic data that cannot be cached directly; handle caching yourself:
  - `getSystemInfo`
  - `getSystemInfoSync`

> For data related to `system`, `brand`, `model`, `platform`, use the [getDeviceInfo](/en/miniapp/develop/miniapp/api/base/system/getDeviceInfo) API, which has built-in caching.

- The following APIs contain dynamic data with no built-in caching; implement caching at the business layer:
  - `getDeviceInfo`
  - `getGroupInfo`
  - `getCustomConfig`

> For non-persistent storage, prefer `globalData` over the `getStorage` API.

## Streamline App Initialization

In a Ray project, `app.tsx` executes immediately during injection. A common mistake is placing all initialization logic here:

```tsx
// ❌ Avoid: stacking non-urgent logic at startup
initSDK();         // necessary
checkLogin();      // necessary
loadUserConfig();  // not urgent, can be deferred
reportAnalytics(); // not urgent, can be deferred
checkAppUpdate();  // not urgent, can be deferred
```

Keep only logic that affects the first screen (such as login state checks). Defer everything else until after the home page component mounts:

```tsx
// ✅ Recommended: defer non-essential initialization
function HomePage() {
  useEffect(() => {
    loadUserConfig();
    reportAnalytics();
    checkAppUpdate();
  }, []);
}
```

## Checklist

| Check Item | Optimization |
| ---------- | ------------ |
| Complex computation at module top level | Convert to lazy execution; compute only when needed |
| Many synchronous API calls | Reduce or replace with async APIs; use base library cached APIs |
| Non-essential logic in App initialization | Defer to after home page component mounts |
