介紹 Box, Reflow, Render pipeline 等
Box Element
首先瀏覽器上每個元素都是 Box,而每個 Box 分成了 4 個部分,包含了:
- Content Box 內容的區域
- Padding Box 內部的 Spacing
- Border Box 內容和 Padding 間的區域
- Margin Box 外部的空間

Box 有 2 種屬性 Size 以及 Generation,Size 可以分為:
- Intrinsic
- Extrinsic
當 Box Size 是 Intrinsic 時,Box 會使用內容當作該 Box 的空間,不考慮外部環境影響;當 Box Size 是 Extrinsic 時,Box 會透過 CSS 設定空間或是被父元素控制空間。
Intrinsic Size 的範例:
如 <span> 就是一個很好的 Intrinsic Size 的元素,他是個 inline 的元素,所以設定寬高都不會影響到他,只會根據文字的長度決定寬,文字的 line-height 決定此元素的高。
<span>Hello</span>
如果要設定一個元素是最小的 Intrinsic Size,可以使用 width: min-content ,此時會盡可能地進行換行,最後的寬度會由最長的詞為寬度。
<div class="min-intrinsic-size">This is a long long long long sentence</div>
<style>
.min-intrinsic-size {
width: min-content;
}
</style>
另外像是圖片,如果有一張長寬爲 800x600 的圖片,在未進行設定的情況下,它就會以 800x600 的方式自然呈現。
<img src="photo800x600.jpg">
Extrinsic 的範例:
例如 CSS 使用了 aspect-ratio ,定義了寬高比,內容大小被父原素限定住了,就是 Extrinsic Size
.box {
width: 100%;
aspect-ratio: 16 / 9;
}
或是由父元素去設定寬高,決定內容的空間
<div class="box">
<p>Content Content Content</p>
</div>
<style>
width: 200px; height: 100px; overflow: auto;
</style>
Box Generation 可以分為以下 3 種:
- Block
- Anonymous
- Inline
首先 Block 會 100% 的填滿父元素的寬,高是 Intrinsic 由內容決定高度,然後會由上至下進行 Render,並且會加入 BFC 排版,常見的元素有 div , p , address , articale 等。
Anonymous 則是未被元素包起來的內容例如:
<div>Hello</div>
Hello <--- anonymouse box
Anonymous 是由瀏覽器自動生成的,沒辦法透果 CSS 選擇器選到。
下一個是 Inline 它的渲染方式是像是字串,並且會加入 IFC 排版,它的特性是會不生效所設定的寬高和垂直的 margin (水平的仍然是生效的),它的高度會受到 line-height 所影響,但 padding 不會真的影響到它的高,常見的元素有 button , a , i , label 等。
Browser Formatting Context
Formatting Context 是一個區塊、範圍,當 Element 進入 Formatting Context,Element 就會依照它的規則進行呈現。
例如以 BFC(Block Formatting Context) 來說,在內的元素會填滿父元素,並由上到下進行排列。
IFC(Inline Formatting Context) 中的元素會依照由右至左進行排列,寬度則是 Intrinsic 的。
Formatting Context 有著:
- Isolation:外部和內部的規則不會互相進行影響
- Scalability:可以通過建立新的 Formatting Context 實現特定的佈局
- Predictability:擁有明確的規則,元素是可以被控制的
Browser Position
在預設的情況下,瀏覽器的定位會依照 Normal Flow 進行排列(RTL, LTR),在建立元素的時候預設是 static 此時是無法透過設定 left, right, bottom, top 去進行設定。
relative 元素仍然是在 Normal Flow 中,會建立新的 Stacking Content,可以相對於 Containing Block 去進行相對的定位(使用 left, right 等定位,預設是左上角)。
absolute 會完全脫離 Normal Flow 中,會建立新的 Stacking Content,其他的元素會忽略此元素進行排列,會依照 Containing Block 進行定位。
How the browser render the website
首先瀏覽器在渲染時,會透過 HTML 產生 DOM Tree,以及 Style 的 CSSOM(CSS Object Model),之後會將 2 者結合爲 Render Tree 。
Render Tree 會由 Root 開始進行渲染,遇到不顯示的會忽略 (display: none , meta , link ),之後會和 CSSOM 的規則應用在各 node 上。
其中當 DOM 改變(新增、移除、改變位置)發生時,會產生 Reflow :

Reflow 的示意影片:
在 Style 以及 Layout 的部分會使用 CPU 去執行,會阻塞到 main thread,所以當執行過多次的 Reflow 就有可能造成畫面卡的現象。
例如:
@keyframes moving-down-slow {
from {
margin-top: 0;
}
to {
margin-top: 500px;
}
}
@keyframes moving-down-fast {
from {
transform: translateY(0px);
}
to {
transform: translateY(500px);
}
}
這 2 個 style 動畫所做的事是相同的,但在第一個使用了 margin 會導致 Reflow 的產生,若是使用下方的 transform 則不會影響到 Layout。
哪些 CSS 會觸發 Layout 可以參考 https://css-triggers.com/ 會顯示哪些屬性 Trigger 了不同的 Step 。
Layer
Layer 的存在是為了優化網頁的渲染,如果每個 Render Tree 都需要透過 CPU 進行一個個的渲染效率非常差,若可以一起進行則效率會變得更好。
Layer 有分成 2 種類型,一是一般的 Render Layer,另一個是 Composition Layer。
Render Layer 會在以下以時候建立:
position: relative或是absolute並使用了transformtransparent- CSS Filter
- etc
<div class="filter">Filter Render Layer</div>
<style>
.filter {
will-change: filter;
filter: blur(5px);
}
</style>
當該層 Layer 做出不影響 Layout 的更新時,不會影響到整體頁面的更新,減少不必要的重繪。
Composition Layer 則適用於 3D 或是動畫的狀況,它會使用到 GPU 加速繪製,在 Render Layer 滿足以下狀況會變成 Composition Layer:
- 帶有使用 3D 的屬性或是 transform 有
perspective - vido or canvas
- animation opacity
- etc
Composition Layer 會建立 thread 並使用 GPU 加速,所以可以一邊進行動畫一邊執行複雜的任務也不會造成卡頓的問題。
References
https://webperf.tips/tip/layers-and-compositing/
https://developer.mozilla.org/en-US/docs/Glossary/Intrinsic_Size
https://dev.to/gopal1996/understanding-reflow-and-repaint-in-the-browser-1jbg?__readwiseLocation=












