高性能Scroll

// 簡(jiǎn)單的防抖動(dòng)函數(shù)
function debounce(func, wait, immediate) {
    // 定時(shí)器變量
    var timeout;
    return function() {
        // 每次觸發(fā) scroll handler 時(shí)先清除定時(shí)器
        clearTimeout(timeout);
        // 指定 xx ms 后觸發(fā)真正想進(jìn)行的操作 handler
        timeout = setTimeout(func, wait);
    };
};
 
// 實(shí)際想綁定在 scroll 事件上的 handler
function realFunc(){
    console.log("Success");
}
 
// 采用了防抖動(dòng)
window.addEventListener('scroll',debounce(realFunc,500));
// 沒采用防抖動(dòng)
window.addEventListener('scroll',realFunc);
// 防抖動(dòng)函數(shù)
function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate & !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};
 
var myEfficientFn = debounce(function() {
    // 滾動(dòng)中的真正的操作
}, 250);
 
// 綁定監(jiān)聽
window.addEventListener('resize', myEfficientFn);
// 簡(jiǎn)單的節(jié)流函數(shù)
function throttle(func, wait, mustRun) {
    var timeout,
        startTime = new Date();

    return function() {
        var context = this,
            args = arguments,
            curTime = new Date();

        clearTimeout(timeout);
        // 如果達(dá)到了規(guī)定的觸發(fā)時(shí)間間隔盹舞,觸發(fā) handler
        if(curTime - startTime >= mustRun){
            func.apply(context,args);
            startTime = curTime;
        // 沒達(dá)到觸發(fā)間隔弦追,重新設(shè)定定時(shí)器
        }else{
            timeout = setTimeout(func, wait);
        }
    };
};
// 實(shí)際想綁定在 scroll 事件上的 handler
function realFunc(){
    console.log("Success");
}
// 采用了節(jié)流函數(shù)
window.addEventListener('scroll',throttle(realFunc,500,1000));
var ticking = false; // rAF 觸發(fā)鎖

function onScroll(){
  if(!ticking) {
    requestAnimationFrame(realFunc);
    ticking = true;
  }
}

function realFunc(){
    // do something...
    console.log("Success");
    ticking = false;
}
// 滾動(dòng)事件監(jiān)聽
window.addEventListener('scroll', onScroll, false);
//rAF:16.7ms

原文來自http://mp.weixin.qq.com/s/LgwTCzBgYWBe2JFXg8YMtQ

2019.11.20更新

廢話不多說直接上代碼

   useEffect(() => {
    let time: NodeJS.Timeout
    let startTime: Date = new Date()
    const handleCallBack = () => {
      const { scrollY } = window
      const { clientHeight, scrollHeight } = document.documentElement
      if (clientHeight + scrollY >= scrollHeight - 60) {
        callback()
      }
    }
    // TODO:優(yōu)化監(jiān)聽
    // requestAnimationFrame()
    const throttle = () => {
      clearTimeout(time)
      const currentTime: Date = new Date()
      if (Number(currentTime) - Number(startTime) >= mustTime) {
        // 規(guī)定時(shí)間內(nèi)必須執(zhí)行一次
        handleCallBack()
        startTime = currentTime
      } else
        time = setTimeout(() => {
          // 防抖動(dòng)
          handleCallBack()
        }, waitTime)
    }

    window.addEventListener('scroll', throttle)
    return () => {
      window.removeEventListener('scroll', throttle)
    }
  }, [callback, mustTime, waitTime])
//這是自己寫的一個(gè)基于 防抖+節(jié)流的方式實(shí)現(xiàn)的滾動(dòng)加載監(jiān)聽的自定義hook 留著后面直接復(fù)制粘貼
//但是qa在測(cè)試的時(shí)候發(fā)現(xiàn)在安卓系統(tǒng)的瀏覽器上會(huì)有兼容的問題 如果僅僅是使用在微信上應(yīng)該問題不大
useEffect(() => {
    let doing = false;
    const handleCallBack = () => {
      const { scrollY } = window
      const { clientHeight, scrollHeight } = document.documentElement || document.body
      if (clientHeight + scrollY >= scrollHeight - 60) {
        callback()
      }
      doing = false
    }
    const rafCallback = () => {
      if (doing) return
      doing = true
      window.requestAnimationFrame(handleCallBack)
    }
    window.addEventListener('scroll', rafCallback)
    return () => {
      window.removeEventListener('scroll', rafCallback)
    }
  }, [callback])
//這是使用requestAnimationFrame方法根據(jù)屏幕刷新頻率(例如60Hz)在屏幕渲染每一幀結(jié)束之后出發(fā)的監(jiān)聽效果
//避免上面setTimeout的方式監(jiān)聽會(huì)引發(fā)渲染回流的問題
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末亭畜,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子锣枝,更是在濱河造成了極大的恐慌厢拭,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撇叁,死亡現(xiàn)場(chǎng)離奇詭異供鸠,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)陨闹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門楞捂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人趋厉,你說我怎么就攤上這事寨闹。” “怎么了君账?”我有些...
    開封第一講書人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵繁堡,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我乡数,道長(zhǎng)椭蹄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任净赴,我火速辦了婚禮绳矩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘玖翅。我一直安慰自己埋酬,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開白布烧栋。 她就那樣靜靜地躺著写妥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪审姓。 梳的紋絲不亂的頭發(fā)上珍特,一...
    開封第一講書人閱讀 51,624評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音魔吐,去河邊找鬼扎筒。 笑死,一個(gè)胖子當(dāng)著我的面吹牛酬姆,可吹牛的內(nèi)容都是我干的嗜桌。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼辞色,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼骨宠!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤层亿,失蹤者是張志新(化名)和其女友劉穎桦卒,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體匿又,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡方灾,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了碌更。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片裕偿。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖痛单,靈堂內(nèi)的尸體忽然破棺而出嘿棘,到底是詐尸還是另有隱情,我是刑警寧澤桦他,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站谆棱,受9級(jí)特大地震影響快压,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜垃瞧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一蔫劣、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧个从,春花似錦脉幢、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至奕污,卻和暖如春萎羔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背碳默。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工贾陷, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嘱根。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓髓废,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親该抒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子慌洪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

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