今天就跟大家聊聊有關(guān)passive的原理及作用是什么,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
成都創(chuàng)新互聯(lián)是一家專業(yè)從事網(wǎng)站設(shè)計(jì)、成都網(wǎng)站設(shè)計(jì)、網(wǎng)頁設(shè)計(jì)的品牌網(wǎng)絡(luò)公司。如今是成都地區(qū)具影響力的網(wǎng)站設(shè)計(jì)公司,作為專業(yè)的成都網(wǎng)站建設(shè)公司,成都創(chuàng)新互聯(lián)依托強(qiáng)大的技術(shù)實(shí)力、以及多年的網(wǎng)站運(yùn)營經(jīng)驗(yàn),為您提供專業(yè)的成都網(wǎng)站建設(shè)、營銷型網(wǎng)站建設(shè)及網(wǎng)站設(shè)計(jì)開發(fā)服務(wù)!
passived到底有什么用?
passived主要用于優(yōu)化瀏覽器頁面滾動(dòng)的性能,讓頁面滾動(dòng)更順滑~~
passived產(chǎn)生的歷史時(shí)間線
addEventListener():大家都是認(rèn)識(shí)的,為dom添加觸發(fā)事件,故事就從這里開始。
在早期addEventListener是這樣的:
addEventListener(type, listener, useCapture)
useCapture:是否允許事件捕捉,但是很少會(huì)傳true,然后就變成可選項(xiàng)了:
addEventListener(type, listener[, useCapture ])
到現(xiàn)在就變成了這個(gè)樣子:
addEventListener(type, listener, { capture: false, //捕獲 passive: false, once: false //只觸發(fā)一次 })
我們的主角passive就出現(xiàn)了
passive為什么能優(yōu)化頁面的滾動(dòng)性能?
簡述chrome的線程化渲染框架
chrome的線程化渲染框架的兩個(gè)線程:
內(nèi)核線程(Main/Render Thread):負(fù)責(zé)DOM樹構(gòu)建、元素的布局、圖層繪制記錄部分(main-thread side)、JavaScript的執(zhí)行
合成線程(Compositor Thread):圖層繪制實(shí)現(xiàn)部分(impl-side)、圖層圖像合成
上圖可知,頁面Frame#1在內(nèi)核線程中完成js執(zhí)行、布局和繪制后,經(jīng)過一個(gè)周期合成線程去執(zhí)行Frame#1頁面圖像的合成。
用戶輸入事件分類:
在內(nèi)核線程處理的事件
直接由合成線程處理的事件
那么有什么區(qū)別呢?
在內(nèi)核線程處理的事件:需要經(jīng)過內(nèi)核線程處理的輸入事件要在內(nèi)核線程執(zhí)行邏輯,遇到內(nèi)核線程在忙,無法立即響應(yīng)。如用戶的大部分輸入事件都跟頁面元素有關(guān)系,一旦頁面元素注冊了對(duì)應(yīng)事件的監(jiān)聽器,監(jiān)聽器的邏輯代碼(JavaScript)必須在內(nèi)核線程中執(zhí)行(V8引擎運(yùn)行在內(nèi)核線程),因此這種輸入事件經(jīng)常無法立即得到響應(yīng)。
直接由合成線程處理的事件:不經(jīng)過內(nèi)核線程就能快速處理的輸入事件為手勢輸入事件(滑動(dòng)、捏合)。
劃重點(diǎn):最騷的來了,雖然手勢事件可以不在內(nèi)核線程處理,但是手勢事件的產(chǎn)生還是離不開內(nèi)核線程。
頁面卡頓的原因
手勢事件有個(gè)屬性 cancelable,作用是告訴瀏覽器該事件是否允許監(jiān)聽器通過 preventDefault() 方法阻止,默認(rèn)為true。如果在touch事件內(nèi)部調(diào)用preventDefault(),事件默認(rèn)行為被取消,頁面也就靜止不動(dòng)了。但是瀏覽器并不知道touch事件內(nèi)部是否調(diào)用了preventDefault(),瀏覽器只有等內(nèi)核線程執(zhí)行到事件監(jiān)聽器對(duì)應(yīng)的JavaScript代碼時(shí),才能知道內(nèi)部是否會(huì)調(diào)用preventDefault函數(shù)來阻止事件的默認(rèn)行為,所以瀏覽器本身無法優(yōu)化這種場景。手勢輸入事件是由連續(xù)的普通輸入事件組成的,在這種場景下,無法快速產(chǎn)生,會(huì)導(dǎo)致頁面無法快速執(zhí)行滑動(dòng)邏輯,從而讓用戶感覺到頁面卡頓。
而Chrome團(tuán)隊(duì)從統(tǒng)計(jì)數(shù)據(jù)中分析得出,注冊了mousewheel/touch相關(guān)事件監(jiān)聽器的頁面中,80%的頁面內(nèi)部都不會(huì)調(diào)用preventDefault函數(shù)來阻止事件的默認(rèn)行為。對(duì)于這80%的頁面,即使監(jiān)聽器內(nèi)部什么都沒有做,相對(duì)沒有注冊mousewheel/touch事件監(jiān)聽器的頁面,在滑動(dòng)流暢度上,有10%的頁面增加至少100ms的延遲,1%的頁面甚至增加500ms以上的延遲。Chrome團(tuán)隊(duì)認(rèn)為對(duì)于統(tǒng)計(jì)中的這80%的頁面來說,他們都是不希望因?yàn)樽詍ousewheel/touch相關(guān)事件監(jiān)聽器而導(dǎo)致滑動(dòng)延遲增加的。
passive的誕生
所以,passive 監(jiān)聽器誕生了,passive 的意思是“順從的”,表示它不會(huì)對(duì)事件的默認(rèn)行為說 no,瀏覽器知道了一個(gè)監(jiān)聽器是 passive 的,它就可以在兩個(gè)線程里同時(shí)執(zhí)行監(jiān)聽器中的 JavaScript 代碼和瀏覽器的默認(rèn)行為了。
經(jīng)過上面的分析,我們了解到了Passive Event Listeners特性實(shí)際上是為了解決瀏覽器頁面滑動(dòng)流暢度而設(shè)計(jì)的,它通過擴(kuò)展事件屬性passive讓W(xué)eb開發(fā)者來告知瀏覽器監(jiān)聽器是否會(huì)阻止事件的默認(rèn)行為,從而讓瀏覽器可以更智能地決策并優(yōu)化,這其中涉及到了Chrome的多線程渲染框架、輸入事件處理等知識(shí)。
看完上述內(nèi)容,你們對(duì)passive的原理及作用是什么有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。