div置于页面底部_浏览器渲染页面的原理及流程
瀏覽器渲染頁(yè)面的原理及流程
瀏覽器將域名通過(guò)網(wǎng)絡(luò)通信從服務(wù)器拿到html文件后,如何渲染頁(yè)面呢?
1.根據(jù)html文件構(gòu)建DOM樹(shù)和CSSOM樹(shù)。構(gòu)建DOM樹(shù)期間,如果遇到JS,阻塞DOM樹(shù)及CSSOM樹(shù)的構(gòu)建,優(yōu)先加載JS文件,加載完畢,再繼續(xù)構(gòu)建DOM樹(shù)及CSSOM樹(shù)。
2.構(gòu)建渲染樹(shù)(Render Tree)。
3.頁(yè)面的重繪(repaint)與重排(reflow,也有稱(chēng)回流)。頁(yè)面渲染完成后,若JS操作了DOM節(jié)點(diǎn),根據(jù)JS對(duì)DOM操作動(dòng)作的大小,瀏覽器對(duì)頁(yè)面進(jìn)行重繪或是重排。一、構(gòu)建DOM樹(shù)及CSSOM樹(shù)1.1構(gòu)建DOM樹(shù)
HTML 文檔中的所有內(nèi)容皆是節(jié)點(diǎn),各節(jié)點(diǎn)之間擁有層級(jí)關(guān)系,如父子關(guān)系、兄弟關(guān)系等,彼此相連,構(gòu)成DOM樹(shù)。最常見(jiàn)的幾種節(jié)點(diǎn)有:文檔節(jié)點(diǎn)、元素節(jié)點(diǎn)、文本節(jié)點(diǎn)、屬性節(jié)點(diǎn)、注釋節(jié)點(diǎn)。
DOM節(jié)點(diǎn)樹(shù)中節(jié)點(diǎn)與HTML文檔中內(nèi)容一一對(duì)應(yīng),DOM樹(shù)構(gòu)建過(guò)程:讀取html文檔,將字節(jié)轉(zhuǎn)換成字符,確定tokens(標(biāo)簽),再將tokens轉(zhuǎn)換成節(jié)點(diǎn),以節(jié)點(diǎn)構(gòu)建 DOM 樹(shù)。如下圖所示:
1.2構(gòu)建CSSOM樹(shù)
CSS文檔中,所有元素皆是節(jié)點(diǎn),與HTML文件中的標(biāo)簽節(jié)點(diǎn)一一對(duì)應(yīng)。CSS中各節(jié)點(diǎn)之間同樣擁有層級(jí)關(guān)系,如父子關(guān)系、兄弟關(guān)系等,彼此相連,構(gòu)成CSSOM樹(shù)。
在構(gòu)建DOM樹(shù)的過(guò)程中,在 HTML 文檔的 head 標(biāo)簽中遇到 link 標(biāo)簽,該標(biāo)簽引用了一個(gè)外部CSS樣式表。由于預(yù)見(jiàn)到需要利用該CSS資源來(lái)渲染頁(yè)面,瀏覽器會(huì)立即發(fā)出對(duì)該CSS資源的請(qǐng)求,并進(jìn)行CSSDOM樹(shù)的構(gòu)建。
CSSOM樹(shù)構(gòu)建過(guò)程與DOM樹(shù)構(gòu)建流程一致:讀取CSS文檔,將字節(jié)轉(zhuǎn)換成字符,確定tokens(標(biāo)簽),再將tokens轉(zhuǎn)換成節(jié)點(diǎn),以節(jié)點(diǎn)構(gòu)建 CSSOM 樹(shù)。如下圖所示:
.CSS文件,又名層疊樣式表。當(dāng)CSSOM樹(shù)生成節(jié)點(diǎn)時(shí),每一個(gè)節(jié)點(diǎn)首先會(huì)繼承其父節(jié)點(diǎn)的所有樣式,層疊覆蓋,然后再以"向下級(jí)聯(lián)"的規(guī)則,為該節(jié)點(diǎn)應(yīng)用更具體的樣式,遞歸生成CSSOM樹(shù)。譬如,上右圖中第二層的p節(jié)點(diǎn),有父節(jié)點(diǎn)body,因此該p將繼承body節(jié)點(diǎn)的樣式:"font-size: 16px;"。然后再應(yīng)用該p節(jié)點(diǎn)自身的樣式:"font-weight: bold;"。所以最終該p節(jié)點(diǎn)的樣式為:"font-size: 16px;font-weight: bold;"。1.3加載JS
若在構(gòu)建DOM樹(shù)的過(guò)程中,當(dāng) HTML 解析器遇到一個(gè) script 標(biāo)記時(shí),即遇到了js,將立即阻塞DOM樹(shù)的構(gòu)建,將控制權(quán)移交給 JavaScript 引擎,等到 JavaScript 引擎運(yùn)行完畢,瀏覽器才會(huì)從中斷的地方恢復(fù)DOM樹(shù)的構(gòu)建。
其根本原因在于,JS會(huì)對(duì)DOM節(jié)點(diǎn)進(jìn)行操作,瀏覽器無(wú)法預(yù)測(cè)未來(lái)的DOM節(jié)點(diǎn)的具體內(nèi)容,為了防止無(wú)效操作,節(jié)省資源,只能阻塞DOM樹(shù)的構(gòu)建。譬如,若不阻塞DOM樹(shù)的構(gòu)建,若JS刪除了某個(gè)DOM節(jié)點(diǎn)A,那么瀏覽器為構(gòu)建此節(jié)點(diǎn)A花費(fèi)的資源就是無(wú)效的。
若在HTML頭部加載JS文件,由于JS阻塞,會(huì)推遲頁(yè)面的首繪。為了加快頁(yè)面渲染,一般將JS文件放到HTML底部進(jìn)行加載,或是對(duì)JS文件執(zhí)行async或defer加載。二.構(gòu)建渲染樹(shù)
渲染樹(shù)(Render Tree)由DOM樹(shù)、CSSOM樹(shù)合并而成,但并不是必須等DOM樹(shù)及CSSOM樹(shù)加載完成后才開(kāi)始合并構(gòu)建渲染樹(shù)。三者的構(gòu)建并無(wú)先后條件,亦非完全獨(dú)立,而是會(huì)有交叉,并行構(gòu)建。因此會(huì)形成一邊加載,一邊解析,一邊渲染的工作現(xiàn)象。
構(gòu)建渲染樹(shù),根據(jù)渲染樹(shù)計(jì)算每個(gè)可見(jiàn)元素的布局,并輸出到繪制流程,將像素渲染到屏幕上。三.頁(yè)面的重繪(repaint)與重排(reflow) 3.1重繪(repaint):屏幕的一部分要重繪。渲染樹(shù)節(jié)點(diǎn)發(fā)生改變,但不影響該節(jié)點(diǎn)在頁(yè)面當(dāng)中的空間位置及大小。譬如某個(gè)div標(biāo)簽節(jié)點(diǎn)的背景顏色、字體顏色等等發(fā)生改變,但是該div標(biāo)簽節(jié)點(diǎn)的寬、高、內(nèi)外邊距并不發(fā)生變化,此時(shí)觸發(fā)瀏覽器重繪(repaint)。 3.2重排(reflow):也有稱(chēng)回流,當(dāng)渲染樹(shù)節(jié)點(diǎn)發(fā)生改變,影響了節(jié)點(diǎn)的幾何屬性(如寬、高、內(nèi)邊距、外邊距、或是float、position、display:none;等等),導(dǎo)致節(jié)點(diǎn)位置發(fā)生變化,此時(shí)觸發(fā)瀏覽器重排(reflow),需要重新生成渲染樹(shù)。譬如JS為某個(gè)p標(biāo)簽節(jié)點(diǎn)添加新的樣式:"display:none;"。導(dǎo)致該p標(biāo)簽被隱藏起來(lái),該p標(biāo)簽之后的所有節(jié)點(diǎn)位置都會(huì)發(fā)生改變。此時(shí)瀏覽器需要重新生成渲染樹(shù),重新布局,即重排(reflow)。
注意:重排必將引起重繪,而重繪不一定會(huì)引起重排。
何時(shí)回引起重排?
當(dāng)頁(yè)面布局和幾何屬性改變時(shí)就需要重排。下述情況會(huì)發(fā)生瀏覽器重排:
1、添加或者刪除可見(jiàn)的DOM元素;
2、元素位置改變——display、float、position、overflow等等;
3、元素尺寸改變——邊距、填充、邊框、寬度和高度
4、內(nèi)容改變——比如文本改變或者圖片大小改變而引起的計(jì)算值寬度和高度改變;
5、頁(yè)面渲染初始化;
6、瀏覽器窗口尺寸改變——resize事件發(fā)生時(shí);3.3如何減少和避免重排Reflow 的成本比 Repaint 的成本高得多的多。一個(gè)節(jié)點(diǎn)的 Reflow 很有可能導(dǎo)致子節(jié)點(diǎn),甚至父節(jié)點(diǎn)以及兄弟節(jié)點(diǎn)的 Reflow 。在一些高性能的電腦上也許還沒(méi)什么,但是如果 Reflow 發(fā)生在手機(jī)上,那么這個(gè)過(guò)程是延慢加載和耗電的。----瀏覽器的渲染原理簡(jiǎn)介
1. 直接改變className,如果動(dòng)態(tài)改變樣式,則使用cssText(考慮沒(méi)有優(yōu)化的瀏覽器);
2. 讓要操作的元素進(jìn)行”離線處理”,處理完后一起更新;
a) 使用DocumentFragment進(jìn)行緩存操作,引發(fā)一次回流和重繪;
b) 使用display:none技術(shù),只引發(fā)兩次回流和重繪;
c) 使用cloneNode(true or false) 和 replaceChild 技術(shù),引發(fā)一次回流和重繪;
3.不要經(jīng)常訪問(wèn)會(huì)引起瀏覽器flush隊(duì)列的屬性,如果你確實(shí)要訪問(wèn),利用緩存;
4. 讓元素脫離動(dòng)畫(huà)流,減少回流的Render Tree的規(guī)模;
原文:瀏覽器渲染頁(yè)面的原理及流程 - 陳由梅 - 博客園
總結(jié)
以上是生活随笔為你收集整理的div置于页面底部_浏览器渲染页面的原理及流程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 埃夫特机器人回零偏差太大_新松、华中数控
- 下一篇: android用qq浏览器打开微信网页版