0

I've build a rather large Vue.js application (like >80 .vue components). My users complain about their draining phone batteries, safari throws a “This webpage is using significant energy...” notice.

How can I possibly find out what's going on? I tried playing around with the performance tab of Chrome and Lighthouse, but didn't really find out anything.

Here are a few things that I feel might have a bad influence:

  • I have a quite a few watchers that keep an eye on vuex states, because it would be a stupid amount of work to pass information up and down components. This has led to a massive store.js file with a ton of variables that are used all over my application.

  • I also use computed properties a lot

  • I have a couple event listeners on events like resizing the window

Hillcow
  • 890
  • 3
  • 19
  • 48
  • yes ... it could be one of those ... or *something else* - hope that helps – Jaromanda X Aug 02 '22 at 08:38
  • 1
    How did you try using the performance dev tools? You can also enable JavaScript CPU throttling in the dev tools to simulate a mobile device, and then "feel around" for slow interactions – the slower, the more work is done, and the more energy is drained. – AKX Aug 02 '22 at 08:39
  • Okay, so this is interesting: While doing absolutely nothing (no scrolling, no mouse interaction or anything else) my app is constantly rendered and drawed: https://imgur.com/a/PT1tdwP why could that be? – Hillcow Aug 02 '22 at 08:55
  • Based on your comment and my past experiences, there are some changes that would change some states (MAYBE computed properties) which are causing other state changes which loop back and change the former states. Even though the values are the same as before, these changes are checked and components are re-rendered accordingly. try comparing these current states with the past ones. – AhmadDeel Aug 02 '22 at 09:05
  • Thanks @AhmadDeel, how can I compare them if nothing has changed? – Hillcow Aug 02 '22 at 09:07
  • With this in mind, you need to utilise [VueDevTools](https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd?hl=en) debugger, and see what's causing this data state change loop. – Jack_Hu Aug 02 '22 at 09:24
  • @Jack_Hu how? The data doesn't change. – Hillcow Aug 03 '22 at 07:54
  • I'm not able to debug your app without a) Seeing it, or b) Seeing any code. If your page is being constantly rendered, and redrawn, then you're either causing the DOM to be reflowed by changing some primary CSS attribute (so, something like `margin`, or `height`, as opposed to `transform`), you're adding/removing DOM elements constantly, or a Vue component that's bound to a piece of data is being changed, so Vue is seeing a change in it's virtual DOM, and updating the actual DOM accordingly. – Jack_Hu Aug 03 '22 at 08:48
  • My best guess would be that the latter might be the case. But how could I find the component if there is not actual data change? @Jack_Hu thanks – Hillcow Aug 03 '22 at 10:31
  • 1
    Unless you know where the issue lies, or VueDevTools shows any data attributes changing (there's also an option to highlight components that change in its settings - https://i.imgur.com/O7i3IUI.png - for an example). Then your next best bet would be to go through the process of elimination, and remove components until the issue stops, and then re-introduce them, until it returns. Then you'll know where the issue is coming from. – Jack_Hu Aug 03 '22 at 10:42

1 Answers1

3

I have a quite a few watchers that keep an eye on vuex states, because it would be a stupid amount of work to pass information up and down components. This has led to a massive store.js file with a ton of variables that are used all over my application.

Why do you use observatories for vuex states? In reality, the information stored in the vuex stores are already reactive with respect to the components so it should not be necessary to use observers.

I also use computed properties a lot

The computed properties are very heavy for the system to manage, they should be used sparingly and above all only and only where they are strictly necessary.

I have a couple event listeners on events like resizing the window

Make sure you delete the event listener once the component is destroyed

Jack_Hu
  • 857
  • 6
  • 17
Francesco
  • 51
  • 4
  • When something is happening in a component x that should trigger some method in component y I use vuex to set a variable for that in x and listen for a change in y. I guess there is a better way to do this? – Hillcow Aug 02 '22 at 08:56
  • I think the observers on the vuex states are probably what's killing it. You're basically doubling the amount of watching that's going on. – Jack_Hu Aug 02 '22 at 08:56
  • @Hillcow - There is. You derive the functionality from the same variable... If: Components = `x` and `y`, Variable = `z`.... If something happens in `x`, which changes `z`. `y` should be bound to `z`, and Vue will automatically detect that `z` has changed, and action `y` accordingly. You don't need to observe it explicitly, and add a watcher, Vue is already taking care of that for you. – Jack_Hu Aug 02 '22 at 09:07
  • But in `y` I have a complex method that should be run every time that `z` changes. How could Vue take care of that automatically? – Hillcow Aug 02 '22 at 09:10
  • Basically I do this a lot: https://stackoverflow.com/a/56461539/6399812 – Hillcow Aug 02 '22 at 09:13
  • Also, I disagree with the fact that computed properties should be avoided... [computed properties are cached based on their reactive dependencies](https://vuejs.org/guide/essentials/computed.html#computed-caching-vs-methods), and should be used *whenever* possible, so long as **data manipulation** is **not** required, but only **data retrieval**. `methods` are run every single time they're encountered, and in the backend, are updated and recalculated every time a `data` variable is modified. `computed` properties are only recalculated if a `data` variable it **uses** is. – Jack_Hu Aug 02 '22 at 09:16