Skip to content

Instantly share code, notes, and snippets.

@cheshirsky
Created May 28, 2015 13:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cheshirsky/6fc369dfce1597af632e to your computer and use it in GitHub Desktop.
Save cheshirsky/6fc369dfce1597af632e to your computer and use it in GitHub Desktop.
<html>
<body>
<div>Cyclic link</div>
<button id="myBtn0">create leak</button>
<br></br>
<div>Clusure leak</div>
<button id="myBtn1">create leak</button>
<br></br>
<div>jQuery cache leak 1</div>
<button id="myBtn2">create leak</button>
<br></br>
<div>jQuery cache leak 2</div>
<button id="myBtn3">create leak</button>
<br></br>
<div>Detached dom links</div>
<button id="myBtn4">create detached dom</button>
<br></br>
<div id="myDiv"></div>
<div id="wrapper"></div>
<div id="data"></div>
<script type="text/javascript" src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript">
function SuperbWrapper(element) {
// JS -> DOM link
this.elementReference = element;
this.someData = 42;
this.fat = new Array(1000).join(new Array(2000).join("test "));
// DOM -> JS -> DOM link
element.someDataAttr = this;
}
document.getElementById('myBtn0').onclick = function() {
var holder = document.getElementById("myDiv");
var child = document.createElement('div');
holder.appendChild(child);
new SuperbWrapper(child);
}
// link to DOM stored from parent function scope.
function createClosureLeak(button, isActive) {
isActive = button.isActive === undefined ? isActive : button.isActive;
// closure stores button from parent scope.
function clickOnActive() {
button.isActive = false;
button.bigString = new Array(1000).join(new Array(2000).join("test "));
}
// closure stores button from parent scope.
function clickOnInactive() {
button.isActive = true;
button.bigString = new Array(1000).join(new Array(2000).join("test "));
}
isActive ? clickOnActive() : clickOnInactive();
isActive = !isActive;
}
var button1 = document.getElementById('myBtn1');
button1.onclick = function() {
createClosureLeak(button1, true);
}
// jquery.cache stored onclick function
function jqueryLeak() {
$('<div/>')
.html(new Array(1000).join(new Array(2000).join("test ")))
.click(function() {})
.appendTo('#data');
// and now it would be stored in cache forever.
// Please use jquery everythere instead to avoid that.
document.getElementById('data').innerHTML = '';
}
document.getElementById('myBtn2').onclick = function() {
jqueryLeak();
}
document.getElementById('myBtn3').onclick = function() {
for(var i = 0; i < 100; i++) {
// jquery.cache keep going to eat ur memory in this case.
// even if dom is not used it keeps handler.
$('<div/>').click(function() {});
}
}
function fill() {
for (var i = 0; i < 250; ++i) {
var div = document.createElement('div');
div.data = new Array(10000);
for (var j = 0, l = div.data.length; j < l; ++j)
div.data[j] = j.toString();
detached.appendChild(div);
}
}
document.getElementById('myBtn4').onclick = function() {
var parent = document.getElementById("wrapper");
detached = document.createElement("div");
parent.appendChild(detached);
// it could be detached somethere else (async?)
parent.removeChild(detached);
fill();
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment