Hi to cut to the chase the performance of our react native app is terrible and its down to how we are using realm.
We are leaning heavily on adding listeners to collections to update the UX, and these listeners fire all too frequently, and with seemingly massive amounts of changes reported.
After looking into it, I think this is due to my misunderstanding of how realm works WRT the schema and modifications to entities - Ive done some tests to confirm my suspicions, but Id really appreciate some clarity around the issue so that I can work out a proper solution.
The main issue is that our schema has an entity type that is commonly related to a bunch of other entities. Ill give an example.
lets say we have many Pets, Toys & Books. Also a couple of Childs.
This relationship is common: Pet.child Toy.child Book.child
Such that, if I update a specific Child, I am likely to trigger an update in many Pets, Toys & Books that have a relationship with that Child
So this is one source of inefficiency - am I right so far?
If each item had a ‘foreign key’ type of reference to its Child owner, or the Child itself had a collection of owned items, then this disproportionate update would not occur?
Second source of inefficiency is how our app creates/updates entities from the backend. We use a ‘PUT’ type of operation, rather than a ‘PATCH’. That is, the schema is almost identical to the structure of the entities coming from the backend. Our Pet API does return a Pet with a Child relationship. We know that something about the Pet has changed, but we dont know what - so we PUT the entire Pet and Child when we update the database, rather than writing only a specific attribute that has changed.
example. Lets say the backend sends us a modified Pet , which is owned by John. The Pets colour has changed for some reason. We write the new Pet and Pet.child to the DB. Realm considers John has been changed because we are writing it, and now every Pet, Toy and Book owner by John is also changed, even though we just updated a single Pets colour.
This is what I observe from our collection listeners firing and the nature of the changes they are reporting
The upshot is that whenever something changes it seems that many other types things are updated as a consequence, even though they havent changed.
Lastly, another thing we are doing which Id like clarification about is when the backend does not supply the Child belonging to a Pet with the Pet, but only the Child’s id…
To be clear, our example Schema looks like this:
Pet {
id: string
name: string,
colour: string,
owner: Child
}
Child {
id: string,
name: string
}
And in some circumstances we would recieve this from the backend:
Pet.id = 3, Pet.name = fido, pet.colour=brown, owner.id = 9
And we would write this to the DB
Pet = {
id: 3,
name: fido,
colour: brown,
owner: {
id:9
}
}
which will write any changes to Pet, and simply maintain the 1:1 relationship with the Child , without writing any changes to the Child itself.
In this situation, I believe that Realm still considers the Child to have been modified? Is this correct?
phew, thats enough for now. I can anticipate that some comments will be, why is your schema like that? In part its because it mirrors the structure of entities coming to us from the backend, and … we didnt know any better. And also having the relationship in the Pet/Child/Toy is simple and useful. If you are dealing with a list of Books, finding the owner is easy. It seems natural to structure the schema this way.
Thanks for any help, confirmation, discussoin this generates.
Steve