摘要
长期维护最容易陷入两个误区:看到视觉问题就叠加 CSS,看到卡顿就删除动画。本站多轮演进表明,可靠修复需要“复现—最小化—假设—测量—修复—回归保护”的闭环。本文以移动宽度、目录锚点、壁纸性能和发布状态为案例,给出面向新手但可重复执行的维护方法。
关键词: 故障诊断;根因分析;性能分析;维护记录;回归
1. 维护不是连续打补丁
一个视觉现象可能跨越多层:文章被裁切可能来自网格子项最小宽度、正文宽内容和全局 overflow 的共同作用;动画卡顿可能来自实时模糊、图片解码和 SVG 绘制叠加。只改最后看到的属性,往往把问题移动到另一设备。
本站采用的诊断闭环是:
flowchart LR A[稳定复现] --> B[缩小变量] B --> C[提出可证伪假设] C --> D[工具测量] D --> E[最小根因修复] E --> F[自动与人工回归] F --> G[维护证据]
2. 案例一:移动文章横向裁切
2.1 现象
窄屏文章标题与正文右侧被截断。给页面加 overflow-x: hidden 能隐藏横向滚动条,却没有恢复被裁掉的内容。
2.2 根因方法
沿包含块从外向内检查网格、正文、.prose 与宽内容组件,确认哪些元素拒绝收缩。修复应让网格子项具有 min-inline-size: 0,标题可正常换行,代码、表格和公式只在自己的边界处理溢出。
2.3 防复发
在 320 与 390 像素视口验证 scrollWidth === clientWidth,同时确认宽代码仍能局部访问。前者防页面溢出,后者防“为了无滚动而裁内容”。
3. 案例二:目录与标题锚点不一致
3.1 现象
目录看得到标题,但刷新深链接或点击自链接可能落不到同一位置。
3.2 根因方法
检查构建期 Rehype 已生成的 ID,发现客户端若再次按自己的规则生成 slug,就会在重复标题和中文标点上分叉。修复是保留既有 ID,只为确实缺失 ID 的标题产生唯一后备值。
3.3 防复发
单元测试输入已有 ID、重复标题和无 ID 标题,断言目录、自链接与外部深链接使用同一锚点。
4. 案例三:动画保留但运行更轻
4.1 现象
主页视觉效果完整,但滚动和壁纸展开在部分桌面浏览器上不顺滑。单纯缩短动画会更突兀,删除波浪则损害设计目标。
4.2 测量与修复
Performance trace 将问题定位到全屏快照、实时模糊、SVG 内部动画与重复逐帧计算。后续改为单一进度、预计算几何、外层 transform、按生命周期暂停波浪,并在需要时才准备高清图。
历史记录显示,在当时 CPU×4 的测试环境中,优化后壁纸动画 p95 帧时间约 5.7ms、Long Task 为 0。这里重要的不是数字本身,而是“保留效果、改变执行路径”的方法。
4.3 防复发
视觉契约禁止高频布局属性动画;逻辑测试覆盖反向和取消;真实 trace 检查 Layout、Paint、Long Task 与帧分布。
5. 案例四:部署时间不等于当前时间
5.1 现象
状态卡显示最近部署时间,用户却将其理解为当前本地时间或页面刷新时间。
5.2 根因方法
首先确认数据来源:仓库提交、Pages deployment、Worker 缓存还是浏览器显示。展示层应说明状态语义和观测时间;刷新按钮应发起一轮明确检查,并让并发调用共享请求。
5.3 防复发
测试请求去重与失败降级;界面文案避免“实时”等无法保证的表达。外部服务不可用时保留静态页面功能。
6. 如何书写维护记录
有效记录至少包含:用户可见现象、复现条件、根因证据、修改文件、验证命令、未解决边界和对应提交。不要只写“优化性能”或“修复样式”,因为下一位维护者无法判断方案是否仍适用。
Beads 用于当前任务状态与依赖,仓库文档用于长期架构和性能证据,Git 历史用于版本事实。三者职责不同,不能用临时 Markdown TODO 代替任务跟踪,也不能用任务状态代替代码说明。
7. 面向新手的维护流程
- 用最小路径稳定复现,不同时修改多个假设。
- 读取当前代码与配置,拒绝根据旧截图猜实现。
- 用浏览器面板、测试或构建输出收集可验证证据。
- 优先修复状态模型和职责边界,再调视觉参数。
- 运行全量门禁并检查差异中是否混入无关改动。
- 部署后用对应提交的线上页面复核。
- 把昂贵问题沉淀为契约测试或维护文档。
8. 局限与结论
证据驱动并不意味着必须为每个像素建立自动测试。审美判断仍需要真实页面,人机交互也需要设备体验。它要求的是:事实与偏好分开、现状与计划分开、一次测量与普遍结论分开。由此,网站维护才从“不断救火”转化为可学习、可复现、可持续改进的工程过程。