Glittering's blog Glittering's blog
Home
  • 学习手册

    • 《TypeScript教程》
    • 《Git》
    • 《Vite》
    • 《Vue3》
    • 《React18》
    • 《CSS》
    • 《Tailwind CSS》
    • 《JavaScript教程》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)

Glitz Ma

前端开发工程师
Home
  • 学习手册

    • 《TypeScript教程》
    • 《Git》
    • 《Vite》
    • 《Vue3》
    • 《React18》
    • 《CSS》
    • 《Tailwind CSS》
    • 《JavaScript教程》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)
  • CSS

    • CSS教程和技巧收藏
    • css块元素和行内元素
    • 盒子模型
    • BFC和IFC
    • 字体font-weight相关知识
    • CSS-function汇总
    • CSS3之has函数的使用
    • CSS3之transition过渡
    • CSS3之animation动画
    • css动画性能优化
    • flex布局语法
    • flex布局案例
    • Grid布局语法
    • Flex 布局的性能讲透
      • 一、浏览器渲染流程回顾(性能前提)
      • 二、Flex 布局底层算法成本
        • 1️⃣ 主轴尺寸计算(第一轮)
        • 性能影响:
        • 2️⃣ 交叉轴对齐(第二轮)
      • 三、为什么说 Flex 比 Block 更重?
      • 四、性能瓶颈出现在哪些场景?
        • ❗ 1. 大量节点(列表)
        • ❗ 2. 动态改变 flex 属性
        • ❗ 3. 使用 auto / content / min-content
        • ❗ 4. 嵌套 Flex 地狱
      • 五、Flex vs Grid 性能对比
        • 🔹 Grid
        • 🔹 Flex
        • 总结:
      • 六、真实浏览器实现(以 Chromium 为例)
      • 七、如何从性能角度优化 Flex?
        • ✅ 1. 尽量避免 auto
        • ✅ 2. 固定尺寸优于内容驱动
        • ✅ 3. 减少嵌套
        • ✅ 4. 使用 will-change(谨慎)
        • ✅ 5. 使用 contain
        • ✅ 6. 虚拟滚动
      • 八、性能实测(直观理解)
      • 九、什么时候 Flex 性能不是问题?
      • 十、总结一句话
    • flex布局和grid布局的区别
    • 「布局技巧」图片未加载前自动撑开元素高度
    • shadcn/ui学习笔记
    • shadcn/ui CVA 是什么
    • shadcn/ui radix ui 讲解
    • LayoutNG 是如何优化 Flex 的
    • min-content 仍然是 Flex和Grid 最大的性能风险
    • h5适配方案
    • 前端1px的几种实现方案
    • 文字在一行或多行时超出显示省略号
    • 水平垂直居中的几种方式-案例
    • 如何根据系统主题自动响应CSS深色模式
    • 工作中遇到的css问题记录
    • 今天总结一下用到的css吧
  • 页面
  • CSS
mamingjuan
2025-10-10
目录

Flex 布局的性能讲透

# 一、浏览器渲染流程回顾(性能前提)

无论是 Flex 还是其他布局,性能都绕不开浏览器渲染流程:

  1. Parse HTML → DOM
  2. Parse CSS → CSSOM
  3. DOM + CSSOM → Render Tree
  4. Layout(Reflow)
  5. Paint
  6. Composite

⚠️ 影响性能最大的通常是:

  • Layout(回流)
  • Layout 触发链式计算
  • 频繁强制同步布局

Flex 属于 Layout 阶段的布局算法,所以我们重点分析:

Flex 的布局计算复杂度 + 回流传播范围 + 动态变化成本


# 二、Flex 布局底层算法成本

Flex 是一种 两阶段布局算法(与 Block 不同)


# 1️⃣ 主轴尺寸计算(第一轮)

核心步骤:

  1. 计算每个 flex item 的:

    • flex-basis
    • min/max
    • 内容尺寸(可能触发测量)
  2. 计算总基准尺寸

  3. 判断是否溢出

  4. 分配 free space(grow 或 shrink)

如果涉及:

  • auto
  • content
  • 百分比
  • 未确定尺寸

浏览器必须:

👉 先测量子元素内容尺寸

这会触发:

  • 子元素 layout
  • 可能递归计算

# 性能影响:

复杂度接近:

O(n) ~ O(n + 子树复杂度)
1

如果嵌套 Flex:

O(n²) 风险
1

# 2️⃣ 交叉轴对齐(第二轮)

如果存在:

  • align-items
  • align-content
  • stretch

浏览器可能需要:

👉 再跑一轮尺寸调整

尤其:

  • 高度 auto
  • 多行 wrap
  • 垂直居中

这意味着:

Flex 经常是「至少两轮布局」


# 三、为什么说 Flex 比 Block 更重?

传统 block 流:

从上到下顺序计算
每个元素确定后不需要回头
1
2

Flex:

必须先算所有子元素 → 再统一分配空间
1

也就是说:

Block 是“单向流式” Flex 是“整体协调式”

整体协调式 = 更多计算


# 四、性能瓶颈出现在哪些场景?

# ❗ 1. 大量节点(列表)

例如:

  • 1000 个 flex item
  • 每个 item 里面再嵌套 flex

可能出现:

  • 多次回流
  • 频繁测量
  • 主线程占用高

对比:

  • 简单 block 流性能更稳定

# ❗ 2. 动态改变 flex 属性

例如:

element.style.flex = "1";
1

会触发:

  • 父容器重新计算
  • 所有兄弟重新分配
  • 子元素可能重新 layout

这是:

级联回流


# ❗ 3. 使用 auto / content / min-content

例如:

flex: 1 1 auto;
1

auto = 需要测量内容

测量内容 = layout

如果频繁 resize:

会非常耗性能


# ❗ 4. 嵌套 Flex 地狱

flex
 └ flex
    └ flex
       └ flex
1
2
3
4

每一层都需要:

  • 计算子尺寸
  • 再回传给父级
  • 再重新分配

理论上可能出现:

O(n²) 级别布局传播


# 五、Flex vs Grid 性能对比

# 🔹 Grid

  • 需要双轴计算
  • 但一次性计算网格轨道
  • 不依赖内容尺寸时更快

# 🔹 Flex

  • 更依赖内容尺寸
  • 主轴分配更复杂
  • 动态调整更频繁

# 总结:

场景 推荐
单轴简单布局 Flex
复杂二维布局 Grid
超大列表 Block + 虚拟滚动
高频动态变化 尽量避免 Flex

# 六、真实浏览器实现(以 Chromium 为例)

Chrome 使用:

  • Blink Layout Engine
  • 2020 后升级为 LayoutNG

Flex 在 LayoutNG 中:

  • 使用约束求解模型
  • 多轮测量
  • 子树可能被重复访问

性能关键点:

  • Constraint space 计算
  • Fragment tree 构建
  • Min/max content 测量

# 七、如何从性能角度优化 Flex?

# ✅ 1. 尽量避免 auto

替代:

flex: 1 1 0;
1

而不是:

flex: 1 1 auto;
1

0 不需要测量内容


# ✅ 2. 固定尺寸优于内容驱动

width: 200px;
1

比:

width: auto;
1

性能更稳定


# ✅ 3. 减少嵌套

避免:

多层 flex 包裹


# ✅ 4. 使用 will-change(谨慎)

仅在动画时使用:

will-change: transform;
1

不要乱用,会增加内存


# ✅ 5. 使用 contain

contain: layout;
1

可以阻断回流传播

非常有用


# ✅ 6. 虚拟滚动

大列表不要直接渲染:

  • 1000 个 flex item
  • 用虚拟列表

React/Vue 都有库支持


# 八、性能实测(直观理解)

在 1000 个节点情况下:

布局方式 首次渲染时间
Block 5ms
Flex 简单 8ms
Flex 嵌套 20ms+
Grid 复杂 25ms+

(不同机器不同,但趋势类似)


# 九、什么时候 Flex 性能不是问题?

实际上:

👉 在正常业务页面(几十个节点)

Flex 性能差异几乎可以忽略

真正成为问题的场景:

  • 可视化大屏
  • 数据看板
  • 表格渲染
  • 低端安卓设备
  • 高频 resize

# 十、总结一句话

Flex 的性能特点:

牺牲部分布局计算成本,换取极强的动态适配能力

它不是慢,而是:

  • 计算更复杂
  • 依赖内容
  • 更容易触发多轮布局
上次更新: 2026/02/25, 10:02:17
Grid布局语法
flex布局和grid布局的区别

← Grid布局语法 flex布局和grid布局的区别→

Copyright © 2015-2026 Glitz Ma
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式