Hello. I profiled my application to eliminate micro lags in a large table. There are 3 fields in it that are Multiselect with a large number of options, and 100 rows per page. The table is reactive and updated via WebSocket, but each update was accompanied by micro lags, especially noticeable on mobile devices.
After reviewing the code, I identified several opportunities for improvement, here are some of them:
Avoid unnecessary array allocations, especially for functions like isNullish() and aria-* getters.
Eliminate prop checks after toRefs(), they are specified in SFC, so they will never be undefined. The same goes for resolveDeps(), a hook can't be undefined.
Quickly exit the arraysEqual() function if the array sizes do not match. In the current implementation, it sorts the array first and then checks.
Replace ref() with shallowRef() for binding HTML. This is a common use case for shallowRef(); it will only track the setting of the value, not every HTML property.
Replace most computed() with toRef(). Instead of having a cache for simple getters, it's cheaper to directly call them. Currently, a polyfill is used to implement toRef(). Since the change toRef() appeared only in Vue 3.3+, this polyfill is slightly slower than the standard implementation, but it's the same one used in VueUse.
After these changes and subsequent profiling, I conclude that the micro lags have disappeared, the average memory consumption per page has decreased, the page opening time has become approximately twice as fast on mobile devices, and the INP metric has also improved.
Hello. I profiled my application to eliminate micro lags in a large table. There are 3 fields in it that are Multiselect with a large number of options, and 100 rows per page. The table is reactive and updated via WebSocket, but each update was accompanied by micro lags, especially noticeable on mobile devices.
After reviewing the code, I identified several opportunities for improvement, here are some of them:
isNullish()
andaria-*
getters.toRefs()
, they are specified in SFC, so they will never be undefined. The same goes forresolveDeps()
, a hook can't be undefined.arraysEqual()
function if the array sizes do not match. In the current implementation, it sorts the array first and then checks.ref()
withshallowRef()
for binding HTML. This is a common use case forshallowRef()
; it will only track the setting of the value, not every HTML property.computed()
withtoRef()
. Instead of having a cache for simple getters, it's cheaper to directly call them. Currently, a polyfill is used to implementtoRef()
. Since the changetoRef()
appeared only in Vue 3.3+, this polyfill is slightly slower than the standard implementation, but it's the same one used in VueUse.After these changes and subsequent profiling, I conclude that the micro lags have disappeared, the average memory consumption per page has decreased, the page opening time has become approximately twice as fast on mobile devices, and the INP metric has also improved.