2. Dans une application Vue/Nuxt ou autre
application/site web javascript en mode SPA (pas de
page reload), il faut s'assurer que les components,
listeners et autres composants Javascript soient
détruits lorsqu'ils ne sont plus utilisés. Sinon ils
continuent d'utiliser de la mémoire RAM.
3. Dans une app Vue/Nuxt, le framework s'occupe
automatiquement de détruire les event listeners qui
sont ajoutés avec la syntaxe Vue.
Si le même listener est ajouté en js vanille, il ne sera
pas détruit.
<button @click="toggle">Click meeee</button>
<button class="hot-button">Click meeee</button>
<script>
const hotButton = document.querySelector('.hot-button'
hotButton.addEventListener('click', this.toggle)
</script>
4. Disons qu'on veut ajouter un listener sur le resize :
window.addEventListener('resize', () => {
mounted() {1
2
this.currentMaxHeight = this.$refs.container.scrollHeigh3
})4
}5
5. Comme le listener est sur l'élément window, il ne sera
jamais "garbage collected". Il faut donc le détruire
manuellement, sinon à chaque instanciation du
component (sur le mounted()), un nouveau listener
sera ajouté sur le resize du window et va lui aussi
consommer de la RAM.
UN (petit) MEMORY LEAK!!!!
D:
6. Pour ce faire, il faut refactorer le handler pour utiliser
une méthode au lieu d'une fonction anonyme :
mounted() {
window.addEventListener('resize', this.handleResize)
},
beforeDestroy() {
window.removeEventListener('resize', this.handleResize)
},
methods: {
handleResize() {
this.currentMaxHeight = this.$refs.container.scrollHeight
}
}
7. Comment spotter un memory leak?
Avec les profilers du Chrome devtools.
Prérequis :
Désactiver les chromes extensions
Profiler en prod c'est bon pour savoir si il y a un
leak, mais pas pour cibler la cause (à cause de la
minification)
DÉMO
8. RECAP ONGLET PERFORMANCE :RECAP ONGLET PERFORMANCE :
Reload page
Trigger Record
Trigger router and garbage collector (Navigate in the
Vue app)
Stop recording
Analyse timeline for suspicious patterns
9. RECAP ONGLET MEMORY :RECAP ONGLET MEMORY :
Reload page
Take a Heap snapshot
Trigger router and garbage collector (Navigate in the
Vue app)
Take another heap snapshot
Select comparison view and check for suspicious
data
10. CONCLUSIONCONCLUSION
Un gros leak === plus facile à cibler
Beaucoup de petits leaks === durs à cibler
Un leak peut être considéré comme un bug OU une
opportunité d'optimisation de performance.
Respecter les bonnes pratiques est la meilleure
manière de prévenir les leaks en amont (pour pas
finir comme l'API de Google Maps).
Faire attention aux third-partys.
11. The Google Maps API memory leak issue thread :
Issue ouverte en 2011, seule réponse officielle de
Google en 2015 :
https://issuetracker.google.com/issues/35821412#c8
[...] I'm labeling this as won't fix,
because this is technically difficult.
We're not really sure in how many
places we're leaking :-( [...]
12. Lectures détaillées sur les JS memory leaks :
https://vuejs.org/v2/cookbook/avoiding-memory-
leaks.html
https://dzone.com/articles/eradicating-memory-
leaks-in-javascript
https://auth0.com/blog/four-types-of-leaks-in-your-
javascript-code-and-how-to-get-rid-of-them/