Possible Bug: App.vue: watch route

Post Reply
tyra
Posts: 2
Joined: 07 Jun 2021, 20:08

20 Jul 2021, 08:51

In my vue app I had a severe performance problem, where the UI hang for several seconds after triggering certain actions.

In the original primevue freya source in App.vue there is the following code:

Code: Select all

    watch: {
        $route() {
            this.menuActive = false;
            this.$toast.removeAllGroups();
        },
    },
I translated this to composition API in the following way:

Code: Select all

    const route = useRoute();
    const toast = useToast();
    watch(
      () => route,
      () => {
        menuActive.value = false;
        toast.removeAllGroups();
      }
    );
under certain conditions this might produce severe performance problems in production environments (but not in dev environments).
To solve the possible problems I would suggest the following composition API code:

Code: Select all

    const route = useRoute();
    const toast = useToast();
    watch(
      () => route.fullPath,
      () => {
        menuActive.value = false;
        toast.removeAllGroups();
      }
    );
so not the complete reactive route object is watched but just the fullPath property.

quote from the vue router manual:
The route object is a reactive object, so any of its properties can be watched and you should avoid watching the whole route object. In most scenarios, you should directly watch the param you are expecting to change
Note: it might be, that the problem exists only with composition api, I did not test the old api.

Note2: I don't know the exact trigger of the problem. In one case I added a query parameter to the current route in an other case i changed the text of a component inside the freya left side menu.

As a search engine trigger:
In the chrome dev console a warning appears, that helped me to find the source of the vue 3 performance problems with the freya layout:
[Deprecation] 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
This warning seems to come from a 'window' object within 'route'.

tugce.kucukoglu
Posts: 153
Joined: 23 Oct 2020, 09:28

21 Jul 2021, 14:39

Hi,
Note2: I don't know the exact trigger of the problem. In one case I added a query parameter to the current route in an other case i changed the text of a component inside the freya left side menu.
What exactly did you mean? How can I replicate the problem? Did you change the AppMenu.vue or add a programmatic control over the menu?

tyra
Posts: 2
Joined: 07 Jun 2021, 20:08

21 Jul 2021, 15:10

Hi

thanks for your interest.

One component that is a possible trigger the following code in the setup method:

Code: Select all

    const searchTerm = ref<string>(
      typeof queryParameter === "string" ? queryParameter : ""
    );

    // on routes query change: update the graphql query
    watch(
      () => route.query.query,
      () => {
        const queryParameter = route.query["query"] ?? "";
        searchTerm.value =
          typeof queryParameter === "string" ? queryParameter : "";
      }
    );

    // on currents query searchTerm change: update the routes query parameter
    watch(searchTerm, currentSearchTerm => {
      if (route.name === "search" && route.query.query !== currentSearchTerm) {
        router.replace({ name: "search", query: { query: currentSearchTerm } });
      }
    });
if I put log statements in the watches code, they are only executed one time. However, this is the only real difference to other components, where I did not experience this performance problem.
In the chrome dev tools, I could see, that the browser was in a near endless loop inside vue's watch logic. As I don't know all the objects in route (obviously 'window') and especially not their children, I don' t know exactly what is going on. However even 'window' might not, what we want to watch - and the vue docs mention that we should avoid watching route.

After finally having limited the global 'route' watch in 'App.vue' to a more specific watch, the problem has been gone.

the other case is a regular component with a button within the menu:

Code: Select all

<!-- AppMenu.vue -->
<div ..>
    <AppSubmenu .../>
    <MyComponent />
</div>
MyComponent has a button. onClick it will do an rpc call and thru a reactive GraphQl result update its interface. Nothing special in my opignon.
However, without the above patch, after pressing the button, the menu was very sluggish for half a minute and the browser tab task showed > 100% cpu.
After I integrated above patch, the problem was solved here as well.

As I mentioned: I work in a composition API environment. I don't know if it happens in options API as well. Also I did not exist before I integrated the Freya Layout.

I am sorry, that I cannot provide a minimal replication of the problem.


However I would suggest the update of the route watch anyway, as it might make sense to watch only a defined set of properties, so side effects are smaller and the code documentation is more clear.

tugce.kucukoglu
Posts: 153
Joined: 23 Oct 2020, 09:28

24 Jul 2021, 20:36

Hi,
However, without the above patch, after pressing the button, the menu was very sluggish for half a minute and the browser tab task showed > 100% cpu.
This is very interesting because I have never encountered anything like this before. First, I think it might be related to the rpc call but I'll do a check anyway. Being able to reproduce the problem is important because it is very difficult for me to tell which side the problem originates from right now. I will also update the documentation if needed.

Thanks for the great feedback.

Best,

Post Reply

Return to “Freya - PrimeVue”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 1 guest