久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

瀏覽器~加載,解析,,渲染

 李副營長 2015-03-23

昨天為了 了解瀏覽器是怎么處理(.html,、.css、.js)這些文件,,我看了網(wǎng)上的好多資料,,這好多資料中,有很多是通過轉(zhuǎn)載,、或是轉(zhuǎn)載后加之自己的理解,,但是因?yàn)樽约簩?duì)專業(yè)的詞匯理解不好,還有一些作者將不同瀏覽器的處理過程混著說,,總之,,看完了,還是有很多疑慮的地方,。我先根據(jù)昨天了解到的內(nèi)容總結(jié)一下,,日后隨著學(xué)的深了,再回過來補(bǔ)充,。2014.11.6


why

為什么要了解瀏覽器加載,、解析、渲染這個(gè)過程,?
  • 了解瀏覽器如何進(jìn)行加載,,我們可以在引用外部樣式文件,外部js時(shí),,將他們放到合適的位置,,使瀏覽器以最快的速度將文件加載完畢。
  • 了解瀏覽器如何進(jìn)行解析,,我們可以在構(gòu)建DOM結(jié)構(gòu),,組織css選擇器時(shí),,選擇最優(yōu)的寫法,提高瀏覽器的解析速率,。
  • 了解瀏覽器如何進(jìn)行渲染,,明白渲染的過程,我們?cè)谠O(shè)置元素屬性,,編寫js文件時(shí),,可以減少”重繪“”重新布局“的消耗。
    這三個(gè)過程在實(shí)際進(jìn)行的時(shí)候又不是完全獨(dú)立,,而是會(huì)有交叉,。會(huì)造成一邊加載,一邊解析,,一邊渲染的工作現(xiàn)象,。

how

瀏覽器是如何進(jìn)行加載、解析,、渲染的呢,?

  1. 用戶訪問網(wǎng)頁,DNS服務(wù)器(域名解析系統(tǒng))會(huì)根據(jù)用戶提供的域名查找對(duì)應(yīng)的IP地址,,找到后,,系統(tǒng)會(huì)向?qū)?yīng)IP地址的網(wǎng)絡(luò)服務(wù)器發(fā)送一個(gè)http請(qǐng)求。
  2. 網(wǎng)絡(luò)服務(wù)器解析請(qǐng)求,,并發(fā)送請(qǐng)求給數(shù)據(jù)庫服務(wù)器,。
  3. 數(shù)據(jù)庫服務(wù)器將請(qǐng)求的資源返回給網(wǎng)絡(luò)服務(wù)器,網(wǎng)絡(luò)服務(wù)器解析數(shù)據(jù),,并生成html文件,,放入http response中,返回給瀏覽器,。
  4. 瀏覽器解析 http response,。
    1~4步驟需要了解HTTP協(xié)議。
    訪問服務(wù)器端可能遭遇的問題:如果網(wǎng)絡(luò)服務(wù)器無法獲取數(shù)據(jù)庫服務(wù)器返回的資源文件(http response 404),,或者由于并發(fā)原因暫時(shí)無法處理用戶的http請(qǐng)求(http response 500)
  5. 瀏覽器解析 http response后,,需要下載html文件,以及html文件內(nèi)包含的外部引用文件,,及文件內(nèi)涉及的圖片或者多媒體文件,。
以下的內(nèi)容相對(duì)比較復(fù)雜 O(∩_∩)O~

關(guān)于加載順序:當(dāng)瀏覽器獲得一個(gè)html文件時(shí),會(huì)”自上而下“加載,,并在加載過程中進(jìn)行解析渲染,。

加載

即為獲取資源文件的過程,不同瀏覽器,,以及他們的不同版本在實(shí)現(xiàn)這一過程時(shí),,會(huì)有不同的實(shí)現(xiàn)效果(資源間互相阻塞),,。(需要學(xué)習(xí)使用timeline來做測試,,我還不太會(huì)用,,學(xué)會(huì)了在上文。)

<!DOCTYPE html>
<html>
     <head>
           <meta charset="utf-8">
           <link rel="stylesheet"  href="test.css"  type="text/css" />
           <script src="test.js" type="text/javascript"></script>
     </head>
     <body>    
           <p>阻塞</p>
           <img src="test.jpg" /> 
     </body>
</html>

加載過程中遇到外部css文件,,瀏覽器另外發(fā)出一個(gè)請(qǐng)求,,來獲取css文件。
遇到圖片資源,,瀏覽器也會(huì)另外發(fā)出一個(gè)請(qǐng)求,,來獲取圖片資源。這是異步請(qǐng)求,,并不會(huì)影響html文檔進(jìn)行加載,但是當(dāng)文檔加載過程中遇到j(luò)s文件,,html文檔會(huì)掛起渲染(加載解析渲染同步)的線程,,不僅要等待文檔中js文件加載完畢,還要等待解析執(zhí)行完畢,,才可以恢復(fù)html文檔的渲染線程,。

原因:JS有可能會(huì)修改DOM,最為經(jīng)典的document.write,,這意味著,,在JS執(zhí)行完成前,后續(xù)所有資源的下載可能是沒有必要的,,這是js阻塞后續(xù)資源下載的根本原因,。
辦法:可以將外部引用的js文件放在</body>前。

雖然css文件的加載不影響js文件的加載,,但是卻影響js文件的執(zhí)行,,即使js文件內(nèi)只有一行代碼,也會(huì)造成阻塞,。

原因:可能會(huì)有 var width = $('#id').width(),,這意味著,js代碼執(zhí)行前,,瀏覽器必須保證css文件已下載和解析完成,。這也是css阻塞后續(xù)js的根本原因。
辦法:當(dāng)js文件不需要依賴css文件時(shí),,可以將js文件放在頭部css的前面,。

當(dāng)然除了,<link href="" />這種形式,,內(nèi)部<style></style>這種樣式定義,,在考慮阻塞時(shí)也要考慮,。
以上對(duì)于代碼布局對(duì)文檔加載的影響是比較基礎(chǔ)的,隨著瀏覽器的升級(jí),,以及js技術(shù)的應(yīng)用,,html的發(fā)展,web性能也會(huì)逐漸提高,。
列舉一下,,以后可以逐一擴(kuò)充一下:

  • 不要在外部調(diào)用的js文件中調(diào)用運(yùn)行時(shí)間較長的函數(shù),如果一定要用,,可以使用setTimeout函數(shù),。

    為什么呢?

    1. 瀏覽器GUI渲染線程
    2. javascript引擎線程
    3. 瀏覽器定時(shí)器觸發(fā)線程(setTimeout)
    4. 瀏覽器事件觸發(fā)線程
    5. 瀏覽器http異步請(qǐng)求線程(.jpg <link />這類請(qǐng)求)
      原因:瀏覽器有以上五個(gè)常駐線程
      發(fā)現(xiàn)第3個(gè)線程,,我們便知道,,如果在js內(nèi)使用setTimeout()那么會(huì)調(diào)用另一個(gè)線程。
      注意:這里也涉及到 阻塞 的現(xiàn)象,,當(dāng)js引擎線程(第二個(gè))進(jìn)行時(shí),,會(huì)掛起其他一切線程,這個(gè)時(shí)候3,、4,、5這三類線線程也會(huì)產(chǎn)生不同的異步事件(這句話不懂啊),,由于 javascript引擎線程為單線程,,所以代碼都是先壓到隊(duì)列,采用先進(jìn)先出的方式運(yùn)行,,事件處理函數(shù),,timer函數(shù)也會(huì)壓在隊(duì)列中,不斷的從隊(duì)頭取出事件,,這就叫:javascript-event-loop,。
  • 現(xiàn)代瀏覽器存在 prefetch 優(yōu)化,瀏覽器會(huì)另外開啟線程,,提前下載js,、css文件,需要注意的是,,預(yù)加載js并不會(huì)改變dom結(jié)構(gòu),,他將這個(gè)工作留給主加載。

  • 預(yù)加載網(wǎng)頁,,利用空余時(shí)間來提前加載該網(wǎng)頁的后續(xù)網(wǎng)頁,。
    <link rel="prefetch" href="http://">
  • 為js腳本添加defer屬性,使得瀏覽器不等js腳本加載執(zhí)行完,就加載后面的圖片,。既然圖片資源都已經(jīng)加載出來了,,就不要在js內(nèi)寫document.write啦。
    <script defer="true" src="JavaScript.js" type="text/javascript"/>

解析

解析的概念有些多,,需要另寫一篇文章,。于是我就先簡單的寫一下。

  • html文檔解析生成解析樹即dom樹,,是由dom元素及屬性節(jié)點(diǎn)組成,,樹的根是document對(duì)象。

    DOM:文檔對(duì)象模型的縮寫,,是html文檔的對(duì)象表示,,作為html的外部接口供js調(diào)用。

    document.getElementById('test').style.display="none";//通過dom接口將id為test的display值設(shè)為none,。

  • css解析將css文件解析為樣式表對(duì)象,。該對(duì)象包含css規(guī)則,該規(guī)則包含選擇器和聲明對(duì)象,。

css解析.png
css解析.png
  • js解析因?yàn)槲募诩虞d的同時(shí)也進(jìn)行解析,,詳看js加載部分。

渲染

即為構(gòu)建渲染樹的過程,,他是原來DOM樹的可視化表示,構(gòu)建這棵樹是為了以正確的順序繪制文檔內(nèi)容,。
渲染樹和DOM樹的關(guān)系,,不可見的dom元素(<head>…</head> display=none)不會(huì)被插入渲染樹中。還有像一些節(jié)點(diǎn)的位置為絕對(duì)或浮動(dòng)定位(需要css知識(shí)理解),,這些節(jié)點(diǎn)會(huì)在文本流之外,,因此會(huì)在兩棵樹上的不同位置,渲染樹標(biāo)識(shí)出真實(shí)的位置,,并用一個(gè)占位結(jié)構(gòu)標(biāo)識(shí)出他們?cè)瓉淼奈恢谩?/p>

渲染最大的一個(gè)困難就是為每一個(gè)dom節(jié)點(diǎn)計(jì)算符合他的最終樣式,。
  • 為每一個(gè)元素查找到匹配的樣式規(guī)則,需要遍歷整個(gè)規(guī)則表,。關(guān)于遍歷規(guī)則表的方法,,我之前理解錯(cuò)啦。
     #test p{ color:#999999}
    正解:遍歷是自右向左,,也就是先查詢到p元素,,再找到上一級(jí)id為test的元素。之前的理解正好相反,。這樣發(fā)現(xiàn),,遍歷的效率好低。
    為什么:可以去看之前css解析時(shí),,生成的樣式對(duì)象,,遍歷的順序,,自然是從樹的低端向上遍歷。

計(jì)算樣式的一些困難:

  1. 樣式數(shù)據(jù)是非常大的結(jié)構(gòu),,保存這樣是的數(shù)據(jù)是很耗內(nèi)存的,。
  2. 選擇器迭代太深,造成太多的無用遍歷,。
  3. 樣式規(guī)則涉及非常復(fù)雜的級(jí)聯(lián),,定義了規(guī)則的層次(理解:<head>里引用的外部樣式表,會(huì)被局部樣式表中同一屬性的設(shè)置取代,。還有例如body內(nèi)對(duì)font的設(shè)置本來會(huì)應(yīng)用于孩子元素,,但是如果body的孩子元素定義font屬性,則會(huì)被后者取代),。

解決辦法:共享樣式數(shù)據(jù),。(元素可以共享樣式數(shù)據(jù)的條件就是他們的狀態(tài)是”一致“的。)

webkit渲染

計(jì)算樣式并生成渲染對(duì)象的過程為attachment,,每個(gè)dom節(jié)點(diǎn)有一個(gè)attach方法,,attachment的過程是同步的,調(diào)用新節(jié)點(diǎn)的attach方法插入到dom樹中,。
parser:解析,, Render Tree:渲染樹 Layout:安排布局

webkit主流程.png
webkit主流程.png

渲染過程中,webkit使用一個(gè)標(biāo)志位標(biāo)志所有頂層樣式都已經(jīng)被加載完畢,,如果dom元素進(jìn)行attach時(shí),,css元素并沒有被加載完畢,則放置占位符,,并在文檔中標(biāo)記,,當(dāng)樣式表加載完畢,則重新進(jìn)行計(jì)算,。
說明,,文檔的渲染還是要等待頂層css加載完畢。接下來的gecko應(yīng)該也是需要等待頂層css加載完畢,,否則“css規(guī)則樹”(見下文)無法建立啊

Gecko渲染

webkit渲染是一個(gè)元素與樣式規(guī)則匹配的過程,,Gecko則需要構(gòu)建樣式計(jì)算規(guī)則書,然后與dom樹對(duì)應(yīng)生成樣式上下文數(shù)(及渲染樹),。例子:

<html>
     <body>
          <div class=”err” id=”div1″>
               <p>
                    this is      a <span class=”big”> big error    </span>
                    this is also a <span class=”big”> very big error</span>
               </p>
          </div>
          <div class=”err” id=”div2″>
                another error
          </div>
     </body>
</html>

//規(guī)則
 1. div {margin:5px;color:black}
 2. .err {color:red}
 3. .big {margin-top:3px}
 4. div span {margin-bottom:4px}
 5. #div1 {color:blue}
 6. #div2 {color:green}
樣式規(guī)則樹.png
樣式規(guī)則樹.png

解釋一下:A:任意一個(gè)父級(jí)元素,。B、E:代表元素選擇器,,B指div,,E指div下的span。C、G:代表類選擇器,。D,、F:代表:id選擇器。后面的123456,,代表匹配的規(guī)則,。

樣式上下文樹.png
樣式上下文樹.png

解釋一下:當(dāng)遇到一個(gè)dom節(jié)點(diǎn),例如:第二個(gè)div,,根據(jù)css解析結(jié)果,,進(jìn)行規(guī)則匹配發(fā)現(xiàn)符合126這條規(guī)則線,我們發(fā)現(xiàn),,當(dāng)遇到第一個(gè)div時(shí)已經(jīng)匹配過12這條規(guī)則線,,所以只需為規(guī)則6新增一個(gè)節(jié)點(diǎn)至樣式上下文樹的div:F節(jié)點(diǎn)。樣式上下文樹,,是元素匹配樣式的最終結(jié)果(原本是比例的也要換算成具體的px),。 Gecko利用樣式規(guī)則樹,有效的實(shí)現(xiàn)了樣式共享,。Webkit沒有規(guī)則樹,,則需要對(duì)css解析結(jié)果進(jìn)行多次遍歷。出現(xiàn)多次的屬性將會(huì)被按照正確的級(jí)聯(lián)順序進(jìn)行處理最后一個(gè)生效,。

根據(jù)對(duì)計(jì)算樣式困難的理解,,我們?cè)诰帉慶ss樣式表時(shí)應(yīng)該注意一下:

  1. dom深度盡量淺。
  2. 減少inline javascript,、css的數(shù)量,。
  3. 使用現(xiàn)代合法的css屬性。
  4. 不要為id選擇器指定類名或是標(biāo)簽,,因?yàn)閕d可以唯一確定一個(gè)元素,。
  5. 不要給類選擇器指定標(biāo)簽,,類,,代表具有一類屬性的標(biāo)簽,不僅是一個(gè),,雖然可以實(shí)現(xiàn),,但是降低了效率。
  6. 避免后代選擇符,,盡量使用子選擇符,。原因:子元素匹配符的概率要大于后代元素匹配符。后代選擇符;#tp p{} 子選擇符:#tp>p{}
  7. 避免使用通配符,,舉一個(gè)例子,,.mod .hd *{font-size:14px;} 根據(jù)匹配順序,將首先匹配通配符,也就是說先匹配出通配符,然后匹配.hd(就是要對(duì)dom樹上的所有節(jié)點(diǎn)進(jìn)行遍歷他的父級(jí)元素),然后匹配.mod,這樣的性能耗費(fèi)可想而知.

參考文章:
瀏覽器加載和渲染html順序
JS 和 CSS 的位置對(duì)其他資源加載順序的影響

歡迎補(bǔ)充與指正?
歡迎補(bǔ)充與指正?

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多