關(guān)于js函數(shù)節(jié)流和去抖動

實際上啊库倘,今天早上本來想干點別的,但是在吃早餐的時候瀏覽了下掘金,然后看到了這篇博文<a >Jake的關(guān)于圖片懶加載</a> 就順帶研究了一波函數(shù)節(jié)流和去抖動問題。

為什么要函數(shù)節(jié)流

以下場景往往由于事件頻繁被觸發(fā)庵朝,因而頻繁執(zhí)行DOM操作、資源加載等重行為又厉,導致UI停頓甚至瀏覽器崩潰九府。

  1. window對象的resize、scroll事件
  2. 拖拽時的mousemove事件
  3. 射擊游戲中的mousedown覆致、keydown事件
  4. 文字輸入侄旬、自動完成的keyup事件
    例子以scroll事件進行解析
    <code>
    window.onscroll = function(){
    lazyload();
    //throttle(lazyload,window);
    };
    function lazyload(){
    console.log("scroll執(zhí)行了"+scrollnum);
    }
    </code>


    滾動一次

    我們的本意只是讓鼠標滾動一次執(zhí)行一次滾動函數(shù),但是window的onscroll函數(shù)并不是等scroll結(jié)束之后才會調(diào)用煌妈,鼠標滾動或拖動滾動條儡羔,就會不停的觸發(fā)scroll事件宣羊,如果處理的東西多,低版本的IE也會陷入假死狀態(tài)汰蜘。


解決辦法

debounce

抖動:如果用手指一直按住一個彈簧仇冯,它將不會彈起直到你松手為止。 也就是說當調(diào)用動作n毫秒后,才會執(zhí)行該動作壮莹,若在這n毫秒內(nèi)又調(diào)用此動作則將重新計算執(zhí)行時間。這種比較適合window的resize事件,實際需求大多為停止改變大小n毫秒后執(zhí)行后續(xù)處理诵盼;而其他事件大多的需求是以一定的頻率執(zhí)行后續(xù)處理。針對這兩種需求就出現(xiàn)了和throttle兩種解決辦法扰肌。

  1. 去抖1
    <code>
    window.onscroll = function(){
    //lazyload();
    debounce(lazyload,window);
    };
    function debounce(method,context){
    clearTimeout(method.timeout);
    method.timeout = setTimeout(function(){
    method.call(context);
    },500);
    }
    function lazyload(){
    console.log("scroll執(zhí)行了"+scrollnum);
    }
    </code>
    效果如下丙猬,可以看出只執(zhí)行了一次lazyload函數(shù):


    節(jié)流之后的滾動一次的執(zhí)行效果

    利用定時器,讓函數(shù)執(zhí)行延遲500毫秒项滑,在500毫秒內(nèi)如果有函數(shù)又被調(diào)用則刪除上一次調(diào)用依沮,這次調(diào)用500毫秒后執(zhí)行,如此往復
    2.去抖2.
    還有一種節(jié)流方式枪狂,是通過返回閉包的形式危喉,可以設(shè)置延遲時間,兩者運行的結(jié)果是一樣州疾,但是我在實際操作的時候設(shè)置延遲500時辜限,滾動過了一會才執(zhí)行了,設(shè)置為delay為100的時候在視覺上就沒有感覺延遲。而且函數(shù)也只滾動了一次严蓖。
    <code>
    function debounce1(method,delay){
    var timer = null;
    return function(){
    var context = this,args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function(){
    method.apply(context,args);
    },delay);
    }
    }
    </code>

throttle

當我一直滾動鼠標的時候薄嫡,lazyload函數(shù)就會不斷被延遲,這樣只有停下來的時候才會執(zhí)行颗胡,那么再有些需要及時顯示的情況下毫深,就顯得不那么友好了(對于實現(xiàn)keyup事件的提示也沒有意義了),所以可以為函數(shù)添加一個參數(shù)作為到固定間隔必須執(zhí)行毒姨,到了這個時間間隔就必須執(zhí)行哑蔫,這個時候就引入了節(jié)流:
節(jié)流:如果將水龍頭擰緊直到水是以水滴的形式流出,那你會發(fā)現(xiàn)每隔一段時間弧呐,就會有一滴水流出闸迷。也就是會說預先設(shè)定一個執(zhí)行周期,當調(diào)用動作的時刻大于等于執(zhí)行周期則執(zhí)行該動作泉懦,然后進入下一個新周期
代碼如下:
<code>
function throttle2(method, delay, time) {
var timeout,startTime = new Date();
return function() {
var context = this,
args = arguments,
curTime = new Date();
clearTimeout(timeout);
// 如果達到了規(guī)定的觸發(fā)時間間隔稿黍,觸發(fā) handler
if (curTime - startTime >= time) {
method.apply(context, args);
startTime = curTime;
// 沒達到觸發(fā)間隔,重新設(shè)定定時器
} else {
timeout = setTimeout(method, delay);
}
};
</code>



在這個函數(shù)中崩哩,當一次時間較長的時候還是會執(zhí)行兩次巡球,而不是等滾動停止之后再執(zhí)行言沐。達到了想要的效果,既沒有頻繁的執(zhí)行也沒有最后執(zhí)行

引一波圖片懶加載酣栈。

頁面加載速度影響最大的就是圖片险胰,一張普通的圖片可以達到幾M的大小,而代碼也許就只有幾十KB矿筝。當頁面圖片很多時起便,頁面的加載速度緩慢,幾S鐘內(nèi)頁面沒有加載完成窖维,也許會失去很多的用戶榆综。
所以,對于圖片過多的頁面铸史,為了加速頁面加載速度鼻疮,所以很多時候我們需要將頁面內(nèi)未出現(xiàn)在可視區(qū)域內(nèi)的圖片先不做加載, 等到滾動到可視區(qū)域后再去加載琳轿。這樣子對于頁面加載性能上會有很大的提升判沟,也提高了用戶體驗。

將頁面中的img標簽src指向一張小圖片或者src為空崭篡,然后定義data-src(這個屬性可以自定義命名挪哄,我才用data-src)屬性指向真實的圖片。src指向一張默認的圖片琉闪,否則當src為空時也會向服務器發(fā)送一次請求迹炼。可以指向loading的地址

只有當滾動到該圖片的時候才將該圖片的src換為data-src塘偎。這樣就能加速加載速度疗涉。


這樣一開始頁面只需要加載一張圖片
滾動兩次之后

參考網(wǎng)址:https://gold.xitu.io/post/583b10640ce463006ba2a71a
http://www.cnblogs.com/dolphinX/p/3403821.html
http://blog.csdn.net/fengyinchao/article/details/50749317
https://segmentfault.com/a/1190000002764479
http://www.jb51.net/article/49502.htm
http://www.cnblogs.com/fsjohnhuang/p/4147810.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市吟秩,隨后出現(xiàn)的幾起案子咱扣,更是在濱河造成了極大的恐慌,老刑警劉巖涵防,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件闹伪,死亡現(xiàn)場離奇詭異,居然都是意外死亡壮池,警方通過查閱死者的電腦和手機偏瓤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來椰憋,“玉大人厅克,你說我怎么就攤上這事〕纫溃” “怎么了证舟?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵硕旗,是天一觀的道長。 經(jīng)常有香客問我女责,道長漆枚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任抵知,我火速辦了婚禮墙基,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘刷喜。我一直安慰自己残制,他們只是感情好,可當我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布吱肌。 她就那樣靜靜地躺著痘拆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪氮墨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天吐葵,我揣著相機與錄音规揪,去河邊找鬼。 笑死温峭,一個胖子當著我的面吹牛猛铅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播凤藏,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼奸忽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了揖庄?” 一聲冷哼從身側(cè)響起栗菜,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蹄梢,沒想到半個月后疙筹,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡禁炒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年而咆,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片幕袱。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡暴备,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出们豌,到底是詐尸還是另有隱情涯捻,我是刑警寧澤阁危,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站汰瘫,受9級特大地震影響狂打,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜混弥,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一趴乡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蝗拿,春花似錦晾捏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至仓手,卻和暖如春胖齐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嗽冒。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工呀伙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人添坊。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓剿另,卻偏偏與公主長得像,于是被迫代替她去往敵國和親贬蛙。 傳聞我的和親對象是個殘疾皇子雨女,可洞房花燭夜當晚...
    茶點故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容

  • 工廠模式類似于現(xiàn)實生活中的工廠可以產(chǎn)生大量相似的商品,去做同樣的事情阳准,實現(xiàn)同樣的效果;這時候需要使用工廠模式氛堕。簡單...
    舟漁行舟閱讀 7,731評論 2 17
  • ¥開啟¥ 【iAPP實現(xiàn)進入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程,因...
    小菜c閱讀 6,377評論 0 17
  • HTML5面試題總結(jié)1.基礎(chǔ)問題 = 和 == 和 === 的區(qū)別溺职?= : 用于賦值 == : 用于判斷 === ...
    LorenaLu閱讀 1,177評論 0 4
  • 人生就像是煙花岔擂,變化莫測,你永遠猜不準浪耘,下一刻會是什么顏色乱灵,什么形狀,會發(fā)生什么七冲,你只知道痛倚,你的人生并不像煙...
    小名博涵閱讀 237評論 0 0
  • 最近真是怠惰的季節(jié),書也不想看澜躺,電視劇也不想看(雖然還是看了不少)蝉稳,課題也沒能理想(雖然沒日沒夜仿真)抒蚜。 看這本書...
    Tunatime閱讀 205評論 0 0