摘要:原理連續(xù)觸發(fā)事件,但是事件函數(shù)只在在規(guī)定的周期之內(nèi)只執(zhí)行一次。代碼實(shí)現(xiàn)使用在使用節(jié)流函數(shù)后,我們在暫停輸入的后就會輸入輸入框內(nèi)的值,暫停時(shí)間小于,則不會輸出,將重新計(jì)算函數(shù)執(zhí)行時(shí)間。使用分時(shí)函數(shù)這樣在調(diào)用分時(shí)函數(shù)后每隔創(chuàng)建個節(jié)點(diǎn)。
一、節(jié)流函數(shù) 1. 使用場景
DOM.onclick()事件,我們給一個DOM節(jié)點(diǎn)綁定了點(diǎn)擊事件,當(dāng)點(diǎn)擊該元素時(shí)觸發(fā)事件函數(shù)的執(zhí)行,但是當(dāng)我們頻繁點(diǎn)擊該元素時(shí),就會不斷觸發(fā)該點(diǎn)擊事件,如果該點(diǎn)擊事件觸發(fā)的事件函數(shù)是DOM元素的,就會造成很高的性能消耗,可能會造成頁面的卡頓。
所以此時(shí)我們應(yīng)該限制該事件的觸發(fā)頻率,減少頁面的開銷。
2. 原理連續(xù)觸發(fā)事件,但是事件函數(shù)只在在規(guī)定的周期之內(nèi)只執(zhí)行一次。
3. 代碼實(shí)現(xiàn)function throttle(fn, wait = 500) { let lastTime = 0 // 初始化上一次調(diào)用的事件 return function () { let args = [].slice.call(arguments) // 將類數(shù)組轉(zhuǎn)化為數(shù)組 let nowTime = new Date().getTime() // 獲取當(dāng)前時(shí)間 if(nowTime - lastTime > wait) { fn.apply(this, args) lastTime = nowTime // 把上一次調(diào)用時(shí)間重新賦值 } } } // 使用 let btn = document.getElementById("btn") let fn = function () { console.log(1) } btn.onclick = throttle(fn, 1000)
在給按鈕加上點(diǎn)擊事件后,即使一直不停的點(diǎn)擊按鈕,也只會每隔1000ms執(zhí)行一次事件處理函數(shù)。
二、防抖函數(shù) 1.使用場景例如我們在百度搜索的輸入框輸入我們想要搜索的內(nèi)容,在我們停止輸入后一小段時(shí)間(delay)后就會得你輸入框得內(nèi)容然后進(jìn)行搜索,如果你在輸入后暫停的時(shí)間小于規(guī)定的時(shí)間(delay),就會重新計(jì)算該時(shí)間。
2.原理所謂防抖,就是指觸發(fā)事件后在 n 秒內(nèi)函數(shù)只能執(zhí)行一次,如果在 n 秒內(nèi)又觸發(fā)了事件,則會重新計(jì)算函數(shù)執(zhí)行時(shí)間。
3. 代碼實(shí)現(xiàn)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)
在使用節(jié)流函數(shù)后,我們在暫停輸入的500ms后就會輸入輸入框內(nèi)的值,暫停時(shí)間小于500ms,則不會輸出,將重新計(jì)算函數(shù)執(zhí)行時(shí)間。
三、分時(shí)函數(shù)比如我們在將一個很大的數(shù)據(jù)渲染成列表的時(shí)候,我們要求必須將所有數(shù)據(jù)渲染完成,不能使用懶加載,所以這樣當(dāng)我們在短時(shí)間內(nèi)往頁面添加大量的DOM節(jié)點(diǎn)的時(shí)候,顯然會造成瀏覽器的卡頓。
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)
所以我們我們創(chuàng)建一個函數(shù),然節(jié)點(diǎn)的添加分時(shí)進(jìn)行,比如把在1s添加1000個節(jié)點(diǎn)改為每隔200ms添加20個節(jié)點(diǎn)。
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) } }
使用分時(shí)函數(shù)
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()
這樣在調(diào)用分時(shí)函數(shù)后每隔200ms創(chuàng)建20個節(jié)點(diǎn)。
四、惰性函數(shù)在前端開發(fā)中,因?yàn)闉g覽器的差異,一些嗅探工作是不可避免的,比如要實(shí)現(xiàn)一個在各個瀏覽器中都通用的添加事件函數(shù)。常見寫法:
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) } }
但是我們每次執(zhí)行函數(shù)的時(shí)候都要進(jìn)行分支判斷,然后當(dāng)我們在確定了在哪一種瀏覽器中執(zhí)行該函數(shù)的時(shí)候,我們只需要在第一次判斷,后面的使用都不用判斷,因?yàn)槲覀兪窃谕粋€瀏覽器執(zhí)行該函數(shù)。
所以我們可以使用惰性加載函數(shù),在函數(shù)體內(nèi)往往都會有一些分支判斷,但是在第一次進(jìn)入分支條件后,在函數(shù)內(nèi)部會重寫這個函數(shù),重寫之后就是我們所期望的函數(shù),在下一次再進(jìn)入函數(shù)的時(shí)候不用在進(jìn)行分支判斷。
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) }
大家可以關(guān)注我的掘金地址
參考文獻(xiàn)JavaScript設(shè)計(jì)模式與開發(fā)實(shí)踐
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/102354.html
摘要:工程實(shí)踐立足實(shí)踐,提示實(shí)際水平內(nèi)聯(lián)函數(shù)與性能很多關(guān)于性能優(yōu)化的文章都會談及內(nèi)聯(lián)函數(shù),其也是常見的被詬病為拖慢性能表現(xiàn)的元兇之一不過本文卻是打破砂鍋問到底,論證了內(nèi)聯(lián)函數(shù)并不一定就會拖慢性能,過度的性能優(yōu)化反而會有損于應(yīng)用性能。 showImg(https://segmentfault.com/img/remote/1460000011481413?w=1240&h=825); 前端每周...
摘要:周四正式發(fā)布了編程語言,將靜態(tài)類型以及一些現(xiàn)代的語言特性引入了。這是對優(yōu)化之路上的新里程碑。但是語言層面的優(yōu)化限制太多,對而言還是不夠用。其次是優(yōu)化運(yùn)行的步驟。在這方面進(jìn)行調(diào)整,可以提升運(yùn)行的性能。值得注意的是,給的影響很大。 Facebook周四正式發(fā)布了Hack編程語言,將靜態(tài)類型以及一些現(xiàn)代的語言特性引入了PHP。這是Facebook對PHP優(yōu)化之路上的新里程碑。 showIm...
摘要:函數(shù)組件上面我們探討了如何使用和的方法優(yōu)化類組件的性能。它的作用和類似,是用來控制函數(shù)組件的重新渲染的。其實(shí)就是函數(shù)組件的。 原文鏈接: Improving Performance in React Functional Component using React.memo 原文作者: Chidume Nnamdi 譯者: 進(jìn)擊的大蔥 推薦理由: 本文講述了開發(fā)React應(yīng)用時(shí)如...
摘要:面試題來源于網(wǎng)絡(luò),看一下高級前端的面試題,可以知道自己和高級前端的差距。 面試題來源于網(wǎng)絡(luò),看一下高級前端的面試題,可以知道自己和高級前端的差距。有些面試題會重復(fù)。 使用過的koa2中間件 koa-body原理 介紹自己寫過的中間件 有沒有涉及到Cluster 介紹pm2 master掛了的話pm2怎么處理 如何和MySQL進(jìn)行通信 React聲明周期及自己的理解 如何...
摘要:面試的公司分別是阿里網(wǎng)易滴滴今日頭條有贊挖財(cái)滬江餓了么攜程喜馬拉雅兌吧微醫(yī)寺庫寶寶樹海康威視蘑菇街酷家樂百分點(diǎn)和海風(fēng)教育。 (關(guān)注福利,關(guān)注本公眾號回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本人于7-8月開始準(zhǔn)備面試,過五關(guān)斬六將,最終抱得網(wǎng)易歸,深深感受到高級前端面試的套路。以下是自己整理的面試題匯總,不敢藏私,統(tǒng)統(tǒng)貢獻(xiàn)出來。 面試的公司分...
閱讀 1361·2019-08-30 15:55
閱讀 1652·2019-08-26 10:21
閱讀 3442·2019-08-23 18:28
閱讀 3380·2019-08-23 15:38
閱讀 748·2019-08-23 15:24
閱讀 2141·2019-08-23 13:59
閱讀 780·2019-08-23 11:31
閱讀 2874·2019-08-23 10:53