首頁 web前端 前端問答 前端開發者必須知道網頁是如何渲染的

前端開發者必須知道網頁是如何渲染的

Nov 29, 2016 am 09:35 AM

【編者按】其實,有關網頁渲染的文章很多,但是相關資訊比較分散,且論述並不是很完整。如果要想對這個主題有個大致的了解,我們還得學習很多知識。因此,Web開發者Alexander Skutin 決定寫一篇文章。他相信,這篇文章不僅能幫助初學者,也能對那些想要刷新知識結構的高階前端開發者有所裨益。原文地址

譯文如下:

網頁渲染必須在很早的階段進行,可以早到頁面佈局剛剛定型。因為樣式和腳本都會對網頁渲染產生關鍵性的影響。所以專業開發者必須了解一些技巧,以避免在實務的過程中遇到效能問題。

這篇文章不會研究瀏覽器內部的詳細機制,而是提出一些通用的規則。畢竟,不同瀏覽器引擎的工作機制各不相同,這無疑會讓開發者對瀏覽器特性的研究變得更加複雜。

瀏覽器是如何完成網頁渲染?

首先,我們回顧網頁渲染時,瀏覽器的動作:

根據來自伺服器端的HTML程式碼形成文件物件模型(DOM)

載入並解析樣式,形成CSS物件模型。

在文檔物件模型和CSS物件模型之上,創建一棵由一組待生成渲染的物件組成的渲染樹(在Webkit中這些物件被稱為渲染器或渲染對象,而在Gecko中稱之為「frame」。在渲染樹中,每一段文字字串都表現為獨立的渲染器。每一個渲染對像都包含對應的DOM對象,或是文字區塊,還加上計算好的樣式。換言之,渲染樹是一個文檔物件模型的直覺展示。

對渲染樹上的每個元素,計算它的座標,稱之為佈局。瀏覽器採用一種串流方法,佈局一個元素只需通過一次,但是表格元素需要通過多次。

最後,渲染樹上的元素最終展示在瀏覽器裡,這個過程稱為「painting」。

當使用者與網頁交互,或腳本程式改動修改網頁時,前文提到的一些操作將會重複執行,因為網頁的內在結構已經改變了。

重繪

當改變那些不會影響元素在網頁中的位置的元素樣式時,譬如background-color(背景色), border-color(邊框色), visibility(可見性),瀏覽器只會用新的樣式將元素重繪一次(這就是重繪,或者說重新構造樣式)。

重排

當改變影響到文字內容或結構,或元素位置時,重排或重新佈局就會發生。這些改變通常由以下事件觸發:

DOM操作(元素添加,刪除,修改,或元素順序的改變);

內容變化,包括表單域內的文字變更;

CSS屬性的計算或變更;

新增或刪除樣式表;

更改「類別」的屬性;

瀏覽器視窗的操作(縮放,捲動);

偽類啟動(:懸停)。

瀏覽器如何最佳化渲染?

瀏覽器盡可能將重繪/重構 限制在被改變元素的區域內。例如,對於位置固定或絕對的元素,其大小改變只影響元素本身及其子元素,然而,靜態定位元素的大小改變會觸發後續所有元素的重流。

另一種最佳化技巧是,在執行幾段JavaScript程式碼時,瀏覽器會快取這些改變,在程式碼運行完畢後再將這些改變經一次通過加以應用。舉個例子,下面這段程式碼只會觸發一個重構和重繪:

var $body = $('body');
$body.css('padding', '1px'); // reflow, repaint
$body.css('color', 'red'); // repaint
$body.css('margin', '2px'); // reflow, repaint
// only 1 reflow and repaint will actually happen
登入後複製

然而,如前所述,改變元素的屬性會觸發強制性的重排。如果我們在上面的程式碼區塊中加入一行程式碼,用來存取元素的屬性,就會發生這種現象。

var $body = $('body'); $body.css('padding', '1px'); $body.css('padding'); // reading a property, a forced reflow $body .css('color', 'red'); $body.css('margin', '2px');

其結果就是,重排發生了兩次。因此,你應該把存取元素屬性的操作都組織在一起,從而優化網頁效能。 (你可以在JSBin查到更詳細的例子)

有時,你必須觸發一個強制性重排。例如,我們必須將同樣的屬性(例如左邊距)兩次賦值給同一個元素。起初,它應該設定為100px,且不帶動效。接著,它必須透過過渡(transition)動效改變為50px。你現在可以在JSbin上學習這個例子,不過我會在這裡更詳細地介紹它。

首先,我們建立一個帶有過渡效果的CSS類別:.has-transition { -webkit-transition: margin-left 1s ease-out; -moz-transition: margin-left 1s ease-out; -o-transition: margin-left 1s ease-out; transition: margin-left 1s ease-out; }

然後繼續執行:// our element that has a "has-transition" class by default var $targetEltar = $('## );

// remove the transition class
$targetElem.removeClass('has-transition');
// change the property expecting the transition to be   off, as the class is not there
// anymore
$targetElem.css('margin-left', 100);
// put the transition class back
$targetElem.addClass('has-transition');
// change the property
$targetElem.css('margin-left', 50);
登入後複製

然而,這個執行無法奏效。所有改變都被緩存,只在程式碼區塊末尾加以執行。我們需要的是強制性的重排,我們可以透過以下更改加以實現:

// remove the transition class $(this).removeClass('has-transition');

// change the property
$(this).css('margin-left', 100);
// trigger a forced reflow, so that changes in a    class/property get applied immediately
$(this)[0].offsetHeight; // an example, other   properties would work, too
// put the transition class back
$(this).addClass('has-transition');
// change the property
$(this).css('margin-left', 50);
登入後複製

現在程式碼如預期那樣執行了。

有關效能最佳化的實際建議

總結現有的資料,我提出以下建議:

創建有效的HTML和CSS文件,不要忘記指明文檔的編碼方式。樣式應該包含在標籤內,腳本程式碼則要加在標籤末端。

盡量簡化和最佳化CSS選擇器(這種最佳化方式幾乎被使用CSS預處理器的開發者統一忽視了)將嵌套程度保持在最低水平。以下是CSS選擇器的效能排名(從最快者開始)

1. 识别器:#id
2. 类:.class
3. 标签:div
4. 相邻兄弟选择器:a + i
5. 父类选择器:ul> li
6. 通用选择器:*
7. 属性选择:input[type="text"]
8. 伪类和伪元素:a:hover
登入後複製

你應該記住,瀏覽器在處理選擇器時依照從右到左的原則,因此最右端的選擇器應該是最快的: #id或則.class:div * {...} // bad .list li {...} // bad .list-item {...} // good #list .list-item {... } // good * 1.在你的腳本程式碼中,盡可能減少DOM操作。快取所有東西,包括元素屬性以及物件(如果它們被重複使用的話)。當進行複雜的操作時,使用「孤立」元素會更好,之後可以將其加到DOM中(所謂「孤立」元素是與DOM脫離,僅保存在記憶體中的元素)。

2.如果你使用jQuery來選擇元素,請遵從jQuery選擇器最佳實踐方案。

3.為了改變元素的樣式,修改「類別」的屬性是奏效的方法之一。執行此變更時,處在DOM渲染樹的位置越深越好(這也有助於將邏輯與表象脫離)。

4.盡量只為位置絕對或固定的元素添加動畫效果。

5.在使用滾動時會停用複雜的懸停效(例如,在中加入一個額外的不懸停類別)。讀者可以閱讀關於這個問題的一篇文章。

想了解更多的細節問題,大家也可以看看這兩篇文章:

1,How browsers work?

2,Rendering: repaint, reflow/relayout, restyle


本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

2023年將突出的一些前端開發趨勢,學到! 2023年將突出的一些前端開發趨勢,學到! Mar 14, 2023 am 09:37 AM

前端開發趨勢總是不斷發展,有些趨勢會長期流行。這篇文章為大家總結了2023 年將突出的一些前端開發趨勢,分享給大家~

如何使用PHP和Angular進行前端開發 如何使用PHP和Angular進行前端開發 May 11, 2023 pm 04:04 PM

隨著網路的快速發展,前端開發技術也不斷改進與迭代。 PHP和Angular是兩種廣泛應用於前端開發的技術。 PHP是一種伺服器端腳本語言,可以處理表單、產生動態頁面和管理存取權限等任務。而Angular是一種JavaScript的框架,可以用來開發單一頁面應用程式和建構元件化的網頁應用程式。本篇文章將介紹如何使用PHP和Angular進行前端開發,以及如何將它們

Flet:一個可跨平台的基於Flutter的Python框架 Flet:一個可跨平台的基於Flutter的Python框架 Apr 20, 2023 pm 05:46 PM

昨天剛發了一篇Python桌面開發庫大全的微頭條,就被同事安麗了Flet這個庫。這是一個非常新的庫,今年6月才發布的第一個版本,雖然很新,但是它背靠巨人-Flutter,可以讓我們使用Python開發全平台軟體,雖然目前還不支援全平台,但是根據作者的計劃,Flutter支持的,它以後都會支持的,昨天簡單學習了一下,真的非常棒,把它推薦給大家。後面我們可以用它來做一系列東西。什麼是FletFlet是一個框架,允許用你喜歡的語言建立互動式多用戶Web,桌面和行動應用程序,而無需擁有前端開發的經驗。主

學會利用sessionstorage,提高前端開發效率 學會利用sessionstorage,提高前端開發效率 Jan 13, 2024 am 11:56 AM

掌握sessionStorage的作用,提升前端開發效率,需要具體程式碼範例隨著網路的快速發展,前端開發領域也日新月異。在進行前端開發時,我們經常需要處理大量的數據,並將其儲存在瀏覽器中以便後續使用。而sessionStorage就是一個非常重要的前端開發工具,可以提供我們臨時的本機儲存解決方案,提高開發效率。本文將介紹sessionStorage的作用,

前端開發中的JavaScript非同步請求與資料處理經驗總結 前端開發中的JavaScript非同步請求與資料處理經驗總結 Nov 03, 2023 pm 01:16 PM

前端開發中的JavaScript非同步請求與資料處理經驗總結在前端開發中,JavaScript是一門非常重要的語言,它不僅可以實現頁面的互動和動態效果,還可以透過非同步請求來取得和處理資料。在這篇文章中,我將總結一些在處理非同步請求和資料時的經驗和技巧。一、使用XMLHttpRequest物件進行非同步請求XMLHttpRequest物件是JavaScript用於發送

提升網站速度的關鍵最佳化模式,每個前端開發者都必須掌握! 提升網站速度的關鍵最佳化模式,每個前端開發者都必須掌握! Feb 02, 2024 pm 05:36 PM

前端開發者必備:掌握這些最佳化模式,讓網站飛起來!隨著網路的快速發展,網站已成為企業宣傳和交流的重要管道之一。一個效能優良、載入迅速的網站不僅可以提升使用者體驗,還可以吸引更多的訪客。身為前端開發者,掌握一些最佳化模式是不可或缺的。本文將介紹一些常用的前端優化技術,幫助開發者更好地優化網站。壓縮檔案在網站開發中,經常使用的檔案類型包括HTML、CSS和J

Golang前端新趨勢:解讀Golang在前端開發的應用前景 Golang前端新趨勢:解讀Golang在前端開發的應用前景 Mar 20, 2024 am 09:45 AM

Golang前端新趨勢:解讀Golang在前端開發的應用前景近年來,前端開發領域發展迅猛,各種新技術層出不窮,而Golang作為一種快速、可靠的程式語言,也開始在前端開發中嶄露頭角。 Golang(也稱為Go)是由Google開發的程式語言,以其高效的效能、簡潔的語法和強大的功能而聞名,逐漸受到前端開發者的青睞。本文將探討Golang在前端開發的應用前

node.red是什麼 node.red是什麼 Nov 08, 2022 pm 03:53 PM

node.red指Node-RED,是一款基於串流的低程式設計工具,用於以新穎有趣的方式將硬體設備,API和線上服務連接在一起;它提供了一個基於瀏覽器的編輯器,使得我們可以輕鬆地使用編輯面板中的各種節點將串流連接在一起,只需單擊即可將其部署到其運行時。

See all articles