Realm-js: App performance become slow after added realm

Created on 17 Sep 2018  路  5Comments  路  Source: realm/realm-js

Goals

Our app is a chat app , we are going to use local realm database to save all message and we are using AsyncStorage now.
We think realm is better after we read the doc, so we want to use it.

Expected Results

All message saved in realm database and encrypted.
Chatroom will update and show the messages from database.

Actual Results

Messages are displayed, but the app become very slow for any actions.

Steps to Reproduce

Code Sample

This is the realmHelper.js

import Realm from 'realm'

export const DB_CHATROOM = 'ChatRoom'
export const DB_MESSAGE = 'Message'
export const DB_USER = 'User'

export const chatRoomSchema = {
    name: DB_CHATROOM,
    primaryKey: 'id',
    properties: {
        id: { type: 'string' },
        userId: { type: 'string' },
        messages: { type: 'list', objectType: DB_MESSAGE },
    }
}

export const messageSchema = {
    name: DB_MESSAGE,
    primaryKey: '_id',
    properties: {
        _id: { type: 'string' },
        type: { type: 'string' },
        text: { type: 'string' },
        createdAt: { type: 'date', indexed: true },
        user: { type: DB_USER },
    }
}

export const userSchema = {
    name: DB_USER,
    primaryKey: '_id',
    properties: {
        _id: { type: 'string' },
        name: { type: 'string' },
        avatar: { type: 'string', optional: true },
    }
}

const realmConfig = {
    path: 'theartalke.realm',
    schema: [chatRoomSchema, messageSchema, userSchema],
    schemaVersion: 1,
}

export const queryOrCreateChatRoom = (chatRoomId, userId) => new Promise((resolve, reject) => {
    Realm.open(realmConfig).then(realm => {
        realm.write(() => {
            let existQueryChatRoom = realm.objectForPrimaryKey(DB_CHATROOM, chatRoomId)
            if (!existQueryChatRoom) {
                existQueryChatRoom = realm.create(DB_CHATROOM, {
                    id: chatRoomId,
                    userId: userId,
                })
            }

            resolve(existQueryChatRoom)
        })
    }).catch(error => reject(error))
})

export const insertMessage = (chatRoom, incomeMessage) => new Promise((resolve, reject) => {
    Realm.open(realmConfig).then(realm => {
        realm.write(() => {
            let existMessage = realm.objectForPrimaryKey(DB_MESSAGE, incomeMessage._id)
            if (!existMessage) {
                let existUser = realm.objectForPrimaryKey(DB_USER, incomeMessage.user._id)
                if (!existUser) {
                    existUser = realm.create(DB_USER, {
                        _id: incomeMessage.user._id,
                        name: incomeMessage.user.name,
                        avatar: incomeMessage.user.avatar,
                    })
                }

                existMessage = realm.create(DB_MESSAGE, {
                    _id: incomeMessage._id,
                    type: incomeMessage.type,
                    text: incomeMessage.text,
                    createdAt: incomeMessage.createdAt,
                    user: existUser,
                })

                chatRoom.messages.push(existMessage)
            }

            resolve()
        })
    }).catch(error => reject(error))
})

we create or get the chatroom first.

const chatRoom = await realmHelper.queryOrCreateChatRoom(this.props.chatRoomId,
      this.props.userInfo.userId)

insert the new message

realmHelper.insertMessage(this.props.chatRoom, incomeMessages)
````

show the messages using GiftedChat ( FlatList )

messages={Array.from(this.props.chatRoom.messages.sorted([['createdAt', true], ['_id', true]]))}
....
/>
```

Version of Realm and Tooling

  • Realm JS SDK Version: 2.15.3
  • React Native: 0.56.1
  • Client OS & Version: IOS 11.4 and android 8.0
  • Which debugger for React Native: both tried
O-Community T-Help

Most helpful comment

Just briefly looking at the code, you probably don't want to open the Realm every time you want to insert an object - instead save it as a class-level variable upon first opening it and work with that single instance.

All 5 comments

How is performance when debugging is disabled (Debug JS Remotely disabled)?

  • Perhaps consider using a state variable to assign the FlatList's GiftedChat messages property?
  • The consider updating state.messages as needed.

@esutton Thanks for reply.
1, I tried disabled the debug and release mode and it is still slowly.
2, I also tried to set it be a state

the state

    this.state = {
      loading: false,
      sortedList: SortedList.create(props.cacheMessages, {
        unique: true, compare: (m1, m2) => {
          return m2._id.localeCompare(m1._id)
        }
      }),
      showBtnGoBottom: false,
      currentDate: '',
      messages: props.chatRoom.messages.sorted([['createdAt', true], ['_id', true]]),
    }

and update by listener

    realmHelper.realm.addListener('change', () => {
      this.setState({
        messages: this.props.chatRoom.messages.sorted([['createdAt', true], ['_id', true]])
      })
      this.handleMessages(this.state.messages)
    })

finally in giftedchat ( FlatList )

<GiftedChat
          dateFormat={'DD-MM-YYYY'}
          placeholder={I18n.t('chatroom_placeholder')}
          messages={this.state.messages}
....
/>

For few messages ( 10~20 ) , state.messages will be better.
But when messages are more than 500+ it become slow again.
In chat app, the messages must more than 500+


If i don't put messages in GitftedChat and let the code still running , it wont be slow.
Maybe is the problem of the messages and flatlist?

In GiftedChat FlatList code it is

<FlatList
          ref={(ref) => (this.flatListRef = ref)}
          keyExtractor={(item) => item._id}
          enableEmptySections
          automaticallyAdjustContentInsets={false}
          inverted={this.props.inverted}
          data={this.props.messages}
....
/>


Just briefly looking at the code, you probably don't want to open the Realm every time you want to insert an object - instead save it as a class-level variable upon first opening it and work with that single instance.

How is performance when debugging is disabled (Debug JS Remotely disabled)?

  • Perhaps consider using a state variable to assign the FlatList's GiftedChat messages property?
  • The consider updating state.messages as needed.

Thanks Eddie, I don't know why but when I enable "Remote JS debugging", my app becomes slower and takes time more than "disabled Remote JS debugging".

Just briefly looking at the code, you probably don't want to open the Realm every time you want to insert an object - instead save it as a class-level variable upon first opening it and work with that single instance.

Im newbie. You can show code example for me!

Was this page helpful?
0 / 5 - 0 ratings