Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve the devtools performance #649

Closed
Akryum opened this issue Mar 16, 2018 · 29 comments
Closed

Improve the devtools performance #649

Akryum opened this issue Mar 16, 2018 · 29 comments

Comments

@Akryum
Copy link
Member

Akryum commented Mar 16, 2018

Let's use this issue to discuss possible performance improvements for the devtools.

Ideas:

  • Vuex recording performance improvements Vuex recording performance improvements #546
  • Send the components in a lazy way (currently serializing and sending the whole component tree for each flush)
  • Send the current component data in a lazy way (currently the entire component state is serialized and sent)
  • Separate component tree and current component details flush
  • Limit the number of events stored in the devtools
  • Possibility to send only the filtered events to the devtools?
  • Use a virtual scrolling solution for all the relevant lists

If you have more ideas please share! 🐈

@salomvary
Copy link

+1 Optimizing for high frequency events would be great. (Use case: events triggered by mouse moves, scrolling, media elements, etc.)

In my experience the extension slows down Firefox beyond repair (the only way to recover is killing the Firefox process) after a few thousand events and drastically slows down Chrome (recovers after closing the tab).

Snippet to reproduce the slowdown/crash:

<div></div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
  new Vue({
    el: 'div',
    data: {
      foo: null
    },
    mounted () {
      setInterval(() => {
        this.foo = new Date()
        this.$emit('foo', this.foo)
      }, 10)
    }
  })
</script>

@viktor-ku
Copy link

I am experiencing huge problems with performance. When devtools enabled all Chrome tabs are lagging:

  • animations
  • clicks
  • scrolling
  • change pages in vue

Helps if I either disable devtools or kill entire Chrome and restart. But then it will start lagging again after I interact with devtools.

And it happens on all 3 computers that I've used to develope vue apps. One of them has i7 8700k and 16gb of ram so it's definitely not the hardware.

What to do?

@heygambo
Copy link

heygambo commented May 26, 2018

I'd like to be able to exclude certain events and vuex mutations to be shown in vue-devtools.
It would be cool if we could set some options to vue-devtools before the app starts.

const blackListExample = {
  recording: {
    blackList: {
      events: ['mouse-move'],
      mutations: ['MOUSE_MOVE']
    }
  }
}
devtoolsReference.setOptions(blackListExample)
const whiteListExample = {
  recording: {
    whiteList: {
      events: ['mouse-click'],
      mutations: ['MOUSE_CLICK']
    }
  }
}
devtoolsReference.setOptions(whiteListExample)

Probably this easier would be this in the beginning, though:

devtoolsReference.stopEventsRecording()
devtoolsReference.stopMutationsRecording()

@narrowtux
Copy link

narrowtux commented May 28, 2018

The high CPU usage seems like a bug that always happens when reloading the page, at least in my case.

EDIT: Maybe it's got something to do with that it listens to way too much stuff when starting the app, but when you connect to an already running app, it has already gotten most of the stuff initialized so the tool isn't a performance hog.

@AlansCodeLog
Copy link

Just found this issue because I thought it was something wrong with my code, sometimes these panels I was dragging would stutter and the FPS would drop from 60 to 4. After some digging I found it only happens as @kuroljov describes when the vue devtools tab was opened, and once it had been opened it wouldn't go away until I reloaded from a different devtool's tab so as not to trigger it again. This was using electron though, not chrome, so just a reload did the trick for me.

I second the blacklist/whitelist, but it would be nice to be able to do it from the devtools, maybe like a prefix in the filter would make it temporarily permanent (e.g. whitelist: [mutation, module prefix, etc]) Usually bugs can only be in 2-3 mutations, and if using modules, only within a certain module.

Also some sort of snapshot feature would be cool, where you could take snapshots manually or at x intervals.

@varna
Copy link

varna commented Jun 14, 2018

Most often problem with DevTools - mutations:
Doing "many" mutations with DevTools turned on is deadly. i.e. Here I added 294 items to some array:
devtools
Without DevTools this is done instantly. With DevTools on, this takes a couple of minutes, DevTools freezes, sometimes whole browser freezes. Other participants probably already mentioned possible causes.

@jq-87
Copy link

jq-87 commented Jun 14, 2018

@JesusCrow I've had a similar issue in the past and yes the dev tools team should definitely look into handling many mutations at once.

However, in this particular case the multiple mutations are calls to the same mutation.

Perhaps a better approach is to prepare your array before calling the mutation and then pass the updated array to your mutation when it is ready. This cleans up your mutation list and makes looking at your app's history a bit easier.

@maksnester
Copy link

Hi guys, I've found this issue by searching info about the message in console, so I just wanted to ask one thing.
I'm trying to debug my app in Edge with electron app and all the time I see this message infinitely repeated in Edge console:
[flush] serialized 59 instances, took 4.000008533352229ms.

I just wanted to know what does it mean and is it possible to disable it? I can't see anything in console because of it.

Thanks in advance, sorry if off-topic.

@mizzao
Copy link

mizzao commented Nov 1, 2018

I'm currently using a Vuex store for real-time data and it makes it impossible to use devtools as it is streaming.

Maybe it would be nice to just turn off mutation recording by default, and activate it on demand (with filtering), as a stopgap measure. The Chrome profiler has a 'record' button for example, and doesn't just record all the time.

@rhernandog
Copy link

I'm seeing some performance when working with large data. If I don't open Vue devtools the performance tab in Chrome reports a usage of 45MB in the JS Heap, but when running a simple mutation that takes an array of that data and returns it's length, the memory usage goes to almost 400MB. The data itself is not that big, around a 3MB JSON file.

When Vue Devtools are not selected everything works normally and the memory usage is fine.

Stopping the mutation recording doesn't solve anything, memory usage keeps spiking.

@Connum
Copy link

Connum commented Dec 31, 2018

+1 for a way to disable specific messages (or at least the flush message)

I'm currently using a Vuex store for real-time data and it makes it impossible to use devtools as it is streaming.

Same here! I'm using a Vuex Store that provides the current time quite accurately (initially synced with an NTP server, then taking into account the delta to local time), which internally updates itself using requestAnimationFrame, resulting in a mutation every 1 second (as opposed to using setInterval). However, since I enabled the Vue Dev Tools, this leads to the console being polluted with the flush message every second, rendering the console unusable for debugging.

@szalapski
Copy link

I'd love to see some progress on this to make the dev tools more snappy. Right now, it seems to bog down quite easily and also crash a lot.

@Akryum
Copy link
Member Author

Akryum commented Jan 23, 2019

Are you talking about 4.x or 5.x?

@BrianBrenner
Copy link

BrianBrenner commented Jan 23, 2019

@Akryum I've had issues with both. The Vuex stop recording button seems to be broken which makes the dev-tools almost unusable for my case since I can't prevent it from running out of memory.

image

(Note it is paused but still recording mutations, this is on v5 beta 3)

@szalapski
Copy link

szalapski commented Jan 24, 2019

I am working with 4.1.5 beta. Should I try a different version? Is there a version that crashes less often than 4.1.5 beta?

@CaelanStewart
Copy link

CaelanStewart commented Jan 24, 2019

Update

It now:

  • can add its own button in to enable it
  • doesn't rely of bootstrap or jquery, implemented a simple quick tooltip instead

Check the 'Configurable Options' comment at the top of the code:


Original Post:

I just wanted to share this little snippet with you guys, as this has been a bit of annoying issue that still persists.

On a particularly data and component heavy project I'm building at the moment, just using vue-devtools is almost impossible on some pages. It literally lags and stutters and slows down to a halt and then inevitably crashes whenever you do anything.

I quickly hacked together a dead simple script that allows you to interact with components in the console easily. It's not pretty and could be better, but it's functional and doesn't crash when debugging complex pages.

Debugging events will still be difficult though as this does not handle events.

When the trigger button is clicked, It will search all elements on the page for elements tied to a Vue component and then allow you to highlight on mouseenter and to add a global reference on click for use in the console.

It's tied to Bootstrap 3 (and subsequently jQuery) to show a tooltip above the component. Though you could easily swap out the code for another tooltip library (or BS4).

It, similarly to Vue devtools, adds references prefixed with $vm with an index appended. However, with the below script, each component you click will have its own reference, suffixed with an index, incremented on each click of an element.

It also adds 4px padding top and bottom when you trigger the debug mode, so you can select a component directly that is behind a stack of components of the same width/height.

You can change the value of the variable declared at the top of the self-invoking function block to change how far up the hierarchy of components the breadcrumb generated should go up before it stops.

This allows the tooltip to display something to the effect "root > sidebar > tabs > tab > button" when you hover over the component. I found that it was too much and leaving it set to 1 is just fine. But it could be useful.

All you need is a button to trigger it. I (when on local env) show a small button, fixed in the bottom left of the window, to toggle it on and off.

<button id="toggle-vue-debug" type="button" class="btn btn-primary btn-lg">
        <i class="fa fa-bug"></i>
</button>

Gist:
https://gist.github.com/CaelanStewart/6aad4c522ec86ca69db19ec205a39348

@szalapski
Copy link

CaelanStewart , thanks for that code, I thought I'd try it. I noticed it refers to a $ function. Am I right to presume that is from jQuery? I'm hesitant to bring in jQuery for such a small need; especially since using Vue.js largely eliminates the need for jQuery. I'll look to see what I can substitute.

@CaelanStewart
Copy link

@szalapski I've updated it with no dependencies now. If you add the HTML for the button in the page or set the value of autoInsertButton to false at the top, then it will attach the enable event to that. But if autoInsertButton is true, and no button is on the page, it will create a new button and attach events to that.

I also added a quick a dirty tooltip so we can still have that luxury.

Anyway, I shouldn't have read my email after taking half my sleeping tablet, some what nauseating.

Hope that helps.

@CaelanStewart
Copy link

@szalapski, I had made a few critical errors that slipped by my receding consciousness last night, I have fixed those now.

@szalapski
Copy link

I'll try it out.

@szalapski
Copy link

On the other hand, v5 of the dev tools is much improved, thanks!

@CaelanStewart
Copy link

I'm still finding the devtools to be very slow and unresponsive on a complex page with many components.

This is with event recording off.

Details

Opening vue-devtools is fine, but as soon as I start interacting with it, exploring the component hierarchy, it gets progressively choppier, becoming unusable after a 10 seconds of interacting, clicking on components, opening and closing tree nodes etc.

At this point the CPU is raging, "Google Chrome Helper" at ~250% CPU (macOS), and if I leave it for about five minutes, I come back and the CPU is back down to near zero, and the vue-devtools are responsive once again. However, if I begin using the vue-devtools in any way, the same process of progressive slow-down occurs and then settles down after a while.

It seems like some work is queued whenever you click on nodes in the tree, and continuing to interact just queues up more work regardless of the current queue length, and then eventually it works through the queue, and CPU goes back down again.

But, after doing this a couple of times consecutively, even after 10 minutes, it did not settle back down, as if the work load grew exponentially after each try. I gave up waiting at that point.

The app in question doesn't behave in this way, and is reasonably fast and responsive on slow machines considering the scale. This only begins when I start inspecting it via vue-devtools.

I get that the app in question is perhaps an edge case in terms of complexity, and maybe this is just the cost of dealing with something like this using web tech.

The page itself AND vue-devtools DOES respond, seeming to indicate the work is chunked and processed asynchronously, as it doesn't lock the page up entirely, it just responds very slowly with thread so saturated with the async tasks.

Question

I'd like to assist in debugging in any way if I can. What information could I collect that would help with analysing why this happens or the problem points.

And another, question, I wonder if there is perhaps any way that the app in question could be at fault in any way here? It runs fast and doesn't behave this way except when I inspect it with vue-devtools.

I notice that the page slows down when I trigger actions that mutate state just by having vue-devtools open with the props/data of a component visible in the side panel. Is it possible that state mutations being triggered on a timer in my app regularly enough could cause vue-devtools to be constantly working, with watchers being constantly triggered? I'm reasonably certain no such loop exists, and even if it were, it seems unlikely to be an issue if changes are small, so long as small changes don't trigger a large batch of processing every time within vue-devtools.

There are no spurious events where there shouldn't be any when recording the events, further reducing the probability that it's something to do with work being triggered on timers, since I try to make use of events for upward communication between components, and I like to separate distinct by related bits of functionality into a hierarchy of components , and it is likely that work on a timer large enough to cause a slow down like this would trigger an event somewhere.

Anyway, perhaps I've added more detail than is necessary, but I just want to give a good idea of the behaviour I'm seeing here, and to ask in which ways I can best help debug this - as I really want to use the proper vue-devtools!

Thank you very much.

@Akryum
Copy link
Member Author

Akryum commented May 20, 2019

The component inspector still needs a lot of work to be lightning fast and to scale well.

@CaelanStewart
Copy link

CaelanStewart commented May 20, 2019

@Akryum

No worries at all!

The price to pay for a complex app, it seems!

At least now Chrome puts references $n to elements in the tree, accessing .__vue__ isn't too difficult.

Thank you.

@hitautodestruct
Copy link

I'm also experiencing a crash every time I use vue devtools on our complex app.
Might be due to multiple updates of vuex store every 500ms.
If theres a way to add further data for debugging please let me know.

@szalapski
Copy link

szalapski commented Jul 8, 2019

I'd agree--I'm still having trouble with the devtools 5.1.1. Could the source of slowdowns be better isolated? For example, maybe the component inspection itself isn't the problem, but gets bogged down by one feature that might be optionally disabled? I'm just speculating here, but enabling a workaround if possible would be better than shaking our fists at a hard problem.

(Even guidance in the wiki or other document on how to use the devtools in these "moderately complex" situations might be helpful.)

@samboylett
Copy link

I'm currently experiencing this issue with a component running a 10ms timer. It works fine without devtools open, but with devtools will use 120% CPU and the page becomes unresponsive. IMO it needs to debounce updates to every 500ms or whatever it can handle, as a quick fix (maybe set it as an option/checkbox)

@Emobe
Copy link

Emobe commented Oct 31, 2019

I have the same issue as @alendorff. Using vue dev tools with storybook means the console gets polluted on almost every action. Currently I can work around it by adding -flush to the console filter but that's not ideal. Does the user really need to be told about this in the console every time?

@Gameghostify
Copy link

I have the same issue. A component running a timer using requestAnimationFrame (runs every 16.6ms on my screen) slows the dev tools down to a point where they become unusable

It would be great if we could make the devtools ignore certain component's data fields, for example with a comment like //devtools-ignore. Not sure how easy/possible this is though

@vuejs vuejs locked and limited conversation to collaborators Feb 10, 2022
@Akryum Akryum converted this issue into discussion #1702 Feb 10, 2022

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Projects
None yet
Development

No branches or pull requests