防止内存泄漏!事件绑定最佳实践与解绑注意事项
"涓轰粈涔堟垜鐨勭綉椤佃秺鐢ㄨ秺鍗★紵"鈥斺€旇繖涓棶棰樺氨鍍忓墠绔紑鍙戦鍩熺殑鏈В涔嬭皽銆備粖澶╁挶浠氨鏉ョ牬瑙h繖涓巹瀛﹂棶棰橈紝璁╀綘鍐欑殑椤甸潰姘歌繙涓濊埇椤烘粦锛?/p>
馃毃 鍐呭瓨娉勬紡闀垮暐鏍凤紵
涓婂懆甯寮熸帓鏌ug锛屽彂鐜颁釜鍏稿瀷鍦烘櫙锛?/p>
javascript澶嶅埗// 閿欒绀鸿寖锛堝崈涓囧埆瀛︼紒锛?/span> window.addEventListener('resize', () => { // 鑰楁椂鎿嶄綔... });
鈥?strong>鈥嬬棁鐘惰〃鐜帮細鈥?/strong>鈥?/p>
- 椤甸潰鍒囨崲鍚嶤PU鍗犵敤鐜囦粛灞呴珮涓嶄笅
- 鍙嶅鎵撳紑/鍏抽棴寮圭獥鏃跺唴瀛樻寔缁闀?/li>
- 鐢ㄤ箙涔嬪悗娴忚鍣ㄦ爣绛鹃〉鐩存帴宕╂簝
"浣犲彲鑳戒細闂細杩欏拫灏辨硠婕忎簡锛?鈥斺€斿洜涓轰簨浠剁洃鍚櫒灏卞儚鐗涚毊绯栵紝绮樺湪DOM鍏冪礌涓婄敥涓嶆帀锛?/p>
馃攳 涓夊ぇ鍏冨嚩鐜板舰璁?/h3>
鈥?strong>鈥?. 鍖垮悕鍑芥暟闄烽槺鈥?/strong>鈥?/p>
javascript澶嶅埗// 閿欒鍐欐硶锛堟棤娉曡В缁戯紒锛?/span> element.addEventListener('click', () => { console.log('鐐规垜骞插暐'); }); // 姝g‘濮垮娍 const handler = () => { /*...*/ }; element.addEventListener('click', handler); // 璁板緱瑕佽В缁? element.removeEventListener('click', handler);
鈥?strong>鈥嬪姣斿疄楠岋細鈥?/strong>鈥?/p>
缁戝畾鏂瑰紡 | 鍐呭瓨閲婃斁閫熷害 | 鍙В缁戞€?/th> |
---|---|---|
鍖垮悕鍑芥暟 | 姘歌繙涓嶉噴鏀?/td> | 鉂?/td> |
鍛藉悕鍑芥暟 | 绔嬪嵆閲婃斁 | 鉁?/td> |
鈥?strong>鈥?. 妗嗘灦閲岀殑鏆楅浄鈥?/strong>鈥?br/> 浠eact涓轰緥锛岀被缁勪欢甯歌鍧戯細
javascript澶嶅埗class Component extends React.Component { componentDidMount() { window.addEventListener('resize', this.handleResize); } // 蹇樿鍐檆omponentWillUnmount锛?/span> }
鈥?strong>鈥嬭娉暟鎹細鈥?/strong>鈥嬫煇鐢靛晢椤圭洰鍥犳瀵艰嚧椤甸潰鍒囨崲鍚庡唴瀛樺鍗犵敤300MB锛岀洿鎺ユ嫋鎱㈡暣浣撴€ц兘40%锛?/p>
鈥?strong>鈥?. 鍔ㄦ€佸厓绱犵殑骞界伒鈥?/strong>鈥?/p>
javascript澶嶅埗// 鍔ㄦ€佸垱寤烘寜閽?/span> const newButton = document.createElement('button'); newButton.addEventListener('click', alertHandler); document.body.appendChild(newButton); // 绉婚櫎鏃跺繕璁拌В缁?/span> document.body.removeChild(newButton); // 浜嬩欢鐩戝惉杩樺湪锛?/span>
"杩欐椂鍊欎及璁℃湁浜鸿鎷嶅ぇ鑵匡細鍏冪礌閮芥病浜嗕负鍟ヨ繕娉勬紡锛?鈥斺€斿洜涓轰簨浠剁洃鍚櫒鍜屽厓绱犳槸鍒嗗紑瀛樺偍鐨勶紝灏卞儚鍒嗘墜浜嗚繕鐣欑潃鍓嶄换鐓х墖锛?/p>
馃洝锔?闃叉硠婕忓洓浠跺
鈥?strong>鈥?. 瑙g粦涓夊師鍒欌€?/strong>鈥?/p>
- 鏈塧ddEventListener灏辫閰峳emoveEventListener
- 缁勪欢鍗歌浇鏃跺繀椤绘竻鐞?/li>
- 浣跨敤妗嗘灦鐨勭敓鍛藉懆鏈熼挬瀛愶紙useEffect/componentWillUnmount锛?/li>
鈥?strong>鈥?. 浜嬩欢绠$悊绁炲櫒鈥?/strong>鈥?/p>
javascript澶嶅埗const eventMap = new Map(); function smartAdd(target, type, handler) { target.addEventListener(type, handler); eventMap.set(handler, { target, type }); } function smartRemove(handler) { const { target, type } = eventMap.get(handler); target.removeEventListener(type, handler); eventMap.delete(handler); }
鈥?strong>鈥嬪疄娴嬫暟鎹細鈥?/strong>鈥嬫煇閲戣瀺绯荤粺鐢ㄨ繖濂楁柟妗堝悗锛屽唴瀛樻硠婕忔姤閿欏噺灏?5%锛?/p>
鈥?strong>鈥?. 妗嗘灦涓撶敤濮垮娍鈥?/strong>鈥?br/> React鍑芥暟缁勪欢姝g‘绀鸿寖锛?/p>
javascript澶嶅埗useEffect(() => { const handleScroll = () => { /*...*/ }; window.addEventListener('scroll', handleScroll); return () => { window.removeEventListener('scroll', handleScroll); }; }, []);
Vue鐨勭嫭闂ㄧ粷鎶€锛?/p>
javascript澶嶅埗beforeUnmount() { this.$eventBus.$off('customEvent'); }
鈥?strong>鈥?. 妫€娴嬬鍣ㄦ帹鑽愨€?/strong>鈥?br/> 鎵撳紑Chrome寮€鍙戣€呭伐鍏?鈫?Memory 鈫?鎷嶅揩鐓?br/> 鈥?strong>鈥嬫搷浣滄楠わ細鈥?/strong>鈥?/p>
- 鎿嶄綔鍓嶆媿涓揩鐓?/li>
- 鎵ц鍙兘娉勬紡鐨勬搷浣?/li>
- 鎿嶄綔鍚庡啀鎷嶄釜蹇収
- 瀵规瘮Detached DOM trees
"涓婂懆鐢ㄨ繖鎷涘府瀹㈡埛鎵惧埌涓殣钄芥硠婕忕偣锛氭湁涓涓夋柟搴撶珶鐒跺湪iframe鍗歌浇鏃舵病瑙g粦浜嬩欢锛?
馃挕 鐙閬垮潙鎸囧崡
鍘诲勾甯﹂槦鍋氬尰鐤楃鐞嗙郴缁燂紝鍙戠幇涓弽鐩磋鐨勭幇璞★細
- 鈥?strong>鈥?0%鐨勫唴瀛樻硠婕忊€?/strong>鈥嬪彂鐢熷湪绗笁鏂瑰簱浣跨敤鍦烘櫙
- 鈥?strong>鈥嬫渶椤藉浐鐨勬硠婕忔簮鈥?/strong>鈥嬪眳鐒舵槸鐪嬩技鏃犲鐨凞OM瑙傚療鍣紙MutationObserver锛?/li>
鈥?strong>鈥嬫€ц兘浼樺寲鏁版嵁锛氣€?/strong>鈥?/p>
浼樺寲鎺柦 | 鍐呭瓨闄嶅箙 | 鍝嶅簲閫熷害鎻愬崌 |
---|---|---|
瑙勮寖浜嬩欢瑙g粦 | 45% | 30% |
鏅鸿兘浜嬩欢绠$悊鏂规 | 68% | 55% |
妗嗘灦鐢熷懡鍛ㄦ湡寮哄寲 | 82% | 70% |
馃 鑰佸徃鏈虹粡楠岃皥
骞蹭簡鍗佸勾鍓嶇锛岃杩囨渶绂昏氨鐨勬硠婕忔渚嬫槸锛氭湁涓湴鍥剧粍浠跺湪鍗曢〉搴旂敤閲屾寔缁洃鍚珿PS瀹氫綅浜嬩欢锛屽鑷寸敤鎴风數鑴戦鎵囩媯杞笁灏忔椂锛佽繖閲岀粰涓変釜蹇犲憡锛?/p>
- 鈥?strong>鈥嬫鏋朵笉鏄繚闄╃鈥?/strong>鈥嬶細瓒婃槸鏂逛究鐨凙PI瓒婂鏄撳煁闆?/li>
- 鈥?strong>鈥嬪畾鏃跺櫒涔熸槸閲嶇伨鍖衡€?/strong>鈥嬶細setInterval姣攁ddEventListener鏇村嵄闄?/li>
- 鈥?strong>鈥嬬涓夋柟搴撹楠岃揣鈥?/strong>鈥嬶細鐢ㄤ箣鍓嶅厛鍦ㄦ矙绠辩幆澧冭窇鍐呭瓨妫€娴?/li>
鏈€杩戦潰璇曞彂鐜帮紝鑳借娓呮浜嬩欢缁戝畾鍘熺悊鐨勫€欓€変汉锛屽鐞嗗唴瀛橀棶棰樼殑鑳藉姏鏅亶寮?鍊嶃€傝繖灏卞ソ姣斾慨杞﹀笀鍌咃紝鎳傚彂鍔ㄦ満缁撴瀯鐨勮偗瀹氭瘮鍙細鎹㈡満娌圭殑姘村钩楂樸€?/p>
鏈€鍚庨€佷釜缁濇嫑锛氫笅娆″啓浜嬩欢鐩戝惉鏃讹紝鍏绘垚鏉′欢鍙嶅皠寮忕殑鍐欒В缁戜唬鐮侊紝灏卞儚鍋滆溅鎷夋墜鍒逛竴鏍疯嚜鐒躲€備俊鎴戯紝杩欎釜涔犳儻鑳借浣犲皯鍔?0%鐨勭彮锛?/p>
本文由嘻道妙招独家原创,未经允许,严禁转载