为什么要做性能优化 #
其实可以从两个视角来看:
- 正向视角,性能优化能够带来业务转化,比如:优化页面打开时间,下单转化率提升
- 负向视角,性能优化能够避免用户流失,比如:性能不佳会持续消磨用户耐心,具体来说就是加载缓慢、交互卡顿、页面白屏等问题会导致用户逐渐流失,同时影响口碑,降低新用户转化。
性能的量化 #
业界通用指标 #
一般业界会采用 google 设计的 Core Web Vitals 体系,包括 LCP、INP、CLS 等指标来衡量性能。

Largest Contentful Paint (LCP):衡量加载性能。为了提供良好的用户体验,应在网页首次开始加载的 2.5 秒内完成 LCP。 Interaction to Next Paint (INP):衡量互动性。为了提供良好的用户体验,网页的 INP 应不超过 200 毫秒。 Cumulative Layout Shift (CLS):衡量视觉稳定性。为了提供良好的用户体验,网页的 CLS 应保持在 0.1 或更低。
为确保大多数用户都能达到这些指标的建议目标值,一个合适的衡量阈值是网页加载时间的第 75 个百分位数,并按移动设备和桌面设备进行细分。 如果网页在所有三个 Core Web Vitals 指标的第 75 百分位处达到建议的目标,则评估 Core Web Vitals 合规性的工具应将其视为通过测试。
以上是官方的介绍,具体来讲就是:
- LCP 指的是 Largest Contentful Paint,即最大内容绘制时间,衡量的是页面主要内容加载速度,即用户“感觉页面是不是出来了”。
- 这里说的最大内容,是指渲染在视口中 面积最大的内容元素 ,它完成渲染的时间就是LCP。
- INP 指的是 Interaction to Next Paint,即下次绘制的交互延迟,衡量的是用户和页面互动时的延迟——比如点击按钮、输入框打字等。
- 这里说的延迟,是指从用户操作到页面下一次渲染完成的时间间隔,即交互响应速度。
- CLS 指的是 Cumulative Layout Shift,即累计布局偏移,衡量的是页面在加载过程中布局跳动的程度。
- 例如:
- 图片加载晚导致文字突然被挤下去
- 广告突然插入页面让内容跳动
- 字体加载切换导致布局变化
- 例如:
那这三个值又是如何计算的呢? #
- LCP
其计算分为以下几步:
- 浏览器会监听页面中可能成为 LCP 的元素
- 包括:img、video 的 poster、有 background-image 的 block 元素、大文本块(基于渲染面积)
- 每当「一个候选元素被渲染」或「变更大小」时,浏览器重新判断:
- 当前视口中 面积最大的内容元素 是哪一个?
- LCP 的值 = 这个最大元素完成渲染的时间点
- LCP = 该元素完成绘制的时间(相对 navigationStart),包括:内容下载完成、解码完成、实际绘制到屏幕(paint)
- INP
INP = 所有交互事件的 最大(或近似最大)延迟
浏览器监控三类事件:
- click、tap
- pointer events
- keyboard input
对于每次事件,浏览器记录三段时间:
- Input delay(输入延迟):事件触发 → JS 事件监听器开始执行
- Processing delay(处理延迟):JS 事件处理函数执行时间
- Presentation delay(呈现延迟):JS 执行完成 → 下一帧内容绘制完成
即:单次交互延迟 = Input Delay + Processing Delay + Presentation Delay
INP 的最终值计算方式:
- 浏览器不会拿“所有事件的最大值”,避免一次偶发卡顿打爆数据。
- 而是:使用 99th percentile(99 百分位值) 或最长的那一小部分事件。
最终:INP = 所有交互事件延迟中的 99 百分位
所以它代表你页面中“卡得最严重的一次(或几次)交互”。
- CLS
CLS = 所有 layout shift 的得分累加。
一个布局偏移分数的计算如下: Layout Shift Score = Impact Fraction × Distance Fraction
下面解释 2 个参数:
(1)Impact Fraction:影响区域比例
影响区域 = 偏移前区域 ∪ 偏移后区域
比如:
- 一个 div 往下跳了 100px
- 它占屏幕高度 20%
影响区域可能是:该 div 原位置 + 变化后的区域
Impact Fraction = 影响区域面积 / 视口面积
(2)Distance Fraction:移动距离比例
即元素移动了屏幕的多少比例:Distance Fraction = 元素移动距离 / 视口高度
(3) CLS 单次偏移得分 = Impact × Distance
然后浏览器将 多个偏移事件的得分不断累加:
CLS = Σ(每一次 layout shift 的得分)
但:
- 在 1 秒内
- 且连续的偏移事件
- 会组成 “session window”
CLS 最终采用的是所有 session window 中最大的一个。
最后补充几点:
- 对于LCP,浏览器会不断更新,直到用户第一次交互或页面进入 stable 状态
- 对于每次交互事件,INP都可能发生变更
- 对于每次布局(位移和尺寸)变化,CLS 会计算一次得分并累加
官方说的第 75 百分位表示什么意思 #
比如你收集了100个用户的LCP、INP、CLS数据,按照从小到大的顺序排列,第75个值就是第 75 百分位,如果这个值小于等于建议的目标值,那说明当前网站的性能是健康的。
FCP #
除了以上 3 个指标,还有一个指标是 FCP(First Contentful Paint),它指的是页面首次绘制任何内容的时间。

为了提供良好的用户体验,网站应尽量将首次有意义的绘制时间控制在 1.8 秒或更短的时间。为确保大多数用户都能达到此目标值,一个合适的衡量阈值是网页加载时间的第 75 个百分位数,并按移动设备和桌面设备进行细分。
基于上面的描述,其实可以简单把 FCP 作为白屏的一种参考指标,但是它并不能完全代表白屏时间,比如有些页面可能会通过 skeleton 来作为过渡,这种状态下,用户其实也会认为是一种白屏状态。
自定义业务指标 #
虽然业界已经有了较权威的 Core Web Vitals 指标,但是在实际业务场景中,可能并不能反映真实情况。
举一个商品列表的例子,它的加载流程是这样的:
- 加载页面资源
- 渲染背景图
- 加载商品列表数据
- 渲染商品列表
在这个过程中,我们核心的视图其实是商品列表,而不是背景图。但是,因为背景图非常大,它会直接触发LCP,导致数据上报不准确。
为了解决这个问题,我们需要在商品列表加载完成后,手动触发LCP的上报。
- 如果我们是 vue 项目,那可以在 mounted 钩子中触发
- 如果是 react 项目,那可以在 useEffect 中触发(依赖项为空数组)
不同的业务场景,可能需要上报🛫的指标也不同。
性能数据上报与统计 #
对于业界通用指标,主要涉及到两块:
- performance API
- web vitals sdk
性能数据分析 #
OK,性能如何量化以及如何衡量我们大概知道了,那接下来就需要根据这些指标来分析我们的性能瓶颈。
一般我们可以从两个视角出发:
宏观视角 #
- 空间差异:不同的地区、场所下,性能可能存在差异,比如:地下停车场的网络信息不好,导致性能较差。
- 时间差异:流量高峰期、大促、拉新活动等时期,服务器的抗压性若较弱,性能可能较差。
- 内容差异:营销页往往会包含很多图片、视频素材,导致拖慢性能。
统计视角: #
- 100分位:一般100分位的数据可能都是极端数据,所以我们一般不采用。
- 90分位:90分位能够反映大部分用户访问时的性能水平。
- 75分位:相比于90分位,更加稳健,因为90分位还是可能存在一些极端数据。这也是 web core vitals 的建议值。
- 50分位:特别稳健,完全不受极端数据影响。但是,不能反映绝大部份的性能情况。
- 平均值:计算比较简单,容易受极端数据影响,基本无法反映真实性能情况。
所以,在宏观视角的前提下,一般情况下,我们会在 90 分位、75分位间选择。虽然我日常的性能优化工作主要涉及的是小程序,指标也基本上参考小程序官方的指标设计,但我觉得前期可以采用 75 分位,后期再采用90分位,即分为两个阶段:
- 前期做到性能可接受:75分位
- 后期做到性能尽量极致:90分位
性能优化的常见抓手 #
网络连接阶段 #
- http2/http3:
- 基于http2.0的二进制传输、多路复用、头部压缩,一方面提高了解析、传输效率,另一方面解除了并发请求限制,我们不再需要把一些小图片转成base64格式。
- 当然,http2.0仍然存在队头阻塞,即一个请求流的包丢失了,会阻塞所有请求流。
- http3.0基于quic协议,该协议底层基于udp,解决了连接级的队头阻塞问题,即一个流的包丢失只会阻塞该流,其他流不受影响。
- DNS预解析:
- 使用
<link rel="dns-prefetch" href="//example.com">告知浏览器提前进行 DNS 解析,将域名转换为 IP 地址,减少用户点击链接时的 DNS 查询延迟。
- 使用
- TCP预链接:
- 使用
<link rel="preconnect" href="//example.com">告知浏览器提前与目标服务器建立连接,包括 DNS 解析、TCP 握手和 TLS 协商(如果是 HTTPS),进一步减少后续请求的延迟。
- 使用
- keep-alive:
- HTTP 持久连接(Persistent Connection),允许在同一个 TCP 连接上发送和接收多个 HTTP 请求/响应,避免了每次请求都重新建立 TCP 连接(三次握手)和 TLS 握手的开销。
- 减少重定向:
- 每次重定向都会触发一个新的 HTTP 请求,增加至少一个 RTT(往返时延),严重影响页面加载速度,尤其是在移动网络环境下。应尽量避免不必要的 301/302 重定向。
- CDN加速:
- 内容分发网络(Content Delivery Network),将静态资源缓存到离用户最近的边缘节点。用户请求时可直接从最近的节点获取资源,大幅降低网络延迟和丢包率,同时减轻源站压力。
首次请求 #
- Gzip/Brotli压缩:
- 开启 HTTP 压缩可以显著减少 HTML、CSS 和 JavaScript 等文本资源的传输体积。Brotli 是比 Gzip 更新的算法,通常能提供更高的压缩率(约 20%),大多数现代浏览器都已支持。
- Early Hints 103:
- 一个 HTTP 状态码,允许服务器在生成最终 HTML 响应(200 OK)之前,先发送一个包含 Link 头部的 103 Early Hints 响应。这让浏览器可以在服务器还在处理主请求时,就开始预加载关键资源(如 CSS、JS),利用了服务器思考的时间(Server Think Time)。
- 流式SSR(Streaming SSR):
- 传统的 SSR 需要等待整个 HTML 页面在服务端生成完毕后才一次性发送给客户端。流式 SSR 允许服务端生成一部分 HTML 就立即发送一部分,浏览器可以边下载边解析渲染。这能显著降低 TTFB(Time To First Byte)和 FP(First Paint),让用户更快看到页面内容。
资源加载 #
- 代码体积优化:
- TreeShaking:移除 JavaScript 上下文中未引用的代码(Dead Code)。
- 代码分割(Code Splitting):将代码分离到不同的 bundle 中,然后可以按需加载或并行加载这些文件。
- 代码压缩混淆:
- 移除代码中的空格、注释、换行符,并缩短变量名,从而减小文件体积。混淆还能增加代码被逆向工程的难度。
- 图片体积优化:
- 格式选择:优先使用 WebP 或 AVIF 等现代图片格式,它们在相同质量下通常比 JPEG/PNG 体积更小。
- 压缩:使用工具(如 TinyPNG, ImageOptim)去除图片元数据并进行有损/无损压缩。
- 响应式图片:使用
srcset和sizes属性,根据设备屏幕大小加载合适尺寸的图片。
- 字体裁剪(Font Subsetting):
- 只保留页面实际使用到的字符(如仅保留中文常用字或特定标题字符),极大地减小字体文件体积(中文字体文件通常很大)。
- HTTP缓存:
- 强缓存(Cache-Control/Expires):浏览器直接从本地缓存读取资源,不向服务器发送请求(状态码 200 from disk/memory cache)。
- 协商缓存(Last-Modified/ETag):浏览器发送请求询问服务器资源是否更新,如果未更新,服务器返回 304 Not Modified,浏览器继续使用本地缓存。合理搭配使用可大幅减少网络流量。
- 资源、路由、组件,预加载/懒加载:
- 资源预加载(Preload/Prefetch):
preload:<link rel="preload">告诉浏览器立即加载当前页面必需的关键资源(如字体、首屏大图),优先级高。prefetch:<link rel="prefetch">利用浏览器空闲时间下载将来(如下一个页面)可能用到的资源,优先级低。
- 路由懒加载:
- 利用打包工具(Webpack/Vite)的代码分割功能,将不同路由对应的页面组件拆分成独立的代码块(Chunk),仅在用户访问该路由时才加载对应的 JS/CSS 文件,是单页应用(SPA)优化的标配。
- 组件懒加载:
- 特别适用于 弹窗(Modal)、抽屉(Drawer)、复杂的下拉菜单 等非首屏立即展示的交互组件。
- 原理:通过动态
import()语法将这些组件的代码从主包中分离。只有在用户触发特定操作(如点击打开按钮)时,才发起网络请求加载代码。这能显著减小首屏 JS 体积,加快首屏 TTI(Time to Interactive)。
- 资源预加载(Preload/Prefetch):
- Service Worker、离线包、静态资源预热:
- Service Worker:
- 核心原理:它像一个驻留在浏览器后台的“中介”或“代理服务器”,独立于当前页面运行。
- 实战配置与性能优化(推荐使用 Workbox):
- 预缓存(Precaching):在构建时自动将核心资源(HTML Shell、关键 JS/CSS)加入预缓存列表。应用启动时直接从本地 Cache Storage 读取,实现秒开和离线访问。
- 运行时缓存策略(Runtime Caching):
CacheFirst(缓存优先):适用于图片、字体等不常变的静态资源。一旦缓存,后续请求直接走本地,完全不消耗网络。StaleWhileRevalidate(看旧更变新):适用于头像、新闻列表等。优先返回本地旧数据让页面快速显示(不留白),后台同时发起网络请求更新缓存,下次访问即为最新。NetworkFirst(网络优先):适用于 HTML 主文档或关键 API。优先尝试获取最新数据,网络失败时才降级使用本地缓存兜底。
- 离线包(Offline Package):
- 常见于 Hybrid App(混合应用)。将 HTML/CSS/JS/图片等静态资源打包并内置在 App 客户端中。当用户打开 WebView 时,直接从本地文件系统加载资源,无需通过网络下载,实现秒开体验。
- 静态资源预热(Resource Hinting / Warm-up):
- 这里的“预热”可以指在 WebView 初始化之前提前启动浏览器内核,或者在用户点击链接前提前建立连接(Preconnect)和下载资源(Prefetch)。在服务端层面,CDN 节点也可以进行缓存预热,将源站资源提前推送到边缘节点,避免用户首次请求回源。
- Service Worker:
页面解析 #
- 减少 DOM 深度:
- DOM 树过深会增加内存占用,导致样式计算(Recalculate Style)和布局(Layout/Reflow)变慢。应尽量扁平化 HTML 结构,使用 Flexbox/Grid 布局代替多层 div 嵌套。
- 关键 CSS 内联(Critical CSS):
- 将首屏渲染必须的 CSS 直接写在
<style>标签内放在<head>中。这样浏览器下载完 HTML 就能立即渲染首屏,无需等待外部 CSS 文件下载,消除渲染阻塞(Render Blocking)。
- 将首屏渲染必须的 CSS 直接写在
- script异步加载:
async:脚本下载完立即执行,执行顺序不确定,适合独立的统计脚本。defer:脚本并行下载,但会等到 HTML 解析完成后,按在 HTML 中出现的顺序执行。推荐用于业务逻辑代码,因为它不会阻塞 HTML 解析器构建 DOM 树。
- 减少解析阻塞:
- JS 和 CSS 都会阻塞渲染。除了使用 async/defer(仅仅针对script),还应将非关键 CSS(如打印样式)通过 media 或者 preload 进行控制。
- 避免强制同步布局(Forced Synchronous Layout):
- 浏览器通常会批量处理 DOM 修改以优化性能。但如果你在修改 DOM 后立即读取布局属性(如
offsetHeight),浏览器为了返回准确值,不得不立即触发布局计算(Reflow)。 - 优化:读写分离,先批量读取所有需要的数据,再批量写入 DOM。
- 浏览器通常会批量处理 DOM 修改以优化性能。但如果你在修改 DOM 后立即读取布局属性(如
- CSS选择器优化:
- 浏览器匹配 CSS 选择器是从右向左进行的。虽然理论上减少层级和避免通配符能提升性能,但在现代浏览器引擎优化下,差异已微乎其微。
- 建议:关注代码的可维护性(如使用 BEM 规范、Tailwind CSS)远比过度纠结选择器性能重要。避免使用过于复杂的
:nth-child或深层嵌套即可。
首屏渲染 #
- SSR (Server-Side Rendering) / SSG (Static Site Generation):
- SSR:服务器实时生成 HTML 返回给客户端,首屏内容立即可见,SEO 友好。适合动态内容。
- SSG:构建时生成静态 HTML,部署在 CDN 上。访问速度最快,但只适合内容不常变动的页面(如博客、文档)。
- 模板化创建:
- 在客户端渲染(CSR)中,避免使用 JS 逐个创建 DOM 节点。直接使用 HTML 模板字符串或
<template>标签批量插入,减少 DOM 操作次数。
- 在客户端渲染(CSR)中,避免使用 JS 逐个创建 DOM 节点。直接使用 HTML 模板字符串或
- 关键渲染路径(Critical Rendering Path)优化:
- 缩短从 HTML 接收到像素绘制到屏幕的过程。核心是消除阻塞资源(CSS/JS),让浏览器尽快构建出 Render Tree。
- 骨架屏(Skeleton Screen):
- 在数据加载完成前,先展示页面的大致结构(灰色占位块)。虽然不能加快实际加载速度,但能显著降低用户的心理等待时间,提供更好的感官体验。
- 渐进式渲染(Progressive Rendering):
- 分优先级:优先渲染视口内(Above the Fold)的核心内容,视口外的模块延迟渲染。
- 分层:先渲染低清占位图,加载完后再替换为高清图。
- 优化 LCP 元素(Largest Contentful Paint):
- 确保页面中最大的内容元素(通常是大图或 H1 标题)尽早渲染。
- 手段:对 LCP 图片使用
<link rel="preload">预加载,并确保该图片没有被懒加载(Lazy Load)。
异步数据请求 #
- 接口合并/拆分:
- 合并:在 HTTP/1.1 时代,为了减少 TCP 连接建立的开销,通常将多个小接口合并为一个大接口(BFF 层常做此事)。
- 拆分:在 HTTP/2 多路复用环境下,或者为了避免首屏被慢查询阻塞,可以将一个聚合大接口拆分为核心数据接口(快)和非核心数据接口(慢),让核心内容先展示。
- 请求并发控制:
- 对于http1.1,浏览器对同一域名的并发请求数有限制(通常是 6 个)。如果有大量请求同时发起,会导致后续请求排队等待(Stalled)。可以通过实现一个并发调度器(Scheduler)来控制同时发起的请求数量。
- 接口缓存策略:
- 可以在 HTTP 头中设置
Cache-Control,或者在前端代码层(如 Axios 拦截器、React Query)实现内存缓存。对于一段时间内不变的字典数据、配置数据,直接使用缓存。
- 可以在 HTTP 头中设置
- 数据预拉取(Prefetching):
- 在用户进行某些操作(如鼠标悬停在菜单上)时,预测用户即将访问的内容,提前发起 API 请求。像我们之前对小程序的优化中,我们在点击跳转到另一个页面时,会提前请求接口,将数据保存到global中,当进入下一个页面,且global中已经拿到了数据,则直接使用预请求的数据。
- 请求去重:
- 避免在短时间内对同一个 URL 发起多次重复请求(例如用户快速点击按钮)。可以通过loading状态、防抖、节流等方式来避免。当然也可以通过请求锁的形式来实现,即每次请求前先判断是否有正在进行的请求,如果有,则等待,等正在进行的请求完成后,再用之前的结果,这种一般用于数据不经常变化的场景。
- 离线数据缓存:
- 将 API 数据存入 IndexedDB 或 localStorage。当网络断开或弱网时,优先展示本地存储的旧数据(Stale Data),提示用户当前处于离线模式。
- SSE (Server-Sent Events) / WebSocket:
- 对于实时性要求高的数据(如股票、聊天),传统的轮询(Polling)效率极低。
- SSE:基于 HTTP 的单向通信(服务端推送到客户端),轻量级,适合消息通知。
- WebSocket:基于 TCP 的全双工通信,适合高频交互场景。
数据渲染 #
- 虚拟滚动(Virtual Scrolling):
- 当需要展示成千上万条数据(如长列表)时,只渲染用户视口(Viewport)可见范围内的 DOM 元素。随着滚动动态复用或替换这些节点,保持 DOM 数量恒定,避免浏览器因 DOM 过多而卡顿。
- 分页/无限滚动:
- 分页:传统 Web 常见的方案,明确告知用户数据总量,按需跳转。
- 无限滚动:移动端常见方案,滚动到底部自动加载下一页。需要注意内存控制,避免加载过多导致页面崩溃(通常需配合虚拟滚动)。
- 数据分批渲染(Time Slicing):
- 如果一次性要渲染大量数据(且无法使用虚拟滚动),可以将数据拆分成多个小批次(Chunk),利用
requestAnimationFrame或requestIdleCallback分帧渲染。这样可以避免主线程长时间阻塞,保证页面还能响应用户交互。
- 如果一次性要渲染大量数据(且无法使用虚拟滚动),可以将数据拆分成多个小批次(Chunk),利用
- 增量更新:
- 仅更新发生变化的数据部分,而不是重新渲染整个列表或组件。现代前端框架(React/Vue)的 Diff 算法就是为了实现这一点,但在业务逻辑层面也应注意只传递变更的数据。
- 组件缓存:
- React:使用
React.memo避免父组件更新导致无关子组件的重复渲染;使用useMemo/useCallback缓存计算结果和函数引用。 - Vue:使用
<keep-alive>包裹组件,在组件切换(如 Tab 切换)时将状态保留在内存中,避免重复销毁和创建。
- React:使用
- 避免不必要的渲染:比如仅仅变更了 state A ,不要触发 state B 的重新渲染。
交互就绪 #
- 代码分割(Code Splitting):
- 将代码拆分为多个小块,按需加载。比如基于路由的分割,或者将第三方库(Vendor)单独打包。这样用户访问特定页面时,只需下载该页面所需的代码,减少首屏包体积。
- 懒加载(Lazy Loading):
- 对于非首屏可见的组件或模块,使用动态导入(
import())进行懒加载。等到用户交互(如点击按钮、滚动到特定区域)时再请求资源。
- 对于非首屏可见的组件或模块,使用动态导入(
- 减少 JS 执行时间:
- 移除未使用的代码(Tree Shaking)。
- 优化算法复杂度。
- 避免在主线程进行密集计算,防止阻塞渲染和交互。
- Web Worker:
- 将繁重的计算任务(如大文件解析、图像处理、复杂数据排序)移至后台线程运行,避免阻塞主 UI 线程,保持页面流畅响应。
- 长任务拆分(Long Task Splitting):
- 任何超过 50ms 的任务都会被视为长任务,可能导致页面卡顿。将长任务拆解为多个微任务或宏任务(使用
setTimeout、requestIdleCallback或scheduler.postTask),在任务间隙把控制权交还给浏览器,以便响应用户输入。
- 任何超过 50ms 的任务都会被视为长任务,可能导致页面卡顿。将长任务拆解为多个微任务或宏任务(使用
- 防抖(Debounce)与节流(Throttle):
- 防抖:高频触发事件(如搜索框输入)停止触发 N 毫秒后才执行函数。
- 节流:高频触发事件(如滚动、窗口缩放)在指定时间间隔内只执行一次。
- 两者都能有效减少昂贵的回调函数(如 DOM 操作、API 请求)的执行频率。
持续优化 #
- 意识增强
- 性能监控:数据采集、看板、报警
- 监督机制
- 经验再转化
性能优化常用策略 #
通常,我们可以基于一个原则:根据长期/短期目标,选择ROI合适的方案并渐进式优化
短期ROI #
普遍成本低,见效快,业务层几乎无改动,可通过配置/工程化实现
- http2/3、DNS预解析等
- Gzip/Brotli 压缩
- http 缓存策略
- tree shaking
- 内联关键css
- 代码压缩混淆
中期ROI #
成本相对高一些,业务层代码需要修改
- 图片、字体优化
- 代码分割,懒加载
- 首屏依赖治理
- 业务逻辑优化
- 骨架屏
- 离线数据缓存
长期ROI #
成本高,业务层代码可能需要重构才能实现
- 渐进式渲染
- SSR/SSG
- 数据预拉取
- Web Worker
- Early Hints
如何保持长期的性能稳定 #
其实就是抓手中的持续优化内容。
意识增强 #
这块可以通过设定责任人制度来强化,比如不同的模块分配给不同的人,并由一个主负责人来负责协调。
性能观察 #
性能观察可以分为三个部分:
- 数据上报收集
- 监控看板与报警通知
- 针对一些较明显的数据特征直接映射成某些case(随着沉淀的越多,映射的case也会越多)
监督机制 #
- 定期检查并同步
- 优化经验不断沉淀,并不断优化治理体系
经验再转化 #
- 通用共性优化方案
- 工具化:
- 构建期:与前端工程基建结合
- 运行时:收敛为运行时SDK
- 流程化:SOP + 检查校验
- 工具化:
- 业务领域逻辑优化
- 业务模板沉淀
- 业务领域SDK沉淀