正确做法是每次fetch成功后整体替换列表内容并加loading防重复,用DocumentFragment批量插入提升性能,排序依数据量选前后端,失败时保留旧数据并指数退避。

用 fetch 轮询接口更新排行榜,别用 setInterval 直接刷 DOM
实时排序本质是「数据变,视图变」,HTML 本身不支持自动刷新,必须靠 JS 拉新数据再重绘。常见错误是把 setInterval 套在 DOM 操作里——比如每秒改一次 innerHTML,结果接口还没返回就清空列表,用户看到空白闪动或旧数据残留。
正确做法是:每次 fetch 成功后再整体替换列表内容,且加 loading 状态防重复触发。轮询间隔别设太短(3000 ms 是较稳妥起点),否则容易被服务端限流或压垮前端渲染。
- 接口应返回结构化 JSON,含
topic、hot_score、updated_at字段,别依赖 HTML 片段 - 用
AbortController控制上一轮请求,避免慢请求返回后覆盖新数据 - 首次加载完成前,页面显示 skeleton 占位,而非空列表或“加载中…”文字
用 DocumentFragment 批量插入,避免频繁重排重绘
排行榜每轮更新都要重建 10–50 条 ,如果逐个 appendChild,浏览器会反复计算样式和布局,滚动卡顿明显。直接拼 innerHTML 看似快,但 XSS 风险高,且无法复用已有 DOM 节点(比如已绑定的点击事件)。
DocumentFragment 是无渲染的中间容器,适合先攒好所有节点再一次性挂载。它不触发重排,性能比循环 append 高 3–5 倍(尤其在低端安卓机上)。
- 用
document.createDocumentFragment()创建片段 - 遍历数据时用
document.createElement('li')构建每个项,设置textContent(非innerHTML)防 XSS - 最后用
listElement.appendChild(fragment)一次挂载
排序逻辑写在前端还是后端?看数据量和更新频率
如果话题数稳定在几百以内,且热度分由服务端实时计算(如带权重的点击+转发+时间衰减),那排序必须由后端完成——前端只负责按序渲染。否则你拉回 200 条未排序数据,在 JS 里跑 Array.sort(),既浪费带宽又增加首屏延迟。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
但若数据源来自多个 API(比如合并微博+知乎热榜),或需按用户偏好动态切换排序规则(“按 24h 新增热度” vs “按总热度”),那就得前端排序。注意:用 Intl.Collator 处理中文标题排序,别用默认 String.localeCompare(),否则“人工智能”可能排在“云计算”后面。
- 后端排序:要求接口明确支持
?sort=hot_score&order=desc参数,响应头带Cache-Control: no-cache - 前端排序:对
hot_score做数值比较,避免字符串比较('10' 为 true) - 时间字段统一转成毫秒时间戳再比,别直接比 ISO 字符串
处理网络失败和数据不一致的兜底策略
轮询过程中,接口超时、返回 502、或数据字段缺失(比如某条没 hot_score)很常见。此时若直接清空列表或报错弹窗,用户体验断层。更稳妥的是保留上一版数据,并标记“数据暂未更新”。
关键不是“怎么显示错误”,而是“怎么不让用户感知到错误”。比如加一个淡入淡出的过渡 class,失败时只更新顶部状态栏文字,列表不动;成功后才触发动画切换。
- 用
try/catch包住await fetch(),捕获网络错误,而非只监听response.ok - 校验返回数据结构,缺失必填字段时跳过该条,不中断整个渲染流程
- 连续 3 次失败后暂停轮询,改用指数退避(下次尝试间隔变为
6000ms),避免雪崩
真实场景里,最难调的往往不是怎么刷出来,而是怎么让“刷”的过程没人察觉——loading 不闪、排序不跳、失败不空。这些细节堆起来,才是所谓“实时”的底子。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










