第 2 章 · 性能预算与无障碍实战

📖 前端工程·考点精讲约 2091 字🎯 配套练习:PDE·性能无障碍

考点梳理

2.1 Core Web Vitals(“3 指标 + 预算”)

指标含义良好(示例预算)差(红线)
LCP最大内容元素渲染时间≤ 2.5s> 4s
INP交互到下一帧渲染≤ 200ms> 500ms
CLS累计布局偏移≤ 0.1> 0.25

预算分配法(“L2 加分”):

总预算 LCP 2.5s
├── 网络传输(0.8s)   → 压缩/CDN/HTTP2
├── 下载后执行(0.6s) → 代码分割/减依赖
├── 渲染阻塞(0.5s)   → CSS 内联关键/字体策略
└── 余量(0.6s)       → 缓冲

记忆锚:“LCP 二点五 INP 二百 CLS 一毛;先测再拆预算,超预算砍最大的”。

2.2 前端性能 5 招(“按收益排序”)

#招做法典型收益
1减首屏 JS路由级 lazy() + 首屏外组件动态 importLCP ↓ 30%+
2图片正确尺寸(别传 4K 原图)+ 现代格式(AVIF/WebP)+ loading="lazy"流量 ↓ 50%+
3字体font-display: swap + 子集化(中文按需分包)文字闪现
4长任务拆分大计算分片 / Web Worker(主线程别卡 > 50ms)INP ↓
5依赖治理bundle analyzer 找大依赖,换轻量替代体积 ↓

流式输出场景专项(“AI 产品高频坑”):

坑现象对策
每 token 全量重渲染打字卡顿(INP 爆)消息列表虚拟化(只渲染可见)+ 攒批更新(每 2~3 帧或每 30ms 刷一次)
光标跳动布局偏移预留高度/固定行高(CLS)
停止按钮卡死点了没反应AbortController 真正中断请求(“假停止 = 假体验”)

铁律:“流式场景 INP 是生命线——用户一边看输出一边想打字,卡了 = 产品不可用”。

2.3 无障碍 4 项实操(“4 项”)

项检查方式不合格示例
语义标签语义对(button 不是 div onClick;label 关联输入;nav/main 地标)全 div 堆出来的"按钮"(读屏读不出)
键盘只用 Tab/Shift+Tab/Enter/Space 走完整流程AI 停止按钮 tabIndex 到不了
焦点:focus-visible 可见 + 顺序合理焦点是默认细框看不见
对比文本 ≥ 4.5:1(大字 3:1)灰字 #999 on #fff ≈ 2.8:1

键盘走查 5 步(“10 分钟做完”):

① Tab 到搜索框 → 输入 → Enter(能提交?)
② Tab 走表单 → 每个输入框 label 能读出来?
③ Tab 到 AI 停止/重试按钮 → Space 能触发?
④ 模态框打开后焦点是否被"锁"在里面?关闭后焦点回到触发按钮?
⑤ 页面跳转后焦点回到顶部?

AI 产品无障碍清单(“高频扣分点”):

  • 流式输出的停止按钮键盘可达(“这是 AI 产品特有项”);
  • 结果可复制/可编辑(读屏用户要能改);
  • 错误提示不只靠颜色(红字 + 文字"失败"双通道);
  • 骨架屏/加载态有 aria-live(读屏能播报"正在生成")。

记忆锚:“语义焦点对比键盘,四点五是线;AI 加两条:停止可 Tab,状态能播报”。

🧠 记忆工具箱

口诀速记

  • 指标:“LCP 二点五 INP 二百 CLS 一毛”;
  • 五招:“分割懒图字体换,长任务丢 Worker,依赖砍一砍”;
  • 流式:“虚拟化攒批刷,预留高度别跳,停止要能真中断”;
  • 无障碍:“语义焦点对比键盘,四点五是线;AI 加停止可达 + 状态播报”。

场景锚点

  • 性能预算想象"“修路”":你不是司机(不需要赶路),你是"修路的"——“LCP = 从家到目的地总时长(2.5 分钟内);预算分配 = 每段路限时(哪段超了就修哪段);代码分割 = 别在市区建超宽大道(首屏只修需要的路段);长任务拆分 = 别让一辆大货车堵死三车道(主线程别卡)”——“修路不是越宽越好,是按预算把最堵的段先修好”。
  • 无障碍想象"“餐厅给轮椅顾客设计动线”":你不是顾客(不需要吃饭),你是"无障碍设计师"——“键盘 = 轮椅(只能走通道,按钮必须在通道上);焦点可见 = 轮椅能’看见’自己到哪了;对比度 = 菜单字够大够清楚;语义标签 = 菜单按’凉菜/热菜’分区(读屏像’按区找菜’)”——“只考虑步行顾客的设计 = 一半客人进不来”。

⚠️ 易错提醒

  • 性能"只优化首屏" = 不够:“INP 看交互,流式输出时打字不能卡”(“AI 产品 INP 权重更高”);
  • “停止按钮假中断” = 体验事故:“AbortController 真中断,或至少 UI 立即响应”(“点了没反应 = 用户以为坏了”);
  • 无障碍"补 alt 就完事" = 不及格:“键盘走查 + 焦点 + 对比度全过才算”(“评审会真的用键盘点一遍”);
  • CLS"图片没给宽高" = 经典来源:"width/height 或 aspect-ratio 必须给"。