国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

從瀏覽器多進(jìn)程到JS單線程,JS運(yùn)行機(jī)制最全面的一次梳理

wanghui / 2112人閱讀

摘要:如果看完本文后,還對進(jìn)程線程傻傻分不清,不清楚瀏覽器多進(jìn)程瀏覽器內(nèi)核多線程單線程運(yùn)行機(jī)制的區(qū)別。因此準(zhǔn)備梳理這塊知識點(diǎn),結(jié)合已有的認(rèn)知,基于網(wǎng)上的大量參考資料,從瀏覽器多進(jìn)程到單線程,將引擎的運(yùn)行機(jī)制系統(tǒng)的梳理一遍。

前言

見解有限,如有描述不當(dāng)之處,請幫忙及時指出,如有錯誤,會及時修正。

----------超長文+多圖預(yù)警,需要花費(fèi)不少時間。----------

如果看完本文后,還對進(jìn)程線程傻傻分不清,不清楚瀏覽器多進(jìn)程、瀏覽器內(nèi)核多線程、JS單線程、JS運(yùn)行機(jī)制的區(qū)別。那么請回復(fù)我,一定是我寫的還不夠清晰,我來改。。。

----------正文開始----------

最近發(fā)現(xiàn)有不少介紹JS單線程運(yùn)行機(jī)制的文章,但是發(fā)現(xiàn)很多都僅僅是介紹某一部分的知識,而且各個地方的說法還不統(tǒng)一,容易造成困惑。
因此準(zhǔn)備梳理這塊知識點(diǎn),結(jié)合已有的認(rèn)知,基于網(wǎng)上的大量參考資料,
從瀏覽器多進(jìn)程到JS單線程,將JS引擎的運(yùn)行機(jī)制系統(tǒng)的梳理一遍。

展現(xiàn)形式:由于是屬于系統(tǒng)梳理型,就沒有由淺入深了,而是從頭到尾的梳理知識體系,
重點(diǎn)是將關(guān)鍵節(jié)點(diǎn)的知識點(diǎn)串聯(lián)起來,而不是僅僅剖析某一部分知識。

內(nèi)容是:從瀏覽器進(jìn)程,再到瀏覽器內(nèi)核運(yùn)行,再到JS引擎單線程,再到JS事件循環(huán)機(jī)制,從頭到尾系統(tǒng)的梳理一遍,擺脫碎片化,形成一個知識體系

目標(biāo)是:看完這篇文章后,對瀏覽器多進(jìn)程,JS單線程,JS事件循環(huán)機(jī)制這些都能有一定理解,
有一個知識體系骨架,而不是似懂非懂的感覺。

另外,本文適合有一定經(jīng)驗(yàn)的前端人員,新手請規(guī)避,避免受到過多的概念沖擊。可以先存起來,有了一定理解后再看,也可以分成多批次觀看,避免過度疲勞。

大綱

區(qū)分進(jìn)程和線程

瀏覽器是多進(jìn)程的

瀏覽器都包含哪些進(jìn)程?

瀏覽器多進(jìn)程的優(yōu)勢

重點(diǎn)是瀏覽器內(nèi)核(渲染進(jìn)程)

Browser進(jìn)程和瀏覽器內(nèi)核(Renderer進(jìn)程)的通信過程

梳理瀏覽器內(nèi)核中線程之間的關(guān)系

GUI渲染線程與JS引擎線程互斥

JS阻塞頁面加載

WebWorker,JS的多線程?

WebWorker與SharedWorker

簡單梳理下瀏覽器渲染流程

load事件與DOMContentLoaded事件的先后

css加載是否會阻塞dom樹渲染?

普通圖層和復(fù)合圖層

從Event Loop談JS的運(yùn)行機(jī)制

事件循環(huán)機(jī)制進(jìn)一步補(bǔ)充

多帶帶說說定時器

setTimeout而不是setInterval

事件循環(huán)進(jìn)階:macrotask與microtask

寫在最后的話

區(qū)分進(jìn)程和線程

線程和進(jìn)程區(qū)分不清,是很多新手都會犯的錯誤,沒有關(guān)系。這很正常。先看看下面這個形象的比喻:

- 進(jìn)程是一個工廠,工廠有它的獨(dú)立資源

- 工廠之間相互獨(dú)立

- 線程是工廠中的工人,多個工人協(xié)作完成任務(wù)

- 工廠內(nèi)有一個或多個工人

- 工人之間共享空間

再完善完善概念:

- 工廠的資源 -> 系統(tǒng)分配的內(nèi)存(獨(dú)立的一塊內(nèi)存)

- 工廠之間的相互獨(dú)立 -> 進(jìn)程之間相互獨(dú)立

- 多個工人協(xié)作完成任務(wù) -> 多個線程在進(jìn)程中協(xié)作完成任務(wù)

- 工廠內(nèi)有一個或多個工人 -> 一個進(jìn)程由一個或多個線程組成

- 工人之間共享空間 -> 同一進(jìn)程下的各個線程之間共享程序的內(nèi)存空間(包括代碼段、數(shù)據(jù)集、堆等)

然后再鞏固下:

如果是windows電腦中,可以打開任務(wù)管理器,可以看到有一個后臺進(jìn)程列表。對,那里就是查看進(jìn)程的地方,而且可以看到每個進(jìn)程的內(nèi)存資源信息以及cpu占有率。

所以,應(yīng)該更容易理解了:進(jìn)程是cpu資源分配的最小單位(系統(tǒng)會給它分配內(nèi)存)

最后,再用較為官方的術(shù)語描述一遍:

進(jìn)程是cpu資源分配的最小單位(是能擁有資源和獨(dú)立運(yùn)行的最小單位)

線程是cpu調(diào)度的最小單位(線程是建立在進(jìn)程的基礎(chǔ)上的一次程序運(yùn)行單位,一個進(jìn)程中可以有多個線程)

tips

不同進(jìn)程之間也可以通信,不過代價較大

現(xiàn)在,一般通用的叫法:單線程與多線程,都是指在一個進(jìn)程內(nèi)的單和多。(所以核心還是得屬于一個進(jìn)程才行)

瀏覽器是多進(jìn)程的

理解了進(jìn)程與線程了區(qū)別后,接下來對瀏覽器進(jìn)行一定程度上的認(rèn)識:(先看下簡化理解)

瀏覽器是多進(jìn)程的

瀏覽器之所以能夠運(yùn)行,是因?yàn)橄到y(tǒng)給它的進(jìn)程分配了資源(cpu、內(nèi)存)

簡單點(diǎn)理解,每打開一個Tab頁,就相當(dāng)于創(chuàng)建了一個獨(dú)立的瀏覽器進(jìn)程。

關(guān)于以上幾點(diǎn)的驗(yàn)證,請再第一張圖

圖中打開了Chrome瀏覽器的多個標(biāo)簽頁,然后可以在Chrome的任務(wù)管理器中看到有多個進(jìn)程(分別是每一個Tab頁面有一個獨(dú)立的進(jìn)程,以及一個主進(jìn)程)。
感興趣的可以自行嘗試下,如果再多打開一個Tab頁,進(jìn)程正常會+1以上

注意:在這里瀏覽器應(yīng)該也有自己的優(yōu)化機(jī)制,有時候打開多個tab頁后,可以在Chrome任務(wù)管理器中看到,有些進(jìn)程被合并了
(所以每一個Tab標(biāo)簽對應(yīng)一個進(jìn)程并不一定是絕對的)

瀏覽器都包含哪些進(jìn)程?

知道了瀏覽器是多進(jìn)程后,再來看看它到底包含哪些進(jìn)程:(為了簡化理解,僅列舉主要進(jìn)程)

Browser進(jìn)程:瀏覽器的主進(jìn)程(負(fù)責(zé)協(xié)調(diào)、主控),只有一個。作用有

負(fù)責(zé)瀏覽器界面顯示,與用戶交互。如前進(jìn),后退等

負(fù)責(zé)各個頁面的管理,創(chuàng)建和銷毀其他進(jìn)程

將Renderer進(jìn)程得到的內(nèi)存中的Bitmap,繪制到用戶界面上

網(wǎng)絡(luò)資源的管理,下載等

第三方插件進(jìn)程:每種類型的插件對應(yīng)一個進(jìn)程,僅當(dāng)使用該插件時才創(chuàng)建

GPU進(jìn)程:最多一個,用于3D繪制等

瀏覽器渲染進(jìn)程(瀏覽器內(nèi)核)(Renderer進(jìn)程,內(nèi)部是多線程的):默認(rèn)每個Tab頁面一個進(jìn)程,互不影響。主要作用為

頁面渲染,腳本執(zhí)行,事件處理等

強(qiáng)化記憶:在瀏覽器中打開一個網(wǎng)頁相當(dāng)于新起了一個進(jìn)程(進(jìn)程內(nèi)有自己的多線程)

當(dāng)然,瀏覽器有時會將多個進(jìn)程合并(譬如打開多個空白標(biāo)簽頁后,會發(fā)現(xiàn)多個空白標(biāo)簽頁被合并成了一個進(jìn)程),如圖

另外,可以通過Chrome的更多工具 -> 任務(wù)管理器自行驗(yàn)證

瀏覽器多進(jìn)程的優(yōu)勢

相比于單進(jìn)程瀏覽器,多進(jìn)程有如下優(yōu)點(diǎn):

避免單個page crash影響整個瀏覽器

避免第三方插件crash影響整個瀏覽器

多進(jìn)程充分利用多核優(yōu)勢

方便使用沙盒模型隔離插件等進(jìn)程,提高瀏覽器穩(wěn)定性

簡單點(diǎn)理解:如果瀏覽器是單進(jìn)程,那么某個Tab頁崩潰了,就影響了整個瀏覽器,體驗(yàn)有多差;同理如果是單進(jìn)程,插件崩潰了也會影響整個瀏覽器;而且多進(jìn)程還有其它的諸多優(yōu)勢。。。

當(dāng)然,內(nèi)存等資源消耗也會更大,有點(diǎn)空間換時間的意思。

重點(diǎn)是瀏覽器內(nèi)核(渲染進(jìn)程)

重點(diǎn)來了,我們可以看到,上面提到了這么多的進(jìn)程,那么,對于普通的前端操作來說,最終要的是什么呢?答案是渲染進(jìn)程

可以這樣理解,頁面的渲染,JS的執(zhí)行,事件的循環(huán),都在這個進(jìn)程內(nèi)進(jìn)行。接下來重點(diǎn)分析這個進(jìn)程

請牢記,瀏覽器的渲染進(jìn)程是多線程的(這點(diǎn)如果不理解,請回頭看進(jìn)程和線程的區(qū)分

終于到了線程這個概念了?,好親切。那么接下來看看它都包含了哪些線程(列舉一些主要常駐線程):

GUI渲染線程

負(fù)責(zé)渲染瀏覽器界面,解析HTML,CSS,構(gòu)建DOM樹和RenderObject樹,布局和繪制等。

當(dāng)界面需要重繪(Repaint)或由于某種操作引發(fā)回流(reflow)時,該線程就會執(zhí)行

注意,GUI渲染線程與JS引擎線程是互斥的,當(dāng)JS引擎執(zhí)行時GUI線程會被掛起(相當(dāng)于被凍結(jié)了),GUI更新會被保存在一個隊列中等到JS引擎空閑時立即被執(zhí)行。

JS引擎線程

也稱為JS內(nèi)核,負(fù)責(zé)處理Javascript腳本程序。(例如V8引擎)

JS引擎線程負(fù)責(zé)解析Javascript腳本,運(yùn)行代碼。

JS引擎一直等待著任務(wù)隊列中任務(wù)的到來,然后加以處理,一個Tab頁(renderer進(jìn)程)中無論什么時候都只有一個JS線程在運(yùn)行JS程序

同樣注意,GUI渲染線程與JS引擎線程是互斥的,所以如果JS執(zhí)行的時間過長,這樣就會造成頁面的渲染不連貫,導(dǎo)致頁面渲染加載阻塞。

事件觸發(fā)線程

歸屬于瀏覽器而不是JS引擎,用來控制事件循環(huán)(可以理解,JS引擎自己都忙不過來,需要瀏覽器另開線程協(xié)助)

當(dāng)JS引擎執(zhí)行代碼塊如setTimeOut時(也可來自瀏覽器內(nèi)核的其他線程,如鼠標(biāo)點(diǎn)擊、AJAX異步請求等),會將對應(yīng)任務(wù)添加到事件線程中

當(dāng)對應(yīng)的事件符合觸發(fā)條件被觸發(fā)時,該線程會把事件添加到待處理隊列的隊尾,等待JS引擎的處理

注意,由于JS的單線程關(guān)系,所以這些待處理隊列中的事件都得排隊等待JS引擎處理(當(dāng)JS引擎空閑時才會去執(zhí)行)

定時觸發(fā)器線程

傳說中的setIntervalsetTimeout所在線程

瀏覽器定時計數(shù)器并不是由JavaScript引擎計數(shù)的,(因?yàn)镴avaScript引擎是單線程的, 如果處于阻塞線程狀態(tài)就會影響記計時的準(zhǔn)確)

因此通過多帶帶線程來計時并觸發(fā)定時(計時完畢后,添加到事件隊列中,等待JS引擎空閑后執(zhí)行)

注意,W3C在HTML標(biāo)準(zhǔn)中規(guī)定,規(guī)定要求setTimeout中低于4ms的時間間隔算為4ms。

異步http請求線程

在XMLHttpRequest在連接后是通過瀏覽器新開一個線程請求

將檢測到狀態(tài)變更時,如果設(shè)置有回調(diào)函數(shù),異步線程就產(chǎn)生狀態(tài)變更事件,將這個回調(diào)再放入事件隊列中。再由JavaScript引擎執(zhí)行。

看到這里,如果覺得累了,可以先休息下,這些概念需要被消化,畢竟后續(xù)將提到的事件循環(huán)機(jī)制就是基于事件觸發(fā)線程的,所以如果僅僅是看某個碎片化知識,
可能會有一種似懂非懂的感覺。要完成的梳理一遍才能快速沉淀,不易遺忘。放張圖鞏固下吧:

再說一點(diǎn),為什么JS引擎是單線程的?額,這個問題其實(shí)應(yīng)該沒有標(biāo)準(zhǔn)答案,譬如,可能僅僅是因?yàn)橛捎诙嗑€程的復(fù)雜性,譬如多線程操作一般要加鎖,因此最初設(shè)計時選擇了單線程。。。

Browser進(jìn)程和瀏覽器內(nèi)核(Renderer進(jìn)程)的通信過程

看到這里,首先,應(yīng)該對瀏覽器內(nèi)的進(jìn)程和線程都有一定理解了,那么接下來,再談?wù)劄g覽器的Browser進(jìn)程(控制進(jìn)程)是如何和內(nèi)核通信的,
這點(diǎn)也理解后,就可以將這部分的知識串聯(lián)起來,從頭到尾有一個完整的概念。

如果自己打開任務(wù)管理器,然后打開一個瀏覽器,就可以看到:任務(wù)管理器中出現(xiàn)了兩個進(jìn)程(一個是主控進(jìn)程,一個則是打開Tab頁的渲染進(jìn)程)
然后在這前提下,看下整個的過程:(簡化了很多)

Browser進(jìn)程收到用戶請求,首先需要獲取頁面內(nèi)容(譬如通過網(wǎng)絡(luò)下載資源),隨后將該任務(wù)通過RendererHost接口傳遞給Render進(jìn)程

Renderer進(jìn)程的Renderer接口收到消息,簡單解釋后,交給渲染線程,然后開始渲染

渲染線程接收請求,加載網(wǎng)頁并渲染網(wǎng)頁,這其中可能需要Browser進(jìn)程獲取資源和需要GPU進(jìn)程來幫助渲染

當(dāng)然可能會有JS線程操作DOM(這樣可能會造成回流并重繪)

最后Render進(jìn)程將結(jié)果傳遞給Browser進(jìn)程

Browser進(jìn)程接收到結(jié)果并將結(jié)果繪制出來

這里繪一張簡單的圖:(很簡化)

看完這一整套流程,應(yīng)該對瀏覽器的運(yùn)作有了一定理解了,這樣有了知識架構(gòu)的基礎(chǔ)后,后續(xù)就方便往上填充內(nèi)容。

這塊再往深處講的話就涉及到瀏覽器內(nèi)核源碼解析了,不屬于本文范圍。

如果這一塊要深挖,建議去讀一些瀏覽器內(nèi)核源碼解析文章,或者可以先看看參考下來源中的第一篇文章,寫的不錯

梳理瀏覽器內(nèi)核中線程之間的關(guān)系

到了這里,已經(jīng)對瀏覽器的運(yùn)行有了一個整體的概念,接下來,先簡單梳理一些概念

GUI渲染線程與JS引擎線程互斥

由于JavaScript是可操縱DOM的,如果在修改這些元素屬性同時渲染界面(即JS線程和UI線程同時運(yùn)行),那么渲染線程前后獲得的元素數(shù)據(jù)就可能不一致了。

因此為了防止渲染出現(xiàn)不可預(yù)期的結(jié)果,瀏覽器設(shè)置GUI渲染線程與JS引擎為互斥的關(guān)系,當(dāng)JS引擎執(zhí)行時GUI線程會被掛起,
GUI更新則會被保存在一個隊列中等到JS引擎線程空閑時立即被執(zhí)行。

JS阻塞頁面加載

從上述的互斥關(guān)系,可以推導(dǎo)出,JS如果執(zhí)行時間過長就會阻塞頁面。

譬如,假設(shè)JS引擎正在進(jìn)行巨量的計算,此時就算GUI有更新,也會被保存到隊列中,等待JS引擎空閑后執(zhí)行。
然后,由于巨量計算,所以JS引擎很可能很久很久后才能空閑,自然會感覺到巨卡無比。

所以,要盡量避免JS執(zhí)行時間過長,這樣就會造成頁面的渲染不連貫,導(dǎo)致頁面渲染加載阻塞的感覺。

WebWorker,JS的多線程?

前文中有提到JS引擎是單線程的,而且JS執(zhí)行時間過長會阻塞頁面,那么JS就真的對cpu密集型計算無能為力么?

所以,后來HTML5中支持了Web Worker

MDN的官方解釋是:

Web Worker為Web內(nèi)容在后臺線程中運(yùn)行腳本提供了一種簡單的方法。線程可以執(zhí)行任務(wù)而不干擾用戶界面

一個worker是使用一個構(gòu)造函數(shù)創(chuàng)建的一個對象(e.g. Worker()) 運(yùn)行一個命名的JavaScript文件 

這個文件包含將在工作線程中運(yùn)行的代碼; workers 運(yùn)行在另一個全局上下文中,不同于當(dāng)前的window

因此,使用 window快捷方式獲取當(dāng)前全局的范圍 (而不是self) 在一個 Worker 內(nèi)將返回錯誤

這樣理解下:

創(chuàng)建Worker時,JS引擎向?yàn)g覽器申請開一個子線程(子線程是瀏覽器開的,完全受主線程控制,而且不能操作DOM)

JS引擎線程與worker線程間通過特定的方式通信(postMessage API,需要通過序列化對象來與線程交互特定的數(shù)據(jù))

所以,如果有非常耗時的工作,請多帶帶開一個Worker線程,這樣里面不管如何翻天覆地都不會影響JS引擎主線程,
只待計算出結(jié)果后,將結(jié)果通信給主線程即可,perfect!

而且注意下,JS引擎是單線程的,這一點(diǎn)的本質(zhì)仍然未改變,Worker可以理解是瀏覽器給JS引擎開的外掛,專門用來解決那些大量計算問題。

其它,關(guān)于Worker的詳解就不是本文的范疇了,因此不再贅述。

WebWorker與SharedWorker

既然都到了這里,就再提一下SharedWorker(避免后續(xù)將這兩個概念搞混)

WebWorker只屬于某個頁面,不會和其他頁面的Render進(jìn)程(瀏覽器內(nèi)核進(jìn)程)共享

所以Chrome在Render進(jìn)程中(每一個Tab頁就是一個render進(jìn)程)創(chuàng)建一個新的線程來運(yùn)行Worker中的JavaScript程序。

SharedWorker是瀏覽器所有頁面共享的,不能采用與Worker同樣的方式實(shí)現(xiàn),因?yàn)樗浑`屬于某個Render進(jìn)程,可以為多個Render進(jìn)程共享使用

所以Chrome瀏覽器為SharedWorker多帶帶創(chuàng)建一個進(jìn)程來運(yùn)行JavaScript程序,在瀏覽器中每個相同的JavaScript只存在一個SharedWorker進(jìn)程,不管它被創(chuàng)建多少次。

看到這里,應(yīng)該就很容易明白了,本質(zhì)上就是進(jìn)程和線程的區(qū)別。SharedWorker由獨(dú)立的進(jìn)程管理,WebWorker只是屬于render進(jìn)程下的一個線程

簡單梳理下瀏覽器渲染流程

本來是直接計劃開始談JS運(yùn)行機(jī)制的,但想了想,既然上述都一直在談瀏覽器,直接跳到JS可能再突兀,因此,中間再補(bǔ)充下瀏覽器的渲染流程(簡單版本)

為了簡化理解,前期工作直接省略成:(要展開的或完全可以寫另一篇超長文)

- 瀏覽器輸入url,瀏覽器主進(jìn)程接管,開一個下載線程,
然后進(jìn)行 http請求(略去DNS查詢,IP尋址等等操作),然后等待響應(yīng),獲取內(nèi)容,
隨后將內(nèi)容通過RendererHost接口轉(zhuǎn)交給Renderer進(jìn)程

- 瀏覽器渲染流程開始

瀏覽器器內(nèi)核拿到內(nèi)容后,渲染大概可以劃分成以下幾個步驟:

解析html建立dom樹

解析css構(gòu)建render樹(將CSS代碼解析成樹形的數(shù)據(jù)結(jié)構(gòu),然后結(jié)合DOM合并成render樹)

布局render樹(Layout/reflow),負(fù)責(zé)各元素尺寸、位置的計算

繪制render樹(paint),繪制頁面像素信息

瀏覽器會將各層的信息發(fā)送給GPU,GPU會將各層合成(composite),顯示在屏幕上。

所有詳細(xì)步驟都已經(jīng)略去,渲染完畢后就是load事件了,之后就是自己的JS邏輯處理了

既然略去了一些詳細(xì)的步驟,那么就提一些可能需要注意的細(xì)節(jié)把。

這里重繪參考來源中的一張圖:(參考來源第一篇)

load事件與DOMContentLoaded事件的先后

上面提到,渲染完畢后會觸發(fā)load事件,那么你能分清楚load事件與DOMContentLoaded事件的先后么?

很簡單,知道它們的定義就可以了:

當(dāng) DOMContentLoaded 事件觸發(fā)時,僅當(dāng)DOM加載完成,不包括樣式表,圖片。

(譬如如果有async加載的腳本就不一定完成)

當(dāng) onload 事件觸發(fā)時,頁面上所有的DOM,樣式表,腳本,圖片都已經(jīng)加載完成了。

(渲染完畢了)

所以,順序是:DOMContentLoaded -> load

css加載是否會阻塞dom樹渲染?

這里說的是頭部引入css的情況

首先,我們都知道:css是由多帶帶的下載線程異步下載的。

然后再說下幾個現(xiàn)象:

css加載不會阻塞DOM樹解析(異步加載時DOM照常構(gòu)建)

但會阻塞render樹渲染(渲染時需等css加載完畢,因?yàn)閞ender樹需要css信息)

這可能也是瀏覽器的一種優(yōu)化機(jī)制。

因?yàn)槟慵虞dcss的時候,可能會修改下面DOM節(jié)點(diǎn)的樣式,
如果css加載不阻塞render樹渲染的話,那么當(dāng)css加載完之后,
render樹可能又得重新重繪或者回流了,這就造成了一些沒有必要的損耗。
所以干脆就先把DOM樹的結(jié)構(gòu)先解析完,把可以做的工作做完,然后等你css加載完之后,
在根據(jù)最終的樣式來渲染render樹,這種做法性能方面確實(shí)會比較好一點(diǎn)。

普通圖層和復(fù)合圖層

渲染步驟中就提到了composite概念。

可以簡單的這樣理解,瀏覽器渲染的圖層一般包含兩大類:普通圖層以及復(fù)合圖層

首先,普通文檔流內(nèi)可以理解為一個復(fù)合圖層(這里稱為默認(rèn)復(fù)合層,里面不管添加多少元素,其實(shí)都是在同一個復(fù)合圖層中)

其次,absolute布局(fixed也一樣),雖然可以脫離普通文檔流,但它仍然屬于默認(rèn)復(fù)合層

然后,可以通過硬件加速的方式,聲明一個新的復(fù)合圖層,它會多帶帶分配資源
(當(dāng)然也會脫離普通文檔流,這樣一來,不管這個復(fù)合圖層中怎么變化,也不會影響默認(rèn)復(fù)合層里的回流重繪)

可以簡單理解下:GPU中,各個復(fù)合圖層是多帶帶繪制的,所以互不影響,這也是為什么某些場景硬件加速效果一級棒

可以Chrome源碼調(diào)試 -> More Tools -> Rendering -> Layer borders中看到,黃色的就是復(fù)合圖層信息

如下圖。可以驗(yàn)證上述的說法

如何變成復(fù)合圖層(硬件加速)

將該元素變成一個復(fù)合圖層,就是傳說中的硬件加速技術(shù)

最常用的方式:translate3dtranslateZ

opacity屬性/過渡動畫(需要動畫執(zhí)行的過程中才會創(chuàng)建合成層,動畫沒有開始或結(jié)束后元素還會回到之前的狀態(tài))

will-chang屬性(這個比較偏僻),一般配合opacity與translate使用(而且經(jīng)測試,除了上述可以引發(fā)硬件加速的屬性外,其它屬性并不會變成復(fù)合層),

作用是提前告訴瀏覽器要變化,這樣瀏覽器會開始做一些優(yōu)化工作(這個最好用完后就釋放)