资讯专栏INFORMATION COLUMN

如何使用函数来优化性能?

lncwwn / 3373人阅读

摘要:原理连续触发事件,但是事件函数只在在规定的周期之内只执行一次。代码实现使用在使用节流函数后,我们在暂停输入的后就会输入输入框内的值,暂停时间小于,则不会输出,将重新计算函数执行时间。使用分时函数这样在调用分时函数后每隔创建个节点。

一、节流函数 1. 使用场景

DOM.onclick()事件,我们给一个DOM节点绑定了点击事件,当点击该元素时触发事件函数的执行,但是当我们频繁点击该元素时,就会不断触发该点击事件,如果该点击事件触发的事件函数是DOM元素的,就会造成很高的性能消耗,可能会造成页面的卡顿。

所以此时我们应该限制该事件的触发频率,减少页面的开销。

2. 原理

连续触发事件,但是事件函数只在在规定的周期之内只执行一次。

3. 代码实现
function throttle(fn, wait = 500) {
    let lastTime = 0 // 初始化上一次调用的事件
    return function () {
        let args = [].slice.call(arguments) // 将类数组转化为数组
        let nowTime = new Date().getTime() // 获取当前时间
        if(nowTime - lastTime > wait) { 
            fn.apply(this, args)
            lastTime = nowTime // 把上一次调用时间重新赋值
        }
    }
}

// 使用
let btn = document.getElementById("btn")
let fn = function () {
    console.log(1)
}
btn.onclick = throttle(fn, 1000)

在给按钮加上点击事件后,即使一直不停的点击按钮,也只会每隔1000ms执行一次事件处理函数。

二、防抖函数 1.使用场景

例如我们在百度搜索的输入框输入我们想要搜索的内容,在我们停止输入后一小段时间(delay)后就会得你输入框得内容然后进行搜索,如果你在输入后暂停的时间小于规定的时间(delay),就会重新计算该时间。

2.原理

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

3. 代码实现
function debounce(fn, delay) {
    let timer = null
    return function () {
        let _self = this
        let args = [].slice.call(arguments)
        clearTimout(timer)
        timer = setTimout(function () {
            fn.apply(_self, args)
        }, delay)
    }
} 

// 使用
let inp = document.getElementById("inp")
function handler() {
    console.log(this.value)
}
inp.oninput = debounce(handler, 500)

在使用节流函数后,我们在暂停输入的500ms后就会输入输入框内的值,暂停时间小于500ms,则不会输出,将重新计算函数执行时间。

三、分时函数

比如我们在将一个很大的数据渲染成列表的时候,我们要求必须将所有数据渲染完成,不能使用懒加载,所以这样当我们在短时间内往页面添加大量的DOM节点的时候,显然会造成浏览器的卡顿。

let arr = []
for(let a = 0; a < 1000; a++) {
    arr.push(a)
}
function render(data) {
    for(let i = 0; i < arr.length; i++) {
        let div = document.createElement("div")
        div.innerHTML = arr[i]
        document.body.appenChild(div)
    }
}
render(arr)

所以我们我们创建一个函数,然节点的添加分时进行,比如把在1s添加1000个节点改为每隔200ms添加20个节点。

let timeChunk = function (data, fn, count = 20, delay = 200) {
    let obj,timer
    let start = function () {
        for(let i = 0; i < Math.min(count, data.length); i++) {
            let obj = data.shift()
            fn(obj)
        }
    }
    return function () {
        timer = setInterval(function () {
            if(data.length === 0) {
                return clearInterval(timer)
            }
            start()
        }, delay)
    }
}

使用分时函数

let arr = []
for (let a = 0; a < 1000; a++) {
    arr.push(a)
}

function render(data) {
    let div = document.createElement("div")
    div.innerText = data
    document.body.appendChild(div)
}
let renderlist = timeChunk(arr, render, 20, 200)
renderlist()

这样在调用分时函数后每隔200ms创建20个节点。

四、惰性函数

在前端开发中,因为浏览器的差异,一些嗅探工作是不可避免的,比如要实现一个在各个浏览器中都通用的添加事件函数。常见写法:

let addEvent = function (element, type, handler) {
    if(window.addEventListener) {
        return element.addEventLisenter(type, handler, false)
    } else if (window.attachEvent) {
        return element.attachEvent("on"+type, handler)
    }
}

但是我们每次执行函数的时候都要进行分支判断,然后当我们在确定了在哪一种浏览器中执行该函数的时候,我们只需要在第一次判断,后面的使用都不用判断,因为我们是在同一个浏览器执行该函数。

所以我们可以使用惰性加载函数,在函数体内往往都会有一些分支判断,但是在第一次进入分支条件后,在函数内部会重写这个函数,重写之后就是我们所期望的函数,在下一次再进入函数的时候不用在进行分支判断。

let addEvent = function (element, type, handler) {
    if(window.addEventListener) {
        addEvemt = function(element, type, handler) {
            element.addEventLisenter(type, handler, false)
        }
    } else if (window.attachEvent) {
        addEvent = function(element, type, handler) {
            element.attachEvent("on"+type, handler)
        }
    }
    addEvent(element, type, handler)
}

大家可以关注我的掘金地址

参考文献

JavaScript设计模式与开发实践

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102354.html

相关文章

  • 前端每周清单第 34 期:Vue 现状盘点与 3.0 展望,React 代码迁移与优化,图片优化详论

    摘要:工程实践立足实践,提示实际水平内联函数与性能很多关于性能优化的文章都会谈及内联函数,其也是常见的被诟病为拖慢性能表现的元凶之一不过本文却是打破砂锅问到底,论证了内联函数并不一定就会拖慢性能,过度的性能优化反而会有损于应用性能。 showImg(https://segmentfault.com/img/remote/1460000011481413?w=1240&h=825); 前端每周...

    CoderStudy 评论0 收藏0
  • Hack on HHVM —— Facebook是如何优化PHP的

    摘要:周四正式发布了编程语言,将静态类型以及一些现代的语言特性引入了。这是对优化之路上的新里程碑。但是语言层面的优化限制太多,对而言还是不够用。其次是优化运行的步骤。在这方面进行调整,可以提升运行的性能。值得注意的是,给的影响很大。 Facebook周四正式发布了Hack编程语言,将静态类型以及一些现代的语言特性引入了PHP。这是Facebook对PHP优化之路上的新里程碑。 showIm...

    lmxdawn 评论0 收藏0
  • 使用React.memo()优化函数组件的性能

    摘要:函数组件上面我们探讨了如何使用和的方法优化类组件的性能。它的作用和类似,是用来控制函数组件的重新渲染的。其实就是函数组件的。 原文链接: Improving Performance in React Functional Component using React.memo 原文作者: Chidume Nnamdi 译者: 进击的大葱 推荐理由: 本文讲述了开发React应用时如...

    BetaRabbit 评论0 收藏0
  • 高级前端面试题大汇总(只有试题,没有答案)

    摘要:面试题来源于网络,看一下高级前端的面试题,可以知道自己和高级前端的差距。 面试题来源于网络,看一下高级前端的面试题,可以知道自己和高级前端的差距。有些面试题会重复。 使用过的koa2中间件 koa-body原理 介绍自己写过的中间件 有没有涉及到Cluster 介绍pm2 master挂了的话pm2怎么处理 如何和MySQL进行通信 React声明周期及自己的理解 如何...

    kviccn 评论0 收藏0
  • 2018大厂高级前端面试题汇总

    摘要:面试的公司分别是阿里网易滴滴今日头条有赞挖财沪江饿了么携程喜马拉雅兑吧微医寺库宝宝树海康威视蘑菇街酷家乐百分点和海风教育。 (关注福利,关注本公众号回复[资料]领取优质前端视频,包括Vue、React、Node源码和实战、面试指导) 本人于7-8月开始准备面试,过五关斩六将,最终抱得网易归,深深感受到高级前端面试的套路。以下是自己整理的面试题汇总,不敢藏私,统统贡献出来。 面试的公司分...

    zzir 评论0 收藏0

发表评论

0条评论

lncwwn

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<