Open Bartheleway opened 4 months ago
Hi - thanks for opening this issue.
The usual cause of performance issues is that the normalised data returned by pinia-jsonapi can be recursive, or massively branching, meaning that any code that walks the returned data may continue forever or use excess memory trying to build an object representation. There are some places in the code where we try to prevent recursion, but this is not always possible.
The easy way to check this is to either use console.log
to examine the data and look for recursion, or use another 'walking' library (like JSON.stringify
) and see if the same issue occurs.
Equally, if you are only interested in id
and name
and don't need any of the relationships mapped out, then setting the config option followRelationshipsData: false
should remove opportunities for recursion.
Let us know if this fixes the issue - otherwise if you can share the contents of records
we can have another look to see if there are any obvious issues there.
Hi, thanks for this explaination. While it does make sense, I don't really get why I am getting such performance issues when I am not following the relationships.
Does the lib follow all relationships even if we don't call them in the page?
The issue is not that pinia-jsonapi
follows relationships, but that other libraries which are passed the normalised object may do so - the commonest is JSON.stringify
but anything which attempts to get property values from an object may be susceptible. In this case it is likely that v-autocomplete
is 'walking' the object and recursing.
This issue can be avoided by one of: a) Disabling the mechanism which constructs related getters (followRelationshipsData: false
); b) using map
or similar to extract only the attributes you need from the object; or c) using a library which doesn't walk objects.
Cristal clear :)
I don't know exactly how v-autocomplete
from Vuetify works. Honestly I tried to look into the source but didn't understand at which point they might walk through the object. I find it a bit disapointing that mixing pinia-json with Vuetify oblige me to use map
or disable followRelationshipsData
instead of being able to use a record list out of the box.
I did some tests today:
map
indeed solve the perf issuefollowRelationshipsData: false
also solve the issueI also tested to use the record list out of the box and check if any network calls were made. None appears. This makes me think issue is maybe with using shallowRef
on items of the list thus this would say issue is more with Vue itself than with Vuetify. What do you think?
Ultimately JSONAPI can return recursive relationships, and by default pinia-jsonapi
will convert these to references which can be followed. If any code tries to follow these, then it will lead to infinite recursion.
I wouldn't expect any extra network calls to be made here - all the data is returned from the server and normalised in the original request.
While it is an extra step to prevent this recursion, if you don't need the referenced relationships, or there are attributes and relationships you aren't using, then it is a good idea generally to disable/remove these - not just for this issue, but for overall performance.
Perhaps the best way to do this (which I forgot to mention previously) is to use 'sparse fieldsets' on the JSONAPI request. This means that the server won't even try to calculate and return the data you don't need, making the response quicker and smaller: https://jsonapi.org/format/#fetching-sparse-fieldsets
Yes using sparse field as well as followRelationshipsData
are both valid approch with what you previously explained. Sparse fieldsets allowing more control about what is returned than just disabling all relationships.
Unfortunately in my case my API doesn't support (yet) sparse fieldsets.
I will use the map
or followRelationshipsData
for now and check how to implement fieldsets eventually.
I can work with that and very thankfull for explaination & solution provided.
To pursue the discussion about "code trying to follow relationship", I really don't have any code written that would do that. And I believe this is a side effect of shallowRef
used internally by Vuetify and Vue. Do you believe there is any chance it comes from here / be solved ?
Hi, I'm opening this thread as I discovered that this package seems responsible of some huge performance issues I'm facing with my app.
I basically workaround this issue by creating a computed value based on a list of value coming from this lib and generating a simplified version of it.
If I use directly
records
in av-autocomplete
(it uses a virtual-scroller behind the scene), I can see my CPU going crazy, page freezes and can take up to 5min to display the 10 items. If I use the computed value, display is taking some milliseconds.Do you have any idea why this is happening? Does other people have the same issue?
P.S: I also opened an issue on Vuetify side as I was first thinking issue was on their side. I believe issue is more on this library now.