You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Realm本地数据库读写大对象过慢致React Native应用卡顿求助

问题描述

需要在10-20秒内将BLE监听器获取的6000个对象写入Realm数据库,目前尝试一次性写入全部对象速度极慢,改为批量写入200个对象后仍耗时较长,且读写过程中React Native应用出现卡顿,寻求优化方案。

BLE数据处理代码

let a = [];
let arrayBuffer = [];
const handleNotificationUpdate = data => {
  if (data) {
    let byteArray = data.value;
    const hexArray = byteArrayToHexArray(byteArray);
    const packets = separatePackets(hexArray);
    const decimalArrays = packets.map(packet => packet.map(hex => parseInt(hex, 16)));
    const extractedValues = extractValuesFromPackets(decimalArrays);

    // Adding activityType and currentTime to objects
    const currentDate = new Date();
    const options = {
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit',
      hour12: true,
      timeZone: 'Asia/Karachi', // Pakistan timezone
    };
    const currentTime = currentDate.toLocaleString('en-PK', options);

    extractedValues.forEach(obj => {
      if (!obj.hasOwnProperty('activityType')) {
        obj.activityType = 1;
      }
      obj.currentTime = currentTime;
    });

    // Filter out objects with activityType undefined
    const filteredValues = extractedValues.filter(obj => obj.activityType !== undefined && obj.packetEndHeader !== undefined);

    arrayBuffer.push(filteredValues);
    handleArrayBuffer();
    a = filteredValues;
    console.log(arrayBuffer.length);
  }
};

const handleArrayBuffer = () => {
  if (arrayBuffer.length === 200) {
    console.log('000000000');
    insertDataIntoRealm(arrayBuffer);
    arrayBuffer = [];
  }
};

Realm操作代码

import Realm from 'realm';

const Array2Schema = {
 name: 'Array2',
 properties: {
   activityType: 'int',
   currentTime: 'string',
   greenLed1Counts: 'int[]',
   greenLed2Counts: 'int[]',
   irLedCounts: 'int[]',
   outputFormat: 'int',
   packetEndHeader: 'int',
   packetStartHeader: 'int',
   redLedCounts: 'int[]',
   temperatureSensor: 'int[]',
   time: 'int[]',
   xAxisReading: 'int[]',
   yAxisReading: 'int[]',
   zAxisReading: 'int[]',
 },
};

const Array1Schema = {
 name: 'Array1',
 properties: {
   array2: 'Array2[]',
 },
};

const openRealm = async () => {
 return Realm.open({
   schema: [Array2Schema, Array1Schema],
   schemaVersion: 1,
 });
};

const insertDataIntoRealm = async (arrayData) => {
 try {
   const realm = await openRealm();

   realm.write(() => {
     arrayData.forEach((array2Items) => {
       const array1 = realm.create('Array1', {});
       array2Items.forEach((item) => {
         const array2 = realm.create('Array2', item);
         array1.array2.push(array2);
       });
     });
   });

   realm.close();
 } catch (error) {
   console.log('Error:', error);
 }
};

export { insertDataIntoRealm, openRealm };
优化方案

以下是针对性能和卡顿问题的具体优化点:

1. 复用Realm实例,避免频繁打开/关闭

每次调用insertDataIntoRealm重新打开和关闭Realm会产生巨大开销,改成单例模式复用实例:

// Realm文件中修改openRealm为单例
let realmInstance = null;
const openRealm = async () => {
  if (realmInstance && !realmInstance.isClosed) {
    return realmInstance;
  }
  realmInstance = await Realm.open({
    schema: [Array2Schema, Array1Schema],
    schemaVersion: 1,
  });
  return realmInstance;
};

// 移除insertDataIntoRealm中的realm.close(),仅在应用退出时关闭实例
const insertDataIntoRealm = async (arrayData) => {
 try {
   const realm = await openRealm();

   // ... 写入逻辑 ...

   // realm.close(); // 注释关闭操作
 } catch (error) {
   console.log('Error:', error);
 }
};

2. 使用异步写入避免阻塞主线程

同步realm.write()会阻塞UI线程导致卡顿,改用异步的realm.writeAsync():

const insertDataIntoRealm = async (arrayData) => {
 try {
   const realm = await openRealm();

   await realm.writeAsync(() => {
     arrayData.forEach((array2Items) => {
       const array1 = realm.create('Array1', {});
       // 优化:直接赋值数组替代逐个push,减少操作次数
       array1.array2 = array2Items.map(item => realm.create('Array2', item));
     });
   });
 } catch (error) {
   console.log('Error:', error);
 }
};

3. 简化Schema设计,减少不必要的嵌套

如果Array1仅用于包裹Array2数组,无其他业务属性,可直接存储Array2对象,减少一层嵌套开销:

// Realm文件中移除Array1Schema,修改openRealm
const openRealm = async () => {
 return Realm.open({
   schema: [Array2Schema],
   schemaVersion: 2, // 升级版本号
 });
};

// 简化写入逻辑,直接批量创建Array2对象
const insertDataIntoRealm = async (objects) => {
 try {
   const realm = await openRealm();
   await realm.writeAsync(() => {
     // 批量创建比循环逐个create性能提升显著
     realm.create('Array2', objects, true); // true表示允许更新重复对象,按需调整
   });
 } catch (error) {
   console.log('Error:', error);
 }
};

// 对应修改BLE数据处理中的arrayBuffer逻辑,直接存储单个对象而非数组
const handleNotificationUpdate = data => {
  // ... 其他逻辑 ...

  // 替换arrayBuffer.push(filteredValues)为:
  filteredValues.forEach(item => arrayBuffer.push(item));
};

const handleArrayBuffer = () => {
  if (arrayBuffer.length >= 200) {
    // 取出前200个对象批量写入
    const batch = arrayBuffer.splice(0, 200);
    insertDataIntoRealm(batch);
  }
};

4. 优化数据预处理逻辑

  • 缓存时间格式化配置,避免重复创建:
// 把timeOptions提到函数外部缓存
const timeOptions = {
  year: 'numeric',
  month: '2-digit',
  day: '2-digit',
  hour: '2-digit',
  minute: '2-digit',
  second: '2-digit',
  hour12: true,
  timeZone: 'Asia/Karachi',
};

const handleNotificationUpdate = data => {
  if (data) {
    // ... 其他逻辑 ...
    const currentTime = new Date().toLocaleString('en-PK', timeOptions);
    // ... 其他逻辑 ...
  }
};
  • 移除不必要的console.log,生产环境日志会拖慢性能。

5. 调整批量写入粒度

根据设备性能调整批量大小(如尝试500个对象/批),平衡写入效率和内存占用。


内容的提问来源于stack exchange,提问作者Hamza Qayyum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 02:54:55