[前端日記]16.x 瀏覽器渲染相關知識

碎碎念


正式開始學習Javascript慎陵,從T16.x開始慢慢更新Javascript中的學習筆記與感悟

本篇文章包含以下幾個內(nèi)容:

  1. 白屏與FOUC
  2. 瀏覽器渲染機制
  3. reflow&repaint
  4. 同步&異步疲扎、async&defer

前置知識


在探討白屏問題和FOUC無樣式內(nèi)容閃爍問題出現(xiàn)的原因之前,我們要知道的一個原則是瀏覽器在對于圖片和CSS, 在加載時會并發(fā)加載(如一個域名下同時加載兩個文件). 但在加載 JavaScript 時,會禁用并發(fā),并且阻止其他內(nèi)容的下載爵赵。

白屏與FOUC并不是bug等恐,它僅僅是不同瀏覽器渲染機制的差異洲劣,及不同的代碼順序寫法备蚓,下面來解析下兩種現(xiàn)象的成因。

白屏


現(xiàn)象:瀏覽器頁面在加載時囱稽,出現(xiàn)段時間的白屏星著、無內(nèi)容現(xiàn)象;


原因:在chrome瀏覽器的加載和渲染機制中粗悯,需要等待所有CSS都被加載虚循、解析完成后,再進行頁面渲染样傍。如果CSS樣式放在底部横缔,瀏覽器在渲染完dom后,發(fā)現(xiàn)CSS還沒有加載衫哥、解析茎刚,因此只好再去加載CSS。這個加載等待的時間就出現(xiàn)了長時間的白屏撤逢。

FOUC


現(xiàn)象:無樣式內(nèi)容閃爍膛锭,表現(xiàn)為先展示了沒有樣式(瀏覽器默認樣式)的網(wǎng)頁內(nèi)容,再突然展示加載了樣式的網(wǎng)頁內(nèi)容蚊荣,中間的用戶體驗形象的稱之為『閃爍』初狰。

當我們輸入網(wǎng)址后,瀏覽器會向服務端發(fā)起請求互例,然后服務端將頁面發(fā)送給瀏覽器奢入,瀏覽器邊下載頁面邊進行解析,過程如下:

  1. 邊下載HTML文檔邊構建DOM樹
  2. 瀏覽器會先以瀏覽器默認樣式來解析CSSOM Tree
  3. DOM Tree + CSSOM Tree構建出了渲染樹媳叨,然后頁面內(nèi)容渲染出來
  4. 當解析到內(nèi)聯(lián)腥光、內(nèi)部樣式時,馬上刷新CSSOM Tree糊秆,引起Render Tree的變化
  5. 當解析到外部樣式時武福,會先加載,然后解析和刷新CSSOM Tree

上述五個步驟由于樣式文件在下載過程中的延時受網(wǎng)絡環(huán)境與電腦性能的影響痘番,導致我們看到兩種截然不同的樣式的閃爍變化

第二種出現(xiàn)原因是捉片,CSS樣式表被放置在頁面底部,瀏覽器會先加載沒有樣式的HTML頁面夫偶,等CSS加載完界睁,再渲染一次觉增,這就是FOUC兵拢。

CSS、JS文檔推薦的引入順序


  1. CSS放在<head>中逾礁,保證優(yōu)先加載樣式
    原因:在body渲染前说铃,先構建一個相對完整的CSSOM Tree

  2. JS放在最接近body閉合標簽處访惜,防止JS的加載阻塞后面標簽與樣式的加載

瀏覽器渲染機制


webkit為內(nèi)核的瀏覽器工作流程:

下面我們具體看下當瀏覽器渲染一個頁面時,發(fā)生了什么腻扇?

image
  1. 瀏覽器從服務器獲取到HTML文檔债热,并構建了DOM(文檔對象模型)

  2. 樣式被載入及解析,構建為CSSOM(層疊樣式表模型)

  3. 在完成了DOM和CSSOM的基礎上幼苛,渲染樹將會被創(chuàng)建窒篱,代表了一系列將被渲染的對象(在webkit內(nèi)核的瀏覽器中被稱之為renderer或者render object,在Gecko中舶沿,其被稱之為frame)墙杯。渲染樹映射了除了不可見的元素,例如<head>display:none之外的所有DOM結構括荡,每一個文本字符串都劃分在不同的渲染對象中高镐,每一個渲染對象都包含了它相應的DOM對象以及計算后的樣式。換句話說畸冲,渲染樹是DOM的直觀表示嫉髓。

  4. 渲染樹的每一個元素包含的內(nèi)容都是計算過的,我們稱之為『布局』邑闲。瀏覽器使用一種流式處理的方法算行,只需要一次操作就可以對所有的元素進行布局(表格則需要多次)。

  5. 最后苫耸,布局完成纱意,渲染樹將轉化成屏幕上的實際內(nèi)容,我們稱之為『painting』鲸阔。

兩個重要的概念


Repaint/重繪

當頁面元素樣式的修改不影響其在文檔流中的位置(幾何位置偷霉,元素坐標),僅影響元素的外觀時(background-color褐筛,visibility)类少,瀏覽器只會將新樣式賦予元素,并進行重繪渔扎。

觸發(fā)條件:

不涉及DOM元素或排版上的變化硫狞,如元素的colortext-align晃痴,另外偽類引起的顏色變化也不會造成reflow残吩,僅僅觸發(fā)repaint。

Reflow/重排

當樣式改變影響到文檔內(nèi)容或結構時倘核,瀏覽器就觸發(fā)Reflow操作(可以理解為重新布局)泣侮,重新計算頁面元素位置或幾何結構。

觸發(fā)條件:

  • DOM操作紧唱,即對元素的增刪改活尊,調(diào)整順序等
  • 內(nèi)容變化隶校,包括文本的改變
  • CSS屬性的更改,或者是重新計算
  • 增刪樣式表內(nèi)容
  • 瀏覽器窗口變化
  • 偽類樣式(:hover等)造成的元素表現(xiàn)得改動

對比

從性能角度考慮蛹锰,Reflow的成本要比Repaint高很多深胳。Dom Tree里面每個節(jié)點都有Reflow方法,一個節(jié)點的reflow會導致子節(jié)點铜犬,父節(jié)點或者兄弟節(jié)點reflow舞终,進而導致性能較低的電腦,或是移動端設備體驗很差癣猾。

因此权埠,在頁面制作過程中,應該盡可能的考慮瀏覽器性能問題煎谍,減少Reflow能夠減少瀏覽器引擎的重新渲染攘蔽,提高頁面加載效率。

哪些樣式是高消耗的呐粘?

具體哪些屬性是高消耗的呢满俗?就是繪制前需要瀏覽器進行大量運算的樣式屬性。

  • box-shadows
  • border-radius
  • transparency(圖像透明度)
  • transforms
  • CSS filters(性能殺手)

async和defer


前置知識:同步與異步

日常理解中的同步與異步的語義與計算機中的同步作岖、異步是大相徑庭的唆垃。前者在日常對話中往往會說“這幾件工作我們同步進行”,異步就是將事情分開進行痘儡。

在計算機語言中辕万,同步可以理解為,將事情一件一件沉删,按順序往下進行渐尿,而異步理解為幾件事情同時進行,語義與現(xiàn)實生活中的理解正好相反矾瑰。

defer與async屬性

  • <script src="script.js"></script>

如上砖茸,在無defer與async情況下,瀏覽器會立即加載并執(zhí)行該腳本殴穴。立即指的是凉夯,在渲染該文件 后面的其它元素之前,也就是會阻塞后面HTML元素的解析采幌。只有等腳本解析與執(zhí)行完后劲够,瀏覽器才會繼續(xù)解析其它的元素。

defer與async是腳本異步加載的兩種方式休傍,只對外部腳本有效征绎。我們來具體看看

  • <script src="script.js" defer></script>

加入了defer,實現(xiàn)了腳本文件與HTML文檔的異步加載尊残,也就是腳本文件的加載與加載后續(xù)文檔元素是并行的炒瘸。這里要注意:腳本文件的執(zhí)行會相應的defer到所有元素解析完成后。

《Javascript高級程序設計》中2.1.2提到寝衫,應用了defer屬性的腳本會先于DOMContentLoaded時間執(zhí)行顷扩。但是,在實際情況中延遲腳本不一定按照順序執(zhí)行慰毅,也不一定在DOMContentLoaded事件觸發(fā)前執(zhí)行隘截。因此,使用defer最大的弊端是執(zhí)行順序是未知的汹胃,同樣也發(fā)生在async上婶芭。

  • <script src="script.js" aysnc></script>

有 async,加載和渲染后續(xù)文檔元素的過程將和 script.js 的加載與執(zhí)行并行進行(異步)着饥。

總結:

  1. defer和async在腳本加載方式上都是異步執(zhí)行的犀农;
  2. 差別在于腳本加載完成后,執(zhí)行腳本的時機宰掉;
  3. 執(zhí)行順序上看呵哨,defer是按照加載順序執(zhí)行腳本的,而async是亂序執(zhí)行的轨奄,因為只有某個腳本文件加載完成他就立即執(zhí)行孟害,因此順序無法保證;
  4. 所以挪拟,從使用場景上看挨务,defer是最接近我們用途的,因為他完全不考慮各個腳本之間的依賴玉组,但它可以用在不受依賴谎柄,獨立的腳本上;
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末惯雳,一起剝皮案震驚了整個濱河市谷誓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌吨凑,老刑警劉巖捍歪,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異鸵钝,居然都是意外死亡糙臼,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進店門恩商,熙熙樓的掌柜王于貴愁眉苦臉地迎上來变逃,“玉大人,你說我怎么就攤上這事怠堪±柯遥” “怎么了名眉?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長凰棉。 經(jīng)常有香客問我损拢,道長,這世上最難降的妖魔是什么撒犀? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任福压,我火速辦了婚禮,結果婚禮上或舞,老公的妹妹穿的比我還像新娘荆姆。我一直安慰自己,他們只是感情好映凳,可當我...
    茶點故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布胆筒。 她就那樣靜靜地躺著,像睡著了一般诈豌。 火紅的嫁衣襯著肌膚如雪腐泻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天队询,我揣著相機與錄音派桩,去河邊找鬼。 笑死蚌斩,一個胖子當著我的面吹牛铆惑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播送膳,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼员魏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了叠聋?” 一聲冷哼從身側響起撕阎,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎碌补,沒想到半個月后虏束,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡厦章,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年镇匀,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片袜啃。...
    茶點故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡汗侵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情晰韵,我是刑警寧澤发乔,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站雪猪,受9級特大地震影響栏尚,放射性物質發(fā)生泄漏。R本人自食惡果不足惜浪蹂,卻給世界環(huán)境...
    茶點故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一抵栈、第九天 我趴在偏房一處隱蔽的房頂上張望告材。 院中可真熱鬧坤次,春花似錦、人聲如沸斥赋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽疤剑。三九已至滑绒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間隘膘,已是汗流浹背疑故。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留弯菊,地道東北人纵势。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像管钳,于是被迫代替她去往敵國和親钦铁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,509評論 2 348

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

  • 前端必讀:瀏覽器內(nèi)部工作原理[https://kb.cnblogs.com/page/129756/] 作者: T...
    我是強強閱讀 1,138評論 0 2
  • 1. CSS和JS在網(wǎng)頁中的放置順序是怎樣的才漆? css放在head標簽內(nèi)牛曹,防止渲染時出現(xiàn)白屏 js放在最后body...
    billa_8f6b閱讀 568評論 0 0
  • 1. 介紹 瀏覽器可能是最廣泛使用的軟件。本書將介紹瀏覽器的工作原理醇滥。我們將看到黎比,當你在地址欄中輸入google....
    康斌閱讀 2,013評論 7 18
  • 轉載說明 一、介紹 瀏覽器可以被認為是使用最廣泛的軟件鸳玩,本文將介紹瀏覽器的工作原理焰手,我們將看到,從你在地址欄輸入g...
    17碎那年閱讀 2,442評論 0 22
  • 簡介瀏覽器可以被認為是使用最廣泛的軟件,本文將介紹瀏覽器的工 作原理,我們將看到躲履,從你在地址欄輸入google.c...
    聽風閣閱讀 3,276評論 0 7