事情的經(jīng)過
前段時間群里的老哥提出了一個疑問
image.png
測試
根據(jù)上述的情況蚓庭,我跟群里老哥做了一個demo來測試問題出在哪
<!DOCTYPE html>
<html>
<body>
<div id="app">
<button id="create-input">Create input</button>
<button id="destroy-input">Destroy input</button>
<br>
<button id="create-div">Create div</button>
<button id="destroy-div">Destroy div</button>
</div>
<script>
const getId = (str) => document.getElementById(str)
function createTest(elem) {
const CreateBtn = getId(`create-${elem}`)
const DestroyBtn = getId(`destroy-${elem}`)
const onAddClick = () => {
let input = document.createElement(elem)
input.id = elem
// 給dom綁定大量對象
input._a_ = new Array(1000000).fill('1')
document.body.appendChild(input)
input = null
}
const onRemoveClick = () => {
let input = getId(elem)
if (input) {
input.parentNode.removeChild(input)
}
input = null
}
CreateBtn.addEventListener('click', onAddClick)
DestroyBtn.addEventListener('click', onRemoveClick)
}
createTest('div')
createTest('input')
</script>
</body>
</html>
創(chuàng)建input/div并手動銷毀的演示墓拜,操作完input后需要刷新頁面重置當前window的內(nèi)存
performance.gif
performance2.gif
測試結(jié)果
根據(jù)上述簡單測試,比對memory和perfomance兩個工具畔柔,能夠得到一些結(jié)論:
- 大對象沒有在銷毀DOM元素后直接GC靶擦,而是當下一次有新的大對象創(chuàng)建時(這里是大對象綁定在DOM上)玄捕,才會處理原有大對象的內(nèi)存占用
- Div的GC比較徹底枚粘,Input元素幾乎沒有GC掉原來的垃圾
河大點評了一下:
image.png
那位老哥最后發(fā)郵件咨詢了一下chromium團隊:
image.png
總結(jié)
- 別隨便往DOM對象上綁定東西孝冒,注意銷毀事件綁定
- Input元素對象量承,由于undo/redo的需求拿穴,存在特殊情況
- 該重新學一下V8垃圾回收機制了(