CPU负载监控听起来像是运维平台的活儿,但随着浏览器能力的开放,前端页面自己也能感知到系统的实时压力了。Compute Pressure API正是这样一组接口,它把当前CPU负载抽象成nominal、fair、serious、critical四个等级,通过回调的方式推送给页面。拿到这个数据之后,我们能做的事情很多,比如在压力升高时自动关闭特效、降低轮询频率、切换轻量渲染路径。本文以jQuery为例,演示如何封装这个API并落地一套UI降级方案。

Compute Pressure API的核心概念与浏览器支持情况
Compute Pressure API目前处于W3C草案推进阶段,在Chrome 125及以上版本中默认可用。它的核心对象是PressureObserver,用法与PerformanceObserver比较接近:先创建观察器并传入回调,再调用observe方法指定要观察的数据源,目前唯一支持的数据源是cpu。
回调收到的对象包含两个字段:state表示当前压力等级,取值为nominal(低负载)、fair(中等)、serious(偏高)、critical(临界)四档;time是时间戳。需要注意的是,浏览器对回调触发有采样间隔限制,最短间隔通常为1秒左右,所以它天然就是节流过的,不需要我们再做复杂去抖。
兼容性处理是绕不开的话题。Firefox和Safari目前尚未原生支持该API,所以特征检测必须放在第一步,判断window上是否存在PressureObserver构造函数。检测失败时直接走默认的完整体验,不影响功能可用性。
用jQuery封装压力监听器
直接在业务代码里裸写原生API会让逻辑散落各处,用jQuery封装成一个小组件更符合传统项目的组织方式。下面的代码把监听器挂在一个jQuery插件上,内部完成特征检测、等级映射和事件分发。
(function ($) {
// 压力等级到权重的映射,数值越大压力越高
var LEVEL_WEIGHT = {
nominal: 0,
fair: 1,
serious: 2,
critical: 3
};
$.fn.pressureWatch = function (options) {
var settings = $.extend({
onNominal: $.noop,
onFair: $.noop,
onSerious: $.noop,
onCritical: $.noop,
onChange: $.noop
}, options);
return this.each(function () {
var $root = $(this);
// 特征检测:不支持的浏览器直接跳过,保持默认体验
if (typeof window.PressureObserver === 'undefined') {
console.warn('当前浏览器不支持 Compute Pressure API');
return;
}
var observer = new PressureObserver(function (records) {
var latest = records[records.length - 1];
var state = latest.state;
var weight = LEVEL_WEIGHT[state] || 0;
// 按等级分发到对应回调
if (state === 'nominal') settings.onNominal.call($root[0], state);
if (state === 'fair') settings.onFair.call($root[0], state);
if (state === 'serious') settings.onSerious.call($root[0], state);
if (state === 'critical') settings.onCritical.call($root[0], state);
settings.onChange.call($root[0], state, weight);
});
// 第二个参数为采样间隔,单位毫秒,最小有效值为1000
observer.observe('cpu', { sampleInterval: 2000 });
// 把observer挂在元素数据上,方便后续取消监听
$root.data('pressureObserver', observer);
});
};
})(jQuery);这个插件的设计思路是:每次压力状态变化时,把当前等级同时传给具体等级的回调和统一的onChange回调。前者适合针对某个等级做精细处理,后者适合做全局的权重判断,比如"只要达到serious就降级"这类逻辑。observer实例存在jQuery的data里,需要停止监听时取出调用disconnect即可。
还要注意一个细节:sampleInterval并不是越小越好。设置成1000毫秒意味着每秒最多收到一次回调,如果页面本身逻辑较重,建议放宽到2000毫秒以上,避免监控本身成为负担。
基于压力等级的UI降级策略实战
监听只是手段,降级才是目的。实际项目中比较实用的降级手段有这么几类:关闭CSS动画与过渡、停掉轮播和视频自动播放、把动态图表切换为静态快照、减少并发请求数。下面用一个完整例子演示如何组合这些策略。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
.decorated .banner {
animation: float 3s ease-in-out infinite;
transition: box-shadow .4s;
}
.decorated .chart { display: block; }
.decorated .chart-static { display: none; }
body.lite .banner { animation: none; transition: none; }
body.lite .chart { display: none; }
body.lite .chart-static { display: block; }
</style>
</head>
<body class="decorated">
<div class="banner"></div>
<div class="chart"></div>
<img class="chart-static" src="/static/chart-snapshot.png" alt="图表快照" />
<span id="pressure-state">nominal</span>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
$(function () {
$(document).pressureWatch({
onChange: function (state) {
$('#pressure-state').text(state);
// serious以上进入降级模式,nominal时恢复
if (state === 'serious' || state === 'critical') {
$('body').removeClass('decorated').addClass('lite');
// 顺手停掉视频自动播放
$('video.autoplay').each(function () {
this.pause();
});
} else if (state === 'nominal') {
$('body').removeClass('lite').addClass('decorated');
}
}
});
});
</script>
</body>
</html>这套方案的关键在于用CSS类切换代替逐个修改元素,降级开关集中在body一个类名上,样式内部自行决定隐藏什么、简化什么。这样做的好处是降级逻辑和视觉表现解耦,后续新增可降级元素只需要加几条CSS规则,jQuery侧的判断完全不用动。
另一个容易踩的坑是状态抖动。系统压力在serious和fair之间来回横跳时,页面会频繁切换样式,反而造成额外渲染开销。解决办法是加一层滞回判断:只有连续两次都处于高压力才触发降级,连续两次回到nominal才恢复。可以在插件外用一个简单计数器实现,成本很低但效果明显。
降级兜底与监控数据的进一步利用
对于不支持Compute Pressure API的浏览器,不能让降级能力直接失效。一个实用的兜底思路是采集前端自身的性能指标,比如用requestAnimationFrame统计帧率,连续数秒平均帧率低于40就视同serious等级,手动触发同一条降级路径。这样无论API是否可用,降级入口都是统一的。
function watchFpsAsFallback(onHighPressure, onRecover) {
var frames = 0;
var last = performance.now();
var lowCount = 0;
function loop(now) {
frames++;
if (now - last >= 1000) {
var fps = frames;
frames = 0;
last = now;
if (fps < 40) {
lowCount++;
if (lowCount >= 3) { onHighPressure(); lowCount = 0; }
} else {
lowCount = 0;
onRecover();
}
}
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
}此外,压力数据本身也是很有价值的运行时信息。可以把每次等级变化上报到后端日志,按地区、机型做聚合分析,找出真实的低端用户占比,反过来指导哪些特效从一开始就不该上。相比实验室里的性能测试,这种线上真实负载数据的说服力要强得多。
总结一下整体链路:PressureObserver负责感知,jQuery插件负责封装与分发,CSS类负责执行视觉降级,帧率兜底负责覆盖不支持的浏览器。四层各司其职,改动成本从内到外递增,即使以后迁移到其他框架,这套分层思路也能原样保留。
jQueryCompute Pressure APICPU负载监控修改时间:2026-09-16 14:26:40