ATRULE 技术博客ATRULE 技术博客
首页
博客
文档
关于
首页
博客
文档
关于
  • 技术文章

    • VuePress 2.x 完全指南
    • Gemini3 & GPT5 & DeepSeek3:AI时代程序员的身份转变
    • Agent 架构选型指南:单智能体 vs 多智能体
    • Agent 工程师转型学习路线图 (Full-Stack to Agent Engineer)
    • Agent 工程师学习笔记
    • 📖 Agent 系统架构与工程实践面试速记卡片
    • Agent 流式对话前端踩坑记录
    • RAG 检索工程问题记录
    • Agent 后端问题记录(Koa / MongoDB)
    • LLM 调用与 Agent 编排问题记录
    • Electron 桌面端问题排查记录
    • AI Agent 全栈开发问题排查记录
    • ES2026 与 TypeScript 进阶问题记录
    • 浏览器渲染与 V8 内存问题记录
    • React 19 与 Vue 4 新内核问题记录
    • 前端工程化与微前端问题记录
    • 性能、安全与可观测性问题记录
    • 前端架构实战问题记录
  • 项目实战

    • Node.js + Koa 抖音直播弹幕Agent 五大核心模块(面试项目完整版,TS技术栈)★★★★★
    • Poiclaw 项目蓝图:自主编程实体
    • AI旅行助手

性能、安全与可观测性问题记录

记录 Web Vitals 归因、安全攻防、监控 SDK 设计中踩过的坑,每个问题都是实际遇到过并解决掉的。

问题一:LCP 达标,INP 不达标

现象:LCP 1.8s 达标,INP P75 冲到 300ms+,用户反馈点击卡。

原因:输入发生时长任务正在占主线程——为 LCP 提前加载的大 JS/hydration 在交互时还没让出。

解决:按顺序修——① Performance 面板找 Long Task,用 scheduler.yield() 切片(输入可插队):while (tasks.length) { if (shouldYield()) await scheduler.yield(); doChunk(); };② 重计算挪 Worker(解析/压缩/diff);③ 减一次性 hydration 开销。注意切片拖慢总完成时间——牺牲吞吐换响应是显式取舍,用 INP P75 + 任务完成时间的对比数据自证净收益。

问题二:给 LCP 图加 preload,反而慢了 200ms

现象:<link rel=preload> 首屏大图,LCP 指标恶化。

原因:preload 的 URL 和实际渲染用的不一致(srcset 响应式图片)导致下载两次;或挤占了其他关键资源带宽;或优先级没提对。

解决:先做 LCP 子时段归因(TTFB / 资源发现延迟 / 加载时长 / 渲染延迟),卡在哪段修哪段。"资源发现延迟"长(CSS 链深层依赖)才用 preload;一般场景 fetchpriority="high" 打在 img 上更对症;preconnect 只给马上要用的跨域源。字体组合拳:preload + font-display: swap + size-adjust。

问题三:CSP 配了 nonce 还被 XSS

现象:script-src 'nonce-xxx' 上线后仍被注入执行。

原因:nonce/CSP 管脚本加载入口,管不住 DOM sink 注入——innerHTML = 恶意串 里的 <img onerror> 不需要新 script 标签。

解决:加 Trusted Types 把 innerHTML/eval 等 sink 改成只接受 TrustedHTML 类型,普通字符串直接抛错:

Content-Security-Policy: require-trusted-types-for 'script'; script-src 'nonce-xxx' 'strict-dynamic'

落地路径:report-only 灰度收 sink 清单 → 封装 createHTML 策略(DOMPurify 过滤)→ 三方库用隔离策略。富文本场景注意 mXSS:过滤后的 HTML 回填 DOM 再序列化可能变形绕过,要过滤后校验而不是只校验输入。

问题四:token 过期后 5 个并发 401,全链路登出

现象:access token 过期瞬间,页面 5 个请求各自触发 refresh,结果全部登出。

原因:刷新风暴——refresh token 轮转下旧的立即失效,后到的刷新用已作废的 token。

解决:单飞(singleflight)刷新 + 请求重放只允许一次:

let refreshInFlight: Promise<string> | null = null;

async function refreshOnce(): Promise<string> {
  if (refreshInFlight) return refreshInFlight; // 其余 401 等同一个 Promise
  refreshInFlight = fetch('/auth/refresh', { method: 'POST', credentials: 'include' })
    .then((r) => { if (!r.ok) throw new Error(); return r.json(); })
    .then(({ accessToken }) => accessToken)
    .finally(() => { refreshInFlight = null; });
  return refreshInFlight;
}

存储用内存 + HttpOnly Cookie(XSS 偷不走,CSRF 靠 SameSite=Strict 补);公共客户端授权走 OAuth 2.1 + PKCE;刷新失败广播登出事件并清理 in-flight 请求。

问题五:监控 SDK 接入后页面 FPS 掉了 5

现象:SDK 上线后性能监控自己成了性能问题。

原因:rrweb 全量录屏序列化、PerformanceObserver 回调风暴、同步上报阻塞 unload。

解决:分层采样(错误/慢请求全量,正常会话 1-5%);rrweb 只在错误会话开启;上报走 Worker 聚合压缩 + 攒批(3 秒或 20 条)+ sendBeacon(unload 不阻塞),>64KB 用 fetch keepalive 兜底——双通道会重复,事件带 uuid 服务端幂等去重;所有采集代码 try/catch、开关可远程下发一键关闭。

Prev
前端工程化与微前端问题记录
Next
前端架构实战问题记录