從瀏覽器渲染了解性能優(yōu)化

前言

為能更好的理解瀏覽器性能優(yōu)化,本文會(huì)從瀏覽器多進(jìn)程架構(gòu)以及瀏覽器渲染過程逐步簡(jiǎn)單解析性能優(yōu)化要點(diǎn)

瀏覽器的多進(jìn)程架構(gòu)

進(jìn)程與線程

進(jìn)程類似于一個(gè)工廠宝磨,工廠擁有獨(dú)立的資源且相互獨(dú)立

線程類似于工廠中的工人忘闻,多個(gè)工人協(xié)作完成任務(wù)且相互共享空間

簡(jiǎn)單理解:

????進(jìn)程是cpu資源分配的最小單位,系統(tǒng)會(huì)為其分配內(nèi)存

????線程是cpu調(diào)度的最小單位,一個(gè)進(jìn)程中可擁有一個(gè)或多個(gè)線程

????不同進(jìn)程之間也可以進(jìn)行通信但是代價(jià)較大

瀏覽器多進(jìn)程

簡(jiǎn)單理解:

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

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

????基本上每打開一個(gè)Tab頁就相當(dāng)于創(chuàng)建了一個(gè)獨(dú)立的瀏覽器進(jìn)程

:瀏覽器有自身的優(yōu)化機(jī)制,打開多個(gè)tab頁后部分tab頁的進(jìn)程會(huì)被合并(例如多個(gè)空白頁合并)

為什么瀏覽器是多進(jìn)程的(主要原因)

想象如果瀏覽器是單線程的元暴,某個(gè)Tab頁或是插件腳本崩潰了就會(huì)影響到整個(gè)瀏覽器,所以瀏覽器為保證穩(wěn)定性設(shè)計(jì)為多進(jìn)程

瀏覽器包含哪些主要進(jìn)程

1. Browser進(jìn)程:瀏覽器的主控進(jìn)程兄猩,只有一個(gè)

????負(fù)責(zé)瀏覽器界面顯示茉盏,與用戶交互

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

????將瀏覽器渲染進(jìn)程存放在內(nèi)存中的bitmap(位圖)繪制到用戶界面上

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

2. 第三方插件進(jìn)程:每種類型的插件對(duì)應(yīng)一個(gè)進(jìn)程援岩,使用插件時(shí)才創(chuàng)建

3. GPU進(jìn)程:最多存在一個(gè),用于3D繪制

4. 瀏覽器渲染進(jìn)程(Renderer進(jìn)程):該進(jìn)程內(nèi)部為多線程掏导,默認(rèn)每個(gè)Tab頁面一個(gè)進(jìn)程,互不影響

? ?頁面渲染羽峰,腳本執(zhí)行趟咆,事件處理等

細(xì)化瀏覽器渲染進(jìn)程

瀏覽器中頁面的渲染,js的執(zhí)行梅屉,事件循環(huán)等都在該進(jìn)程中執(zhí)行值纱,其中包含多個(gè)線程

1. GUI渲染線程

????該線程負(fù)責(zé)渲染頁面,解析HTML于CSS坯汤,并構(gòu)建DOM樹并生成RenderObject樹

????單頁面需要重繪或是因?yàn)槟承┎僮骰亓鲿r(shí)虐唠,該線程就會(huì)執(zhí)行

????:為保證不會(huì)因?yàn)殇秩緯r(shí)改變DOM導(dǎo)致的頁面錯(cuò)亂,GUI渲染線程與JS線程是互斥的

2. JS引擎線程

????其為JS內(nèi)核惰聂,負(fù)責(zé)處理JS腳本語言(V8引擎)

????一個(gè)Tab頁(renderer進(jìn)程)中無論什么時(shí)候都只有一個(gè)JS線程在運(yùn)行JS程序

3. 事件觸發(fā)線程

????其歸屬于瀏覽器用于處理被觸發(fā)的事件并將其回調(diào)函數(shù)放置于任務(wù)隊(duì)列中疆偿,待JS主執(zhí)行棧空時(shí)按一定規(guī)則執(zhí)行任務(wù)隊(duì)列中的回調(diào)函數(shù)

4. 定時(shí)器觸發(fā)線程

????用于處理setTimeout或是setInterval

5. 異步HTTP請(qǐng)求線程

????用于處理頁面中存在的異步HTTP請(qǐng)求搓幌,并將回調(diào)放入事件隊(duì)列中杆故,最后由js引擎執(zhí)行


頁面構(gòu)建過程

瀏覽器處理部分

開啟進(jìn)程存放頁面

????進(jìn)程中包含

????????GUI渲染線程:用于獲取到HTML后進(jìn)行頁面的構(gòu)建與渲染

????????JS引擎線程:用于處理頁面中的JS代碼,每個(gè)瀏覽器進(jìn)程都有一個(gè)

????????事件處理線程:用于處理用戶觸發(fā)事件產(chǎn)生的回調(diào)函數(shù)

????????HTTP處理線程:用于處理HTTP請(qǐng)求

????????定時(shí)器觸發(fā)線程:用于處理頁面中生成的定時(shí)器溉愁,并在合適的時(shí)候?qū)⒒卣{(diào)交由任務(wù)隊(duì)列

:為保證數(shù)據(jù)與視圖的統(tǒng)一性处铛,GUI線程與JS線程存在互斥關(guān)系

構(gòu)建流程(GUI渲染線程)

1. 瀏覽器開始逐行解析HTML并開始創(chuàng)建DOM樹,DOM樹的創(chuàng)建是一個(gè)深度遍歷的過程拐揭,當(dāng)前節(jié)點(diǎn)的所有子節(jié)點(diǎn)構(gòu)建完成后才會(huì)構(gòu)建當(dāng)前節(jié)點(diǎn)的下一個(gè)兄弟節(jié)點(diǎn)撤蟆,此時(shí)的document.readyState="loading"

2. 如果遇到外聯(lián)JS文件且沒有設(shè)置異步執(zhí)行則立即下載并同步執(zhí)行,遇到CSS文件則立即下載并生成CSSOM

3. HTML解析完成后將完整DOM樹與CSSOM結(jié)合生成渲染樹RenderTree堂污,此時(shí)的document.readyState="interaction"

渲染流程

1. RenderTree是由與DOM節(jié)點(diǎn)一一對(duì)應(yīng)的渲染對(duì)象RenderObject組成的家肯,其包含了節(jié)點(diǎn)信息以及渲染上下文

2. 處于相同坐標(biāo)空間的渲染對(duì)象都會(huì)歸并到一個(gè)渲染層中,對(duì)于形成層疊上下文的渲染對(duì)象會(huì)自動(dòng)為其創(chuàng)建新的渲染層盟猖,渲染對(duì)象自動(dòng)從屬于父元素最近的渲染層息楔,常見生成渲染層的方式

????根元素document

????postion: relative/absolute/fixed/sticky

????opacity < 1

????存在CSS fliter屬性

????存在CSS transform屬性

3. 在渲染層的基礎(chǔ)上滿足特定條件后該渲染層會(huì)被提升為合成層(圖形層)寝贡,擁有單獨(dú)的圖形上下文(相當(dāng)于進(jìn)行單獨(dú)渲染),其余不是合成層的渲染層和第一個(gè)擁有圖形上下文的父層共用一個(gè)合成層值依,合成層通常為經(jīng)常變動(dòng)的效果

????3Dtransforms: translate3D/translateZ

????video/canvas/iframe

????CSS動(dòng)畫實(shí)現(xiàn)的opacity動(dòng)畫轉(zhuǎn)換

????position:fixed

????will-change

????對(duì)opacity/transform/fliter應(yīng)用了transition或animation

????使用了裁剪(Clip)或者反射(Reflection)

:將渲染層提升為合成層會(huì)帶有GPU加速效果圃泡,但是不能濫用

4. 得到各層后瀏覽器會(huì)計(jì)算出各層在頁面中的位置(回流)并調(diào)用其繪圖上下文進(jìn)行繪制渲染尝丐,最終呈現(xiàn)出整個(gè)頁面

隱式合成與層爆炸触创、層壓縮

若一個(gè)或多個(gè)非合成元素堆疊在合成層元素上,這些非合成層元素就會(huì)被提升成合成層假颇,從而出現(xiàn)隱式合成

層爆炸指產(chǎn)生的合成層太多導(dǎo)致大量占用GPU與內(nèi)存資源辆亏,進(jìn)而導(dǎo)致頁面卡頓或閃爍的現(xiàn)象风秤;其解決方法是提高合成層的z-index從而避免層疊來消除隱式合成

層壓縮是瀏覽器自身優(yōu)化機(jī)制,會(huì)將隱式合成產(chǎn)生的多余堆疊合成層壓縮為一個(gè)合成層扮叨,從而大大減少合成層的數(shù)量缤弦,降低GPU與內(nèi)存消耗

層合成規(guī)則的優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

????層合成產(chǎn)生的位圖會(huì)交由GPU進(jìn)行單獨(dú)處理,其處理速度比CPU快

????需要重繪是只需重繪其自身不影響其他層

????元素提升為合成層后transform或是opacity的改變部觸發(fā)重繪

缺點(diǎn)

????合成層過多導(dǎo)致GPU占用過高彻磁,容易出現(xiàn)頁面閃爍

????隱式合成產(chǎn)生過多的合成層碍沐,會(huì)占用過多的資源

優(yōu)化方式

????動(dòng)畫使用transform實(shí)現(xiàn)

????減少隱式合成,動(dòng)畫節(jié)點(diǎn)設(shè)置高z-index

????減小合成層的尺寸衷蜓,可以使用scale放大累提,節(jié)省性能

重繪與回流

重繪:尺寸與布局不發(fā)生改變,僅改變部分樣式

回流:頁面中元素的尺寸與布局發(fā)生變化(合成層除外)

重繪不一定回流磁浇,回流一定重繪

引起回流的操作

????頁面初始渲染

????改變字體或元素的尺寸

????改變?cè)氐目梢妰?nèi)容

????增刪DOM元素

????fixed的元素滾動(dòng)時(shí)會(huì)一直回流

????調(diào)整窗口大小

????訪問offsetWidth或是offsetHeight等破壞flush隊(duì)列的操作

flush隊(duì)列

為性能優(yōu)化考慮斋陪,瀏覽器自身會(huì)維護(hù)一個(gè)flush隊(duì)列,該隊(duì)列存儲(chǔ)著回流的內(nèi)容置吓,每經(jīng)過一段時(shí)間或該隊(duì)列達(dá)到一定長度后瀏覽器就會(huì)一次性將其全部回流完成无虚,實(shí)現(xiàn)優(yōu)化性能的目的。但當(dāng)開發(fā)者訪問offsetwidth衍锚,offsetheight骑科,width,height等屬性時(shí)构拳,瀏覽器為了給開發(fā)者返回該元素準(zhǔn)確的值會(huì)破壞flush隊(duì)列咆爽,致使瀏覽器自身優(yōu)化失效

頁面優(yōu)化性能方法

代碼層面

元素位置變換時(shí)盡量使用css3的transfrom來代替top left的操作,因?yàn)樽儞Q僅僅影響圖層的組合位置

????使用opacity來代替visibility置森,因?yàn)橥该鞫炔⒉挥|發(fā)重繪

????????:透明度改變時(shí)GPU在繪畫時(shí)只是簡(jiǎn)單的降低之前畫好紋理的alpha值來達(dá)到效果

????將多次class樣式改變操作合并為一次(預(yù)先定義改變后的class)

????使用display:none將dom元素離線后修改

????利用文檔碎片documentFragment收集短時(shí)間內(nèi)回流元素后一次回流添加到頁面(vue同款優(yōu)化)

????動(dòng)畫實(shí)現(xiàn)過程中使用transfrom:tranleteZ(0)使其提升為合成層通過GPU單獨(dú)渲染

????為動(dòng)畫元素新建圖層并提高其z-index以減少隱式合成

????減少對(duì)flush隊(duì)列的訪問斗埂,盡量不要破壞瀏覽器自身優(yōu)化

????單調(diào)色塊可使用合成層優(yōu)化中的scale縮放來優(yōu)化內(nèi)存占用

????CSS在上JS在下,觸發(fā)瀏覽器的first paint且減少同步代碼阻塞渲染的機(jī)率

資源層面

????除首屏展示外其余資源(圖片凫海、組件呛凶、視頻等)懶加載

????首屏中包含的視頻可以進(jìn)行分割傳輸

????單調(diào)圖片過大導(dǎo)致性能問題時(shí)可使用canvas或是svg繪圖

????對(duì)HTML、JS行贪、CSS資源進(jìn)行壓縮漾稀,服務(wù)器開啟Gzip

????對(duì)靜態(tài)資源使用緩存

????使用CDN縮短用戶與資源的距離? ? *? 升級(jí)到HTTP2使資源可以享受二進(jìn)制傳輸模闲、首部壓縮、多路復(fù)用

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末崭捍,一起剝皮案震驚了整個(gè)濱河市尸折,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌殷蛇,老刑警劉巖实夹,帶你破解...
    沈念sama閱讀 212,599評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異粒梦,居然都是意外死亡亮航,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門匀们,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缴淋,“玉大人,你說我怎么就攤上這事泄朴≈囟叮” “怎么了?”我有些...
    開封第一講書人閱讀 158,084評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵叼旋,是天一觀的道長。 經(jīng)常有香客問我沦辙,道長夫植,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,708評(píng)論 1 284
  • 正文 為了忘掉前任油讯,我火速辦了婚禮详民,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘陌兑。我一直安慰自己沈跨,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,813評(píng)論 6 386
  • 文/花漫 我一把揭開白布兔综。 她就那樣靜靜地躺著饿凛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪软驰。 梳的紋絲不亂的頭發(fā)上涧窒,一...
    開封第一講書人閱讀 50,021評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音锭亏,去河邊找鬼纠吴。 笑死,一個(gè)胖子當(dāng)著我的面吹牛慧瘤,可吹牛的內(nèi)容都是我干的戴已。 我是一名探鬼主播固该,決...
    沈念sama閱讀 39,120評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼糖儡!你這毒婦竟也來了伐坏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,866評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤休玩,失蹤者是張志新(化名)和其女友劉穎著淆,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拴疤,經(jīng)...
    沈念sama閱讀 44,308評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡永部,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,633評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了呐矾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片苔埋。...
    茶點(diǎn)故事閱讀 38,768評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蜒犯,靈堂內(nèi)的尸體忽然破棺而出组橄,到底是詐尸還是另有隱情,我是刑警寧澤罚随,帶...
    沈念sama閱讀 34,461評(píng)論 4 333
  • 正文 年R本政府宣布玉工,位于F島的核電站,受9級(jí)特大地震影響淘菩,放射性物質(zhì)發(fā)生泄漏遵班。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,094評(píng)論 3 317
  • 文/蒙蒙 一潮改、第九天 我趴在偏房一處隱蔽的房頂上張望狭郑。 院中可真熱鬧,春花似錦汇在、人聲如沸翰萨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽亩鬼。三九已至,卻和暖如春阿蝶,著一層夾襖步出監(jiān)牢的瞬間辛孵,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評(píng)論 1 267
  • 我被黑心中介騙來泰國打工赡磅, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留魄缚,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,571評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像冶匹,于是被迫代替她去往敵國和親习劫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,666評(píng)論 2 350

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