代码注入优化

代码注入是小程序启动流程中继代码包下载后的关键阶段:基础库将开发者的 JS 代码加载进 JavaScript 引擎,依次完成解析、编译和执行。这个阶段的核心特点是——所有被加载模块的顶层代码都会在此刻立即执行,包括 App() 定义、全局变量初始化,以及 App.onLaunch / App.onShow 生命周期。

因此,优化代码注入耗时的核心思路是:尽量减少启动时必须执行的代码量,将不紧迫的工作推迟到真正需要时再做。

控制模块顶层的执行量

JS 模块的顶层代码(函数体以外的代码)在注入时会被立即执行。如果在顶层进行复杂计算、大量数据初始化或同步读取操作,这部分耗时会直接累加到注入阶段。

// 顶层的 transform 调用在注入时立即执行
const processedList = rawList.map(item => heavyTransform(item));

// 推迟到真正需要时再处理
function getProcessedList() {
  if (!_cache) _cache = rawList.map(item => heavyTransform(item));
  return _cache;
}

减少同步 API 的调用

在启动过程中,高频调用 TTT 能力可能会阻塞 JS 线程,影响代码执行。应尽量减少或不调用同步 API,绝大多数同步 API 以 Sync 结尾。

缓存机制:

  • 基础库对以下接口做了一层缓存,避免重复调用:

    • getLaunchOptions
    • getLaunchOptionsSync
  • 以下接口调用频繁,但含有动态数据,无法直接缓存,可自行处理缓存:

    • getSystemInfo
    • getSystemInfoSync

注意:涉及 system、brand、model、platform 等数据可调用 getDeviceInfo 接口,该接口已做缓存

  • 以下接口包含动态数据,暂不处理,业务层可自行缓存逻辑:
    • getDeviceInfo
    • getGroupInfo
    • getCustomConfig

非持久化存储可通过 globalData 存储,而非 getStorage 接口。

精简 App 初始化的工作量

Ray 项目的 app.tsx 在注入阶段会立即执行。常见误区是把所有初始化工作都集中在这里:

// ❌ 避免:把不紧迫的逻辑堆在启动时执行
initSDK();         // 必要
checkLogin();      // 必要
loadUserConfig();  // 不紧迫,可延迟
reportAnalytics(); // 不紧迫,可延迟
checkAppUpdate();  // 不紧迫,可延迟

建议只保留真正影响首屏的逻辑(如登录态检查),其余操作延迟到首页组件挂载后再执行:

// ✅ 推荐:非必要初始化推迟到首页挂载后
function HomePage() {
  useEffect(() => {
    loadUserConfig();
    reportAnalytics();
    checkAppUpdate();
  }, []);
}

检查清单

检查项优化方法
模块顶层是否有复杂计算改为懒执行,在需要时再计算
是否有大量同步 API 调用减少或替换为异步 API,使用基础库缓存接口
App 初始化是否包含非必要逻辑延迟到首页组件挂载后再执行