Q-select with large data sets: performance, details about lazy-loading
-
Hi,
I recently had to import a pretty large list of options into my app (~2500 items) that are used by a single component containing several q-selects with user-input/filtering. The data is pulled down from Firebase realtime DB on load and set into Vuex, and the q-select options are generated from a vuex getter that maps over objects in state and returns an array of name strings.
The app is still performant from a user perspective, but the Vue devtools now crash consistently before opening on pages containing these q-selects. I didn’t have this issue until the import, so I assume this is due to the size of the data.
I don’t have much experience debugging perf issues, so I have questions:
- Is there an aspect of this flow that is problematic?
- Does Q-select start to have issues as the size of the data set grows - ie. is q-select’s parsing of the data the likely culprit, or is it how I am handling the data in general?
- Are performance issues multiplied by having multiple q-selects in the same component, even if they pull from the same data?
- Would lazy-loading (from state) be a solution to this problem, and are there any examples of this I could look at? (I prefer longer, larger initial loading times to repeated queries to the backend). In general, I’m not sure if I need to be limiting the data received by my component, or limiting the values available/displayed at a given time by each select.
Some of the questions are redundant - just curious to hear strategies about lazy-loading/handling large data sets with q-selects/debugging perf issues.
-
In general, I’m not sure if I need to be limiting the data received by my component, or limiting the values available/displayed at a given time by each select.
both, but most of the time I would say:
displayed
Easy trick for me that really helped was to freeze a big set of data in vuex. So you could try to freeze the options before you store the options in vuex:
Vue.set(this.state.options) = Object.freeze(list_of_options);
-
Wow, I don’t know how/why this works, but I tried it and my console no longer freezes up. Thanks! Do you happen to remember your source for this? Or is this just something I should know about as a dev? I’ve never used Object.freeze before.
Also, don’t know if this makes a difference but since the data is received from firebase inside a “child_added” listener, I am freezing each individual object rather than the entire list. I wonder if, despite the positive outcome, this is in fact achieving the desired effect.
-
@dmoylan you see the usage example in some quasar components that uses large data with virtual scroll. Api https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze example usage https://quasar.dev/vue-components/select#Render-performance, https://quasar.dev/vue-components/table#Virtual-scrolling, https://quasar.dev/vue-components/virtual-scroll#Usage
Why it’s ideal for such use case is explained in the tip section of the last link above.
-
@metalsadman Thanks for the reference - that makes sense. Quasar docs never fail!
Also, unrelated to Quasar but I found that what was crashing my Vue devtools was the firing of 2k+ mutations through Firebase’s child_added listener. Calling ref.once(‘value’) on load and then setting the full list through a single mutation fixes this issue.