瀏覽器的載入以及重繪和回流問題總結

2021-08-25 22:07:38 字數 3030 閱讀 2207

瀏覽器的載入原則:按照自上而下的順序載入,一般來說瀏覽器會依據html來建立dom樹,並通過css來共同生成render樹(去掉一些沒用的東西)。而js作為整體載入,需要等待dom樹建立完成,通常放在最後(window.onload)。詳細一點的html載入流程如下:

1、輸入**瀏覽器向伺服器傳送請求獲得html檔案。

2、瀏覽器載入html**,自上而下開始解析。

3、發現引入的css檔案,載入這個css檔案。

4、瀏覽器載入body中的元素,並結合css檔案對頁面進行渲染,

5、當瀏覽器遇到需要載入資源的標籤時(img、video等),不會等待資源載入完成,而是繼續向後渲染。

6、當資源載入完畢時,瀏覽器會重新渲染這部分。

7、瀏覽器遇到js**即載入,通常來說,如果script標籤在某元素前面,標籤中包含window.onload,則在render樹渲染完載入js**。

8、針對js中對某些元素節點有特殊操作,則重新渲染這部分節點。

重繪(repaint)和回流(reflow)

重繪(repaint):當render樹中一部分元素的屬性(如一些外觀、樣式不影響布局的)發生變化時需要重新渲染的過程叫做重繪。

回流(reflow):當render樹中一部分或者全部屬性(如元素的規模、尺寸、隱藏等)發生改變而需要重建時叫做回流。

回流的發生:

1、dom樹的結構變化,如新增或刪除元素。

2、元素的幾何屬性的改變(如margin、padding、width、height、border等)。

3、頁面初始化渲染。

4、獲取某些屬性,瀏覽器為取得準確的值也會觸發回流(offsettop、clienttop、scrolltop、getcomputedsyle()等等)。

5、瀏覽器視窗尺寸的改變。

* 瀏覽器減少回流重繪的方法: *

我們可以知道如果每句js操作都去回流重繪,瀏覽器消耗巨大,所以通常瀏覽器會維護乙個佇列,把所有會引起回流、重繪的操作放入這個佇列,等佇列中的操作到了一定的數量揮著到了一定的時間間隔,瀏覽器就會flush佇列,進行乙個批處理。這樣多次回流、重繪就變成一次。

* 我們日常開發時如何減少回流、重繪 *

減少回流、重繪其實就是需要減少對render tree的操作(合併多次多dom和樣式的修改),並減少對一些style資訊的請求,盡量利用好瀏覽器的優化策略。具體方法有:

1、直接改變classname,如果動態改變樣式,則使用csstext(考慮沒有優化的瀏覽器)

// 不好的寫法

var left = 1

;var top = 1

;el.style

.left = left + "px"

;el.style

.top = top + "px"

;// 較好的寫法

el.classname += "classname1"

;// 比較好的寫法

el.style

.csstext += "left: " + left + "px; top: " + top + "px;"

;

2、讓要操作的元素進行「離線處理」,處理完後一起更新

a). 使用documentfragment進行快取操作,引發一次一次回流和重繪;

//不好的寫法(模式中所說的反模式)

var p, t;

p = document.createelement('p');

t = document.createtextnode('fist paragraph');

p = document.createelement('p');

t = document.createtextnode('second paragraph');

// 好的寫法

var p, t, frag;

frag = document.createdocumentfragment();

p = document.createelement('p');

t = document.createtextnode('fist paragraph');

p = document.createelement('p');

t = document.createtextnode('second paragraph');

b). 使用display: none技術,只引發兩次回流和重繪;(只是減少重繪和回流的次數,display: none是會引起重繪和回流,相對而言,visibility: hidden只會引起重繪)

c). 使用clonenode(true or false)和replacechild技術,引發一次回流和重繪;

// 建立轉殖映象

var oldnode = document.getelementbyid('target'),

clone = oldnode.clonenode(true);

// 處理轉殖物件的操作...

//完成後

oldnode.parentnode.replacechild(clone, oldnode);

3、不要經常訪問會引起瀏覽器flush佇列的屬性,如果你確實要訪問,利用快取

// bad way

for(迴圈)

// 較好的寫法

var left = el.offsetleft,

top = el.offsettop,

s = el.style;

for(迴圈)

4、讓元素脫離動畫流(position屬性設為absolute或fixed,使元素脫離文件流),減少回流的render tree的規模。

5、盡量不使用**布局,如果沒有定寬**一列的寬度由最寬的一列決定,那麼可能在最後一行的寬度超出之前的列寬,引起整體回流造成table肯需要多次計算才能確定好其渲染樹中節點的屬性,通常需要花三倍同等元素的時間。

歡迎關注支援,謝謝!

瀏覽器的重繪和回流

重繪 當元素樣式的改變不影響布局時,瀏覽器會使用重繪的方式來更新元素的變化,這種改變只會在ui層的重新畫素繪製,這種方式的對瀏覽器開銷比較小。常見的重繪操作有 改變元素顏色 改變元素背景色 more 回流 又名 重排 當元素的尺寸 結構或者觸發了某個屬性的改變,會導致瀏覽器重新渲染,這種操作會造成回...

瀏覽器的回流和重繪

重繪 比如 background color font size 等,這些屬性的改變不會影響頁面的結構布局,只會影響內容的變化,即這些屬性的改變將會引起瀏覽器的重繪 回流 比如 padding margin height 等,改變這些屬性會影響頁面的結構布局,即改變這些屬性會引起瀏覽器的回流 為什麼...

瀏覽器的重繪和回流

我的部落格 這是我在之前面試中遇到的乙個問題,今天回想起來正好做乙個總結 這其實也是我遇到的一道面試題,與重繪和回流息息相關 使用者輸入 瀏覽器嘗試與伺服器建立連線 伺服器傳送永久重定向 瀏覽器跟蹤重定向位址 伺服器處理請求 伺服器傳送html響應 瀏覽器接收響應,開始解析 解析html檔案,處理並...