Modern web applications consume a lot of computer resources. A blog application in which I type this text currently consumes 130 megabytes of memory. On today's scale, it's a pretty decent result. On my laptop equipped with 8 gigabytes of RAM, I start noticing performance problems when a browser tab exceeds somewhere around one gigabyte of allocated memory. When you build a complex Vue application consisting of many views with deeply nested components hierarchy, very soon you will encounter memory issues. Here is a quick overview of what you can do with Chrome devtools' utility to analyze and improve the application's memory consumption.
There is a good guide from Chrome devtools team on how to fix memory problems. To sum it up, a frequent source of memory leaks in web applications are detached DOM elements that can't be processed by the garbage collector. There is a special tool designed to help in memory leaks investigation, devtools' memory profiles.
The number after the @ character is the objects’ unique ID, allowing you to compare heap snapshots on a per-object basis. What does each constructor group mean you can read here.
If we filter class by value detached, we'll get a list of all elements detached from DOM tree along with objects that directly on indirectly reference these elements (Retainers). There is a good description of distance, shallow and retained size and other terms in the official documentation.
You can select an item and then type $0 in the console to print the element ($0..$4 reference to latest items selected in elements inspector or heap profile, check console utilities API reference).
You can also check the Retainers tree and try to find which objects prevent the detached element from being garbage collected. This is not always a memory leak, elements are also preserved for optimization reasons.
Sometimes, detached elements are a side effect of chrome extensions. For clarity, it's better to disable extensions during the memory leaks investigation (incognito mode can be helpful if you don't want to use a separate browser or don't want to spend time manually disabling extensions).
Also, pay attention to a webpack's development mode, which features like hot module reloading could interfere with the application's normal execution, increase heap allocation and potentially produce leaks. It's better to hunt leaks running the production build of the application.
Suspect objects that retain a huge memory volume, that can give a clue to where the leak happens.
It's not obvious how to find real retainment path until you are very familiar with devtools' heap snapshot internals, V8, Blink rendering engine and chromium overall.
A common approach that I've developed while working on Vue application performance can be simplified into three steps: identify, prove, fix.
First, find in which circumstances memory consumption grows. If you use a router or dynamic components, it's the first place to check. If you suspect a particular component, isolate the component and experiment. Try disabling children components or some features. A common source of memory leaks are incorrect destructing and unhandled contexts. If you call a 3rd-party component constructor inside a component initialization hook, check that you correctly unregister everything in the beforeDestroy hook.
Another potential source of memory wastefulness is a Vuex state. A state that includes complex structures like multidimensional arrays is a common cause for extensive memory consumption, especially if it undergoes many mutations during the application lifecycle.