
本文介绍一种高效、无闪烁的 html 表格周期性更新方法:通过客户端时间戳与服务端增量校验结合,仅在数据实际变更时触发 dom 更新,并支持单请求批量获取多模块变更状态。
本文介绍一种高效、无闪烁的 html 表格周期性更新方法:通过客户端时间戳与服务端增量校验结合,仅在数据实际变更时触发 dom 更新,并支持单请求批量获取多模块变更状态。
在实时监控类页面(如聊天活跃度看板)中,频繁全量刷新多个独立区域(图表、表格、计时器等)不仅浪费带宽和服务器资源,还可能引发 UI 跳动、交互错位等不良体验。原方案使用 jQuery .load() 每 10 秒无差别重载全部
✅ 推荐架构:单请求 + 时间戳校验 + JSON 增量响应
替代多次独立 .load(),建议统一发起一个参数化 AJAX 请求,例如:
// 客户端维护各模块最后更新时间戳(毫秒)
let lastUpdate = {
graph: 0,
chat: 0,
watchers: 0,
time: 0
};
function fetchUpdates() {
const params = new URLSearchParams({
update: 'all4',
ts_graph: lastUpdate.graph,
ts_chat: lastUpdate.chat,
ts_watchers: lastUpdate.watchers,
ts_time: lastUpdate.time
});
fetch(`myscript?${params}`)
.then(r => r.json())
.then(data => {
// data 示例:{ graph: { html: "...", ts: 1715234567890 }, time: { html: "...", ts: 1715234567900 } }
Object.entries(data).forEach(([key, payload]) => {
if (payload && payload.html) {
const $el = $(`#${key === 'graph' ? 'concurrentChart' : key}`);
$el.fadeOut('fast', () => {
$el.html(payload.html).fadeIn('slow');
lastUpdate[key] = payload.ts || Date.now();
});
}
});
})
.catch(err => console.warn('Update failed:', err));
}
// 启动轮询(可缩短至 3–5 秒,因负载大幅降低)
setInterval(fetchUpdates, 5000);
✅ 服务端 PHP 改造要点(关键逻辑)
PHP 脚本需支持 update=all4 模式,并对每个模块执行「时间戳比对 → 有变更则生成 HTML + 新时间戳」:
if ($_GET['update'] === 'all4') {
$response = [];
$now = time();
// 统一数据库查询上下文(避免重复连接)
$dbCriteria = [
'minimumEpoch' => $_SESSION['minimumEpoch'],
'livestreamId' => null
];
// 每个模块检查:若客户端 ts latestChatViewerCountGraph(),
'ts' => time()
];
}
if (isset($_GET['ts_chat']) && $_GET['ts_chat'] latestChatsGetChatTable($dbCriteria),
'ts' => time()
];
}
// ... 同理处理 watchers、time
header('Content-Type: application/json');
echo json_encode($response);
exit;
}
? 提示:getXXXLastModified() 应从缓存(如 Redis)、数据库 updated_at 字段或内存状态中快速读取,严禁在此处执行全量 SQL 查询。
⚠️ 用户体验关键注意事项
-
布局稳定性优先:为防止内容更新导致下方元素跳动,务必为所有动态容器设置固定高度或最小高度(min-height),并启用 CSS contain: content 提升渲染性能:
#concurrentChart, #chats, #watchers, #currentTime { contain: content; min-height: 120px; /* 避免高度塌陷 */ } - 平滑过渡控制:.fadeOut().html().fadeIn() 可能造成短暂空白。更优做法是使用 opacity 动画 + visibility: hidden 配合 transition,或采用 CSS @keyframes fade-replace 实现无缝切换。
- 错误降级策略:AJAX 失败时应保留旧内容并显示轻量提示(如顶部 toast),而非清空区域;可加入指数退避重试逻辑。
该方案将请求次数从 4 次/10秒降至 1 次/5秒,服务端计算量下降 75% 以上,同时彻底消除“无意义刷新”,兼顾性能、可维护性与用户体验。











