网站JS性能优化与内存泄漏排查实战指南
原生JS优化到底能提升多少
许许多多的站长觉得网站出现卡顿现象是因为服务器带宽存在问题或者后端接口运行速度缓慢, 然而实际上前端原生JS的代码质量对于页面加载以及交互体验有着直接的影响力。我曾见识过一个电商类型的网站, 仅仅只是将循环之中的DOM操作转移到循环的外部, 首屏渲染所需要的时间便缩短了40%。原生JS实施优化的核心要点在于减少那些没有必要的计算以及重绘。
是以常见之for循环为例, 若于每次循环之际皆去读取array.length, 那么浏览器便需反复地进行计算。而正确之做法乃是运用变量来缓存其长度:
// 低效写法
for (let i = 0; i < arr.length; i++) { }
// 优化后
let len = arr.length;
for (let i = 0; i < len; i++) { }比如说频繁地对 style 属性进行操作, 每做出一次修改, 浏览器就会触发一次重排行为。应当将修改进行合并, 或者采用 class 切换的方式:
// 不推荐
el.style.width = '100px';
el.style.height = '200px';
// 推荐
el.classList.add('new-style');把setTimeout做动画替换成用requestAnimationFrame, 将给每个子元素绑监听替换为用事件委托——这些均为网站原生JS优化的基本功。有一个原则: 操作DOM能少则少, 能用CSS解决的就别动用JS。
JS代码执行效率优化有哪些坑
对于函数本身的执行效率而言, 除了减少对 DOM 的操作外, 也是较容易被忽视的。倘若闭包使用过多, 便会占用额外的内存, 而递归写法要是不设置终止条件, 将会直接导致爆栈。我曾优化过一个后台管理系统, 其中存在一个列表筛选功能,每一次输入操作都会触发全量遍历, 后来将其改成防抖并加上索引查找后, 输入响应时间从 200 毫秒降低到了 10 毫秒以下。
防抖代码直接拿去用:
function debounce(fn, delay = 300) {
let timer = null;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}还有, eval以及Function构造器尽量别去使用, 它们会使得解析速度被拖慢。JSON.parse比起eval来安全并且快上十倍。要是碰到大量有着相同结构的对象, 采用Object.create(null)去替代{}来作为缓存字典, 能够省去原型链查找所产生的开销。
从事动画或者高频触发的事件, 运用requestAnimationFrame搭配performance.now()进行时间戳判断, 能够控制渲染帧率, 防止掉帧。将这些细节累积起来, 页面便实现流畅了。
内存泄漏排查怎么下手
内存泄漏于单页应用当中最为常见, 不少站长发觉网站用用便起变化, 变得卡顿, 最终致使浏览器崩溃。排查的首要步骤为: 开启Chrome DevTools的Performance版块, 于其中进行一段操作的录制, 审视内存曲线是否持续上扬而不回落。要是曲线仅仅上升而不下降, 那么必定存在泄漏。
常见泄漏来源:
对于全局变量, 存在没有进行释放的情况, 举例来说, 就是将数据挂载在了window之上, 而在页面切换过后,该数据依然存在着。
定时器未被清除, 回调也未被清除, 在setInterval注册之后, 当组件进行销毁时, 却没有调用clearInterval, 导致函数一直持有外部引用。
解析DOM引用存在残留的情况, 将DOM节点存储于数组之中, 尽管节点已从页面上被移除, 然而数组对其仍存在引用, 致使内存无法实现回收。
利用Memory面板去拍摄快照(Heap Snapshot), 就此比对两次操作在前后之际的内存差别。要是发觉存在大量处于detached状态的DOM节点, 又或者Closure里的引用链长度很长, 那么此即为泄漏点。有一个实用型工具: performance.memory能够对JS堆的大小进行实时查看:
if (performance.memory) {
console.log(performance.memory.usedJSHeapSize / 1024 / 1024 + 'MB');
}用于修复泄漏的方式相当简单, 具体是对于已用过的定时器要记得去清除, 针对事件监听要记得将其移除, 对于不再有需求的对象需把它置为null。养成这样的习惯之后, 内存泄漏基本上就会与你保持距离了。
否玩代码编辑的本站内容, 网址为https://www.fouwan.com。


