- Adding Instance Properties
- Form Validation
- Editable SVG Icon Systems
- Create a CMS-Powered Blog
- Unit Testing Vue Components
- Creating Custom Scroll Directives
- Debugging in VS Code
- Using Axios to Consume APIs
- Avoiding Memory Leaks
- Client-Side Storage
- Packaging Vue Components for npm
- Dockerize Vue.js App
- Practical use of scoped slots with GoogleMaps
Avoiding Memory Leaks
Memory leaks in Vue applications do not typically come from Vue itself, rather they can happen when incorporating other libraries into an application.
The following example shows a memory leak caused by using the Choices.js library in a Vue component and not properly cleaning it up. Later, we will show how to remove the Choices.js footprint and avoid the memory leak.
In the example below, we load up a select with a lot of options and then we use a show/hide button with a v-if directive to add it and remove it from the virtual DOM. The problem with this example is that the
v-if directive removes the parent element from the DOM, but we did not clean up the additional DOM pieces created by Choices.js, causing a memory leak.
To see this memory leak in action, open this CodePen example using Chrome and then open the Chrome Task Manager. To open the Chrome Task Manager on Mac, choose Chrome Top Navigation > Window > Task Manager or on Windows, use the Shift+Esc shortcut. Now, click the show/hide button 50 or so times. You should see the memory usage in the Chrome Task Manager increase and never be reclaimed.
Resolving the Memory Leak
In the above example, we can use our
hide() method to do some clean up and solve the memory leak prior to removing the select from the DOM. To accomplish this, we will keep a property in our Vue instance’s data object and we will use the Choices API’s
destroy() method to perform the clean up.
Check the memory usage again with this updated CodePen example.
Details about the Value
Memory management and performance testing can easily be neglected in the excitement of shipping quickly, however, keeping a small memory footprint is still important to your overall user experience.
Consider the types of devices your users may be using and what their normal flow will be. Could they use memory constrained laptops or mobile devices? Do your users typically do lots of in-application navigation? If either of these are true, then good memory management practices can help you avoid the worst case scenario of crashing a user’s browser. Even if neither of these are true, you can still potentially have degradation of performance over extended usage of your app if you are not careful.
In the above example, we used a
v-if directive to illustrate the memory leak, but a more common real-world scenario happens when using vue-router to route to components in a Single Page Application.
Just like the
vue-router removes elements from the virtual DOM and replaces those with new elements when a user navigates around your application. The Vue
beforeDestroy() lifecycle hook is a good place to solve the same sort of issue in a
vue-router based application.
We could move our clean up into the
beforeDestroy() hook like this:
We have discussed managing memory when removing elements, but what if you intentionally want to preserve state and keep elements in memory? In this case, you can use the built-in component keep-alive.
When you wrap a component with
keep-alive, its state will be preserved and therefore kept in memory.
This technique can be useful to improve user experience. For example, imagine a user starts entering comments into a text input and then decides to navigate away. If the user then navigated back, their comments would still be preserved.
Once you use keep-alive, then you have access to two more lifecycle hooks:
deactivated. If you do want to clean up or change data when a keep-alive component is removed, you can do so in the