实践笔记性能优化与调试技巧 | 青训营

109 阅读4分钟

性能优化和调试技巧

1性能优化

1.1防抖

  1. 痛点:Js中的函数绝大多是由用户主动调用触发的,但是在一些少数情况下函数的触发不是由用户直接控制的,在这种情况下可能会被非常频繁地调用,从而造成性能问题。例如鼠标的mousemove事件,如果需要实现一个拖拽功能,就需要持续监听 mousemove事件,如果不加以控制,即使鼠标移动的距离很小,回调事件的触发次数仍然十分巨大。有比如window的onresize事件,当浏览器窗口大小被拖动而改变尺寸的时候这个事件会被一直触发,对性能造成巨大的消耗

  2. 实现原理:所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

  3. 代码实现

        /*
            防抖代码
        */
        function debounce(fun, delay) {
            let timeout = null;
            return function(e) {
                clearTimeout(timeout);
                timeout = setTimeout(() => {
                    fun();
                }, delay*1000)
            }
        }
        
        /*
            处理函数
        */
        function handle() {
            ...
        }
        
        //监听窗口滚动事件
        window.addEventListener('scroll', debounce(handle, 5));
    

1.2节流

  1. 痛点:同上

  2. 实现原理:函数节流的实现原理和函数防抖略有不同,函数节流保证了回调函数在规定时间内只执行一次。但两者都是为了限制回调函数的执行频次,以优化函数触发频率过高导致的浏览器性能下降问题。

  3. 代码实现

        /*
            节流函数
        */
        function throttle(fun, delay) {
            let run = true // 设置节流阀是节流实现的关键
            return function() {
                if (!run) { return; }
                run = false;
                setTimeout(() => {
                    fun();
                    run = true;
                }, delay*1000)
            }
        }
        
        /*
            处理函数
        */
        function handle() {
            ...
        }
        
        //监听窗口滚动事件
        window.addEventListener('scroll', throttle(handle, 5));
    

1.3重绘和重排

  1. 浏览器的渲染机制:HTML会被HMTL解析器解析成DOM Tree。css会被css解析器解析成CSSOM Tree(并行解析),两者解析完成后被合并到一起,形成渲染树

  2. 概念 1)重排:也叫回流,在DOM的大小,位置进行修改后,浏览器要重新计算元素的这些几何属性,这就是重排。(一个子元素的集合属性发生改变,直接影响了其父元素、兄弟元素以及向上追溯到的很多祖先元素,浏览器也要重新渲染与被修改元素相关联的其他元素)。重排几乎是无法避免的,页面的首次渲染、字体大小和数量的修改、伪类的激活、删除可见的DOM元素、改变浏览器窗口的大小等都会引发重排。 2)重绘:对DOM的样式进行修改,如colorbackground-color,浏览器不需要重新计算几何属性,直接绘制被修改元素的新样式,就是重绘。

  3. 优化 1)必要性:整个在浏览器的渲染过程中(页面初始化,用户行为改变界面样式,动画改变界面样式等)重排和重绘会大大影响web性能。重绘和重排的开销是非常昂贵的,如果我们不停的在改变页面的布局,就会造成浏览器耗费大量的开销在进行页面的计算,这样的话,我们页面在用户使用起来,就会出现明显的卡顿。 2)实现方法: ①、减少offsetTop、offsetLeft、scrollTop、scrollLeft、clientTop、clientLeft等属性的使用。 ②、减少DOM操作

        const el = document.querySelector('.el');
        el.style.borderLeft = '1px';
        el.style.borderRight = '1px';
        el.style.padding = '1px';
        // 以上操作会引起三次重排
    

    ③、批量修改DOM元素 ④、减少使用CSS表达式


1.4代码细节

  1. 慎用全局变量(全局变量定义在全局上下文,沿着作用域链查找全局变量会浪费时间,降低性能)。可以用缓存全局变量的方法优化此问题。
  2. 通过原型链给实例原型新增方法,减少实例在内存中占用的空间。
  3. 减少闭包的使用,闭包使用不当会造成内存泄露
  4. 延迟不必要的js首屏加载。
  5. 合理使用事件委托。 ......

2调试工具

  1. chrome开发者工具
  2. firefox插件firebug
  3. IE开发者工具 ......