var someResource = getData(); setInterval(function() { var node = document.getElementById('Node'); if(node) { // Do stuff with node and someResource. node.innerHTML = JSON.stringify(someResource)); } }, 1000);
乍一看没啥问题,之后如果 Node 节点从DOM上被移除,因为上面的 callback 对 Node 节点有引用,所以 Node 节点会一直常驻内存,不会被CG回收。
要避免以上问题,就要养成 removeEventListener 和 clearInterval 的习惯。
var someResource = getData(); var interval = setInterval(function() { var node = document.getElementById('Node'); if(node) { // Do stuff with node and someResource. node.innerHTML = JSON.stringify(someResource)); } else { // Remove Timer clearInterval(interval); } }, 1000);
还比如:
var element = document.getElementById('button'); function onClick(event) { element.innerHtml = 'text'; } element.addEventListener('click', onClick); // Do stuff element.removeEventListener('click', onClick); element.parentNode.removeChild(element); // Now when element goes out of scope, // both element and onClick will be collected even in old browsers that don't // handle cycles well.
在 addEventListener 之后已经要记得 removeEventListener
闭包
闭包造成内存泄漏的情况比较复杂,而且较难查找。限于本文主旨,不做原理说明。
总结
个人认为 VueJS SSR 后端绘制内存泄漏造成影响要比普通的 VueJS 前端内存泄漏造成的影响要更大。
前端内存泄漏的影响,都是发生在客户机器上,而且基本上现代浏览器也会做好保护机制,一般自行刷新之后都会解决。但是,一旦后端绘制内存泄漏造成宕机之后,整个服务器都会受影响,危险性更大,搞不好年终奖就没了。
前端工程师一般都是关注于浏览器端表现,在开发过程中的内存泄漏问题不太在意也不太容易被发现。一般都是在项目上线一段时间之后,才发现内存泄漏的情况。那个时候再去着手,可能会有些无从下手或者手忙脚乱。
那么,就让我们在开发的时候开始关注内存泄漏问题,将 VueJS SSR 后端绘制内存泄漏问题扼杀于襁褓之中。