前端面试之页面渲染规则📖

引言💭

面试时被问到了性能优化方面的问题,一脸懵逼,要学习性能优化首先得先了解页面渲染规则。网页的渲染是一个复杂的过程,涉及多个阶段和机制。

基础知识📑

一、文档流与布局

1. 文档流

文档流是浏览器根据 HTML 结构逐步从上到下、从左到右地渲染元素。浏览器解析 HTML 时,元素的排列遵循文档流的规则:

  • 块级元素 :独占一行,通常具有 100% 的宽度。例如:<div>, <p>, <section> 等。
  • 行内元素 :与其他行内元素排在同一行,宽高由内容决定。例如:<span>, <a>, <strong> 等。

文档流的布局规则影响元素的展示位置和大小,它决定了网页的基本排版。代码示例如下:

css 复制代码
<div>这是一个块级元素</div>
<span>这是一个行内元素</span>
<span>这是另一个行内元素</span>

效果

  • <div> 占据一整行,接下来的内容会换行。
  • <span> 元素会排在同一行内。

2. 盒模型

每个 HTML 元素都可以视为一个"盒子",盒模型定义了元素的尺寸和间距。标准盒模型和 IE 盒模型是两种常见的盒子计算方式:

  • 标准盒模型(content-box :元素的宽度和高度只计算内容区域,不包括 padding 和 border。
  • IE 盒模型(border-box :元素的宽度和高度包括了 padding 和 border,计算更为直观。

例如,假设我们有如下的 CSS:

css 复制代码
div {
  width: 200px;
  padding: 20px;
  border: 10px solid #000;
  margin: 15px;
}
  • content-box 模式下,div 的总宽度为 200px (width) + 40px (padding) + 20px (border)
  • border-box 模式下,div 的总宽度依然是 200px,包含了 padding 和 border。

理解盒模型有助于精确控制元素的尺寸与布局。

二、格式化上下文

1. 什么是格式化上下文?

格式化上下文(FC)是浏览器渲染元素的规则集合,决定了元素如何相互排列和展示。不同类型的格式化上下文会显著影响元素的布局行为。常见的格式化上下文包括 块级格式化上下文(BFC)弹性格式化上下文(FFC)网格格式化上下文(GFC)

2.块级格式化上下文(BFC)

BFC 是一个独立的渲染区域,决定了其中元素的布局和其他元素的交互行为。BFC 的特点包括:

  • 独立性:BFC 内的元素不会影响外部元素,外部元素也不会影响 BFC 内的元素。
  • 布局规则:BFC 中的块级元素会从上到下垂直排列,行内元素则从左到右排列。
  • Margin 重叠:同一 BFC 下相邻元素的 margin 会发生重叠,较大的 margin 会决定最终的间距。

要触发 BFC,可以通过设置 overflow: hiddendisplay: flow-root 等属性。例如:

css 复制代码
.container {
  overflow: hidden; /* 触发 BFC */
}

示例

ini 复制代码
<div class="container">
  <div class="item">Item 1</div>
  <div class="item">Item 2</div>
</div>
css 复制代码
.container {
  overflow: hidden;
  background-color: lightgray;
}

.item {
  margin-top: 20px;
  background-color: lightblue;
}

在这个示例中,overflow: hidden 会触发 BFC,保证 .container 内部元素的布局独立,不会受到外部影响。

3. 弹性格式化上下文(FFC)

Flexbox(弹性布局)创建了一种新的格式化上下文------弹性格式化上下文(FFC) 。在 FFC 中,元素可以自动适应容器的空间,且具有强大的对齐功能。通过 display: flexdisplay: inline-flex 创建弹性布局,使得子元素可以灵活地调整排列方式。

css 复制代码
.container {
  display: flex;
  justify-content: space-between;
}

.item {
  width: 100px;
  height: 100px;
  background-color: lightblue;
}

效果 :子元素 .item 会在 .container 中等距排列。

4. 网格格式化上下文(GFC)

CSS Grid(网格布局)创建了 网格格式化上下文(GFC) ,允许开发者设计复杂的二维布局。在 GFC 中,子元素根据网格模板进行布局,可以在行列中自由放置和对齐。示例代码:

css 复制代码
.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

.item {
  background-color: lightcoral;
  height: 100px;
}

效果.container 内部的 .item 元素会均匀分布在 3 列网格中。

三、布局模型

  • 块级布局:块级元素从上到下、占据整行,常用于布局的基本框架。
  • 行内布局:行内元素不会占据整行,常用于文本排版和小组件。
  • Flex 布局 :通过 display: flex 创建弹性布局,子元素可以在水平方向或垂直方向上灵活排列。
  • Grid 布局 :通过 display: grid 创建网格布局,可以精确地控制元素的位置和大小,适用于复杂的二维布局。

示例:使用 Flexbox 和 Grid 布局的对比

Flexbox 示例:

css 复制代码
.container {
  display: flex;
  justify-content: space-between;
}

.item {
  width: 100px;
  background-color: lightgreen;
}

Grid 示例:

css 复制代码
.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

.item {
  background-color: lightyellow;
  height: 100px;
}

四、层叠上下文与 z-index

层叠上下文是一个三维概念,决定了页面上不同元素的堆叠顺序。元素的 z-index 属性用于控制元素的堆叠层次,值越大,元素越靠前。

  • 堆叠上下文z-index 不仅仅依赖于元素自身,还受父元素的影响。如果父元素创建了新的堆叠上下文,那么子元素的 z-index 仅在这个上下文内有效。
css 复制代码
.parent {
  position: relative;
  z-index: 10;
}

.child {
  position: absolute;
  z-index: 20;
}

效果child 元素会堆叠在 parent 元素上方。

五、CSS 样式书写方式

CSS 样式可以通过不同的方式书写,每种方式有其优缺点:

  • 行内样式:直接写在 HTML 元素上,优先级最高,但不便于维护。
  • 内嵌样式 :写在 <style> 标签中,适合小范围的页面样式,但不易复用。
  • 外联样式 :通过 <link> 引入外部 CSS 文件,易于维护和复用,支持并发加载,提高页面加载速度。

此外,CSS 预处理器(如 StylusSass)提供了更强大的功能,如省略分号和花括号、使用变量和混合宏等,使得 CSS 的书写更简洁高效。 在文章中继续补充页面渲染规则相关的内容:

页面渲染💻

六、渲染过程概述

页面渲染是指浏览器从接收到 HTML 文档开始,到最终将内容显示在屏幕上的整个过程。

整个渲染过程大致可分为以下几个主要步骤:

1. 解析 HTML 构建 DOM 树

浏览器会逐行解析 HTML 文档,将其中的元素和结构转化为 DOM(文档对象模型)树。DOM 是 HTML 页面结构的树状表示,包含了页面中的所有元素、文本、属性等。

2. 解析 CSS 构建 CSSOM 树

浏览器会同时解析页面中的 CSS(包括外部样式表、内联样式和样式标签等),并根据 CSS 规则构建 CSSOM(CSS 对象模型)树。CSSOM 描述了元素的样式,如字体、颜色、位置、大小等。

3. 构建渲染树

DOM 树和 CSSOM 树会合并,生成渲染树。渲染树是页面渲染的关键,描述了需要展示的元素以及它们的样式。通过渲染树,浏览器可以知道哪些元素是需要显示的,哪些元素是隐藏的。

4. 布局(Layout)

布局阶段,浏览器根据渲染树中每个元素的样式信息(如尺寸、位置等)进行计算,确定每个元素在屏幕上的准确位置。布局过程是影响页面性能的重要因素,特别是在页面内容多、样式复杂时,浏览器可能会执行大量的回流操作。

5. 绘制(Paint)

绘制阶段,浏览器根据布局信息将渲染树中的每个元素转化为图层,并进行绘制。这些图层最终形成屏幕上显示的内容。

  • 分层 根据元素的属性(如 position, opacity, transform 等),浏览器决定哪些元素需要分配到独立的图层中,这些图层可以独立绘制和合成。
  • 生成绘制指令 浏览器为每个图层生成绘制指令,这些指令决定了每个图层如何在屏幕上显示。

6. 合成(Composite)

是将各个图层合并成最终图像的过程。在合成阶段,浏览器将每一层的绘制结果合成在一起,最后将图层显示到屏幕上。

渲染主线程合成线程是两个不同的线程,它们在浏览器渲染过程中的作用和职责不同。浏览器通常会利用多线程来提高渲染效率,尤其是在处理复杂页面时,渲染主线程和合成线程的分工有助于加快页面的显示速度。

七、渲染过程中的优化

现代浏览器采用多种优化技术来提高页面的加载速度和渲染效率。常见的优化方法包括:

  • 懒加载:对于不需要立即显示的资源(如图片、视频等),浏览器会延迟加载,这样可以加快页面初次渲染速度。
  • 异步加载 JavaScript :使用 asyncdefer 属性异步加载 JavaScript,避免 JavaScript 阻塞页面渲染。
  • 资源合并与压缩:通过合并 CSS 和 JavaScript 文件,并进行压缩,减少请求次数和资源体积,提高加载效率。
  • GPU 加速:对于复杂的图形渲染,浏览器可以将渲染过程交给 GPU 进行加速,从而提高性能。
  • 渲染树优化:一些元素的渲染并不会立即影响到其他元素,这些元素可以被延迟渲染或在后台处理,减少不必要的计算。

八、常见的性能瓶颈

在页面渲染过程中,一些操作可能会导致性能问题,常见的瓶颈包括:

  • 强制回流(Reflow)和重绘(Repaint) :频繁的 DOM 操作(如改变元素尺寸、位置或样式)会导致浏览器频繁计算布局和重绘页面,这会影响性能。尤其是在动画和复杂布局中,频繁触发回流可能导致页面卡顿。
  • 大量的 HTTP 请求:如果页面包含大量的资源(如图片、字体、JS 文件等),浏览器需要发送大量请求,增加了网络延迟和加载时间。
  • JavaScript 执行阻塞:如果 JavaScript 脚本没有进行异步加载,它会阻塞浏览器渲染进程。尤其是在 DOM 操作和样式计算之前执行的 JavaScript,会增加页面加载的等待时间。

九、影响渲染的因素

页面的渲染效率受到多种因素的影响,包括但不限于:

  • 资源大小:图片、字体和视频等资源的大小直接影响页面加载速度。通过合理的压缩和优化,能够减少这些资源的体积,提高页面加载速度。
  • DOM 和 CSS 的复杂度:过于复杂的 DOM 结构和大量的 CSS 样式会增加渲染时间,尤其是当页面上有大量的嵌套元素时,渲染引擎需要更多的时间来计算布局和绘制。
  • JavaScript 代码的执行时间:JavaScript 的执行会影响渲染流程,尤其是阻塞式的 JavaScript,可能导致页面显示卡顿。
  • 浏览器兼容性:不同的浏览器可能对渲染规则有所不同,因此开发者需要确保网页在不同的浏览器和设备上有一致的表现。

结语

网页渲染过程是一个复杂且多层次的过程,从 HTML 的解析、布局模型的选择到最终的绘制和合成,每个步骤都对页面的呈现效果和性能产生影响。

相关推荐
开心小老虎15 分钟前
threeJs实现裸眼3D小狗
前端·3d·threejs
龙井>_<1 小时前
vue3使用keep-alive缓存组件与踩坑日记
前端·vue.js·缓存
Captaincc2 小时前
OpenAI以API的形式发布了三 个新模型:GPT-4.1、GPT-4.1 mini 和 GPT-4.1 nano
前端·openai
A-Kamen3 小时前
Webpack vs Vite:深度对比与实战示例,如何选择最佳构建工具?
前端·webpack·node.js
codingandsleeping4 小时前
OPTIONS 预检请求
前端·网络协议·浏览器
_一条咸鱼_4 小时前
大厂Android面试秘籍:Activity 结果回调处理(八)
android·面试·android jetpack
_一条咸鱼_4 小时前
大厂Android面试秘籍:Activity 与 Fragment 交互(九)
android·面试·android jetpack
程序饲养员4 小时前
ReactRouter7.5: NavLink 和 Link 的区别是什么?
前端·javascript·react.js
小小小小宇5 小时前
CSS 层叠上下文总结
前端
拉不动的猪5 小时前
设计模式之------命令模式
前端·javascript·面试