Vue-meta: Performance issue on big pages

Created on 12 Oct 2018  路  11Comments  路  Source: nuxt/vue-meta

I've a performance issue in Nuxt, that apparently comes from vue-meta.
When creating a certain number of elements (here 50 items from a Vuetify list each with a few child components), vue-meta getMetaInfo accounts for more than 50% of the processing time:

Chrome Dev Tools

Also when clearing that list, vue-meta takes about 200ms, and the actual clearing by Vue takes only 15ms:

Chrome Dev Tools

I think it's by design due to the fact that vue-meta goes recursively through the whole components tree, which is quite expensive.
I propose adding a feature in vue-meta where a component can declare an option to tell vue-meta to not recurse through it's children. In my case I know that I won't put meta in other places than pages, so that would be a huge performance gain.

EDIT: Just thought about a bit more the option would probably need to be propagated to the children... Which kinda renders it useless. I'm not exactly sure how to solve this :(.

EDIT2: Just looked at the implementation, and the refresh for meta actually starts from the root each time \o/, so the option should work ;). I could try to do a PR for this?

enhancement v2

All 11 comments

Would it maybe be possible to implement some kind of event based mechanism?

Something like when a component is created it 'registers' with vue-meta _if needed_, and if vue-meta wants to refresh it can just request all registered components to send their meta data? Then we wouldnt have to traverse any tree at all.

@pimlie I really like the idea, we would have to make sure to deregister on destroy to avoid memory leak, but I don't see a disadvantage to this compare to browsing the whole tree. Would be quite a big change though.
@manniL do you know of anything that would prevent us to do that?

EDIT: Hum actually, the issue would be keeping the order parent <-> child, we would need to build some kind of tree that mimics the component tree but only with components that have meta information.

As a registering mechanism would possibly result in a flattened structure, we have to make sure we still have logic in place so child components can only overwrite the same data as their parents, and not e.g. data from (the child of) a parent's sibling.

@pimlie I would have more thought of maintaining a simple tree structure with a side Map component => Node in the tree. Then when your register a component, you go back up it's parent chain, find the first parent component that is in the map, get it's node in the tree and add it as child.
As the number of element with meta info is probably not too big it would be less costly to do this + browsing the small tree than browsing the whole component tree each time.

New development in the investigation ;).
I was wondering why changing my search was triggering a refresh from vue-meta. From the code of vue-meta, refresh should only occur if a component with meta is created/deleted, and this was not the case there.
I checked what was triggering and it turns out that every components in my app has meta info! The source is apparently Nuxt i18n, and more precisely this mixin:
https://github.com/nuxt-community/nuxt-i18n/blob/master/src/plugins/seo.js#L3

The mixin registers head() for every single component. Also this method checks whether this._hasMetaInfo is true for the component, but it is always true as this._hasMetaInfo is set to true if the method head is defined. (see: https://github.com/declandewet/vue-meta/blob/master/src/shared/plugin.js#L47 and https://github.com/nuxt/nuxt.js/blob/dev/lib/core/meta.js#L17)

So the solution would probably first to fix the issue in Nuxt i18n. What do you think @manniL @pimlie ?
And moreover this mixin combined with the one from Vuetify create this bug: https://github.com/nuxt/nuxt.js/issues/3846

The performance improvement with the registration suggested by @pimlie would still be good though IMO 馃憤

@adrienbaron Interesting results! Focussing on resolving the nuxt-i18n "problem" would be a great start I think. While attacking that front, we might come to conclusions that help for the global "issue" there :relaxed:

I think a way to say "hey, my children won't have any more information" won't be wrong as well to prune parts of the tree that must be traversed.

Nice found. I also found that seo option in nuxt-i18n cause issues, for example when you have long page transition, then when switching pages meta title blinks with default value, wich is inappropriate, so I turned seo: false and made this tags myself.

@bdrtsky You can checkout this documentation on how to improve perfs of Nuxt i18n SEO (and avoid them being recomputed for every component rerendering on the page): https://github.com/nuxt-community/nuxt-i18n/blob/master/docs/seo.md#improving-performance

Great link, didn't saw that before, thanks @adrienbaron

Closing as changes for this issue are included in the v2 release candidate. Please help us testing the release candidate and report any follow-ups in a new issue

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hurradieweltgehtunter picture hurradieweltgehtunter  路  4Comments

DRoet picture DRoet  路  9Comments

dysol picture dysol  路  6Comments

vishr picture vishr  路  5Comments

hvalcourtSerdy picture hvalcourtSerdy  路  3Comments