您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關(guān)passive的原理及作用是什么,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
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)性能?
簡(jiǎn)述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)系,一旦頁面元素注冊(cè)了對(duì)應(yīng)事件的監(jiān)聽器,監(jiān)聽器的邏輯代碼(JavaScript)必須在內(nèi)核線程中執(zhí)行(V8引擎運(yùn)行在內(nèi)核線程),因此這種輸入事件經(jīng)常無法立即得到響應(yīng)。
直接由合成線程處理的事件:不經(jīng)過內(nèi)核線程就能快速處理的輸入事件為手勢(shì)輸入事件(滑動(dòng)、捏合)。
劃重點(diǎn):最騷的來了,雖然手勢(shì)事件可以不在內(nèi)核線程處理,但是手勢(shì)事件的產(chǎn)生還是離不開內(nèi)核線程。
頁面卡頓的原因
手勢(shì)事件有個(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)化這種場(chǎng)景。手勢(shì)輸入事件是由連續(xù)的普通輸入事件組成的,在這種場(chǎng)景下,無法快速產(chǎn)生,會(huì)導(dǎo)致頁面無法快速執(zhí)行滑動(dòng)邏輯,從而讓用戶感覺到頁面卡頓。
而Chrome團(tuán)隊(duì)從統(tǒng)計(jì)數(shù)據(jù)中分析得出,注冊(cè)了mousewheel/touch相關(guān)事件監(jiān)聽器的頁面中,80%的頁面內(nèi)部都不會(huì)調(diào)用preventDefault函數(shù)來阻止事件的默認(rèn)行為。對(duì)于這80%的頁面,即使監(jiān)聽器內(nèi)部什么都沒有做,相對(duì)沒有注冊(cè)mousewheel/touch事件監(jiān)聽器的頁面,在滑動(dòng)流暢度上,有10%的頁面增加至少100ms的延遲,1%的頁面甚至增加500ms以上的延遲。Chrome團(tuán)隊(duì)認(rèn)為對(duì)于統(tǒng)計(jì)中的這80%的頁面來說,他們都是不希望因?yàn)樽?cè)mousewheel/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)注億速云行業(yè)資訊頻道,感謝大家的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。