WHAT - Vercel react-best-practices 系列(五)

文章目录

前言

react-best-practices

React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.

Guidelines

在这个系列,我会逐条拆解,每一条都给出:

  • 核心问题是什么
  • 为什么会慢(本质原因)
  • 典型业务场景
  • 反例代码
  • 推荐写法
  • 在 React / Next.js 中的实际收益

JavaScript Patterns

这是系列的第五部分。

这一部分其实非常"工程味" ,不再是 React 专属,而是 JS / DOM / 数据结构层面的硬功夫

这些点看起来"小",但在表格、列表、频繁交互 里都是实打实的性能差异

Batch DOM CSS changes via classes

样式一次性切换,不要逐条改

核心问题

每一次:

js 复制代码
el.style.xxx = ...

都可能触发:

  • style recalculation
  • layout
  • paint

多次修改 = 多次成本

反例:逐条改 style

js 复制代码
el.style.width = '200px'
el.style.height = '100px'
el.style.background = 'red'

推荐:class 批量切换

js 复制代码
el.classList.add('active')
css 复制代码
.active {
  width: 200px;
  height: 100px;
  background: red;
}

浏览器只需要一次 style 计算

典型场景

  • hover / active 状态
  • 拖拽高亮
  • 表格行选中
  • 动态主题切换

一句话总结

DOM 改一次,CSS 管所有

Build index maps for repeated lookups

多次查找,用 Map,不要 filter / find

核心问题

js 复制代码
array.find(...)
  • O(n)
  • 在 render / 循环中反复执行 → O(n²)

反例

ts 复制代码
items.map(item => {
  const user = users.find(u => u.id === item.userId)
  return { ...item, user }
})

推荐:构建索引 Map

ts 复制代码
const userMap = new Map(users.map(u => [u.id, u]))

items.map(item => {
  const user = userMap.get(item.userId)
  return { ...item, user }
})

复杂度从 O(n²) → O(n)

典型场景

  • 表格数据 join
  • id → entity 映射
  • 权限校验
  • diff 对比

一句话总结

先建索引,再查数据

Cache repeated function calls

相同输入,不要重复算

核心问题

ts 复制代码
formatPrice(price)

如果:

  • 在 render 中
  • 在循环里
  • 输入值重复

白算很多次

反例

ts 复制代码
{items.map(i => (
  <span>{formatPrice(i.price)}</span>
))}

推荐:简单 memo

ts 复制代码
const cache = new Map()

function formatPriceCached(price) {
  if (cache.has(price)) return cache.get(price)

  const result = formatPrice(price)
  cache.set(price, result)
  return result
}

React 中更推荐:

ts 复制代码
const formatted = useMemo(
  () => formatPrice(price),
  [price]
)

一句话总结

算过的值,记下来

Use toSorted() instead of sort() for immutability

不要原地排序

核心问题

js 复制代码
array.sort()
  • 原地修改
  • 破坏不可变数据
  • React 中可能导致 状态错乱

反例

ts 复制代码
const sorted = items.sort((a, b) => a.age - b.age)
setItems(sorted)

items 被直接改了

推荐:toSorted(ES2023)

ts 复制代码
const sorted = items.toSorted((a, b) => a.age - b.age)
setItems(sorted)

返回新数组,原数组不变

兼容方案

ts 复制代码
[...items].sort(...)

一句话总结

React 状态 = 不可变

Early length check for array comparisons

先比长度,再比内容

核心问题

ts 复制代码
arraysEqual(a, b)

如果:

  • 长度不同
  • 却仍然逐项对比

纯浪费

反例

ts 复制代码
function isEqual(a, b) {
  return a.every((v, i) => v === b[i])
}

推荐:提前剪枝

ts 复制代码
function isEqual(a, b) {
  if (a.length !== b.length) return false

  return a.every((v, i) => v === b[i])
}

场景

  • memo / shouldComponentUpdate
  • diff 算法
  • selection 对比
  • 权限数组变化检测

一句话总结

先 cheap check,再 expensive check

JS 性能心法

少动 DOM
少扫数组
少算重复
不改原数据
先剪枝

总结

JS 性能不是靠"更快算法",而是靠"少做事"

相关推荐
kyriewen19 小时前
别再 console.log 了:5 个 Chrome DevTools 调试技巧,用过就回不去了
前端·javascript·面试
IT_陈寒20 小时前
Python搞不定字符串编码?这破玩意坑我两小时!
前端·人工智能·后端
DigitalOcean1 天前
Laravel 开发者已在 DigitalOcean 上开通超过 10 万台服务器
前端·laravel
星始流年1 天前
从 Tool 到 Skill——基于 LangChain 的服务端Skill实现
前端·langchain·agent
李惟1 天前
开源本地通信库,纯客户端 RPC,像聊天一样通信
前端
YAwu111 天前
深入解析 React 炫彩鼠标跟随标题组件:从坐标定位到动画性能
前端·react.js
GuWenyue1 天前
排序效率低?5分钟吃透快速排序,性能飙升至O(nlogn)
前端·javascript·面试
OpenTiny社区1 天前
🎨 看完 GenUI SDK 源码我悟了!
前端·vue.js·github
叁两1 天前
前端转型AI Agent该如何学习?(前置篇)
前端·人工智能·node.js
何时梦醒1 天前
深入理解递归与快速排序 —— 从基础入门到手写实现
前端·javascript