大屏页面必须禁用滚动和缩放,否则全屏失效:html和body需同时设margin:0;padding:0;width:100%;height:100%;overflow:hidden;仅设body无效,因滚动由html根元素接管;须配合viewport user-scalable=no、maximum-scale=1.0,并用position:fixed+100vw/100vh避免ios地址栏跳变导致的视口重排。

大屏页面必须禁用滚动和缩放,否则全屏失效
只要出现滚动条或意外缩放,大屏就失去驾驶舱意义。关键不是“撑满”,而是让浏览器彻底交出控制权:html 和 body 必须同时设为:margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden;。只写在 body 上无效——滚动行为默认由 html 根元素接管。
常见错误是依赖 100vh 却没处理 iOS Safari 地址栏隐藏导致的视口跳变。稳妥做法是用 position: fixed 包裹整个内容层,再配合 top: 0; left: 0; width: 100vw; height: 100vh;,避免动态计算视口高度。
- 别用
viewport的user-scalable=yes,必须设为no,且maximum-scale=1.0 - 移动端真机测试时,重点观察地址栏收起瞬间是否触发重排、文字跳动
- 若用
transform: scale()做分辨率适配,overflow: hidden仍需作用于html,否则缩放后溢出部分仍可拖拽
语义化结构要极简,但不能牺牲 DOM 平衡
大屏不需要 SEO 或辅助技术深度支持,语义标签的价值在于逻辑清晰和样式隔离。用 <header></header>、<main></main>、<footer></footer> 划分区域没问题,但别嵌套过深——单个容器子元素超过 50 个,渲染压力会陡增;尤其当 <main></main> 下直接挂几十个图表 <div>,首次 layout 就可能卡顿 300ms 以上。<p>真正影响性能的是 DOM 树不平衡,而非标签名本身。例如把所有图表塞进一个 <code><section></section>,不如拆成 <section class="panel-left"></section>、<section class="panel-center"></section> 等独立区块,既方便 CSS Grid 布局,也利于 JS 按需更新局部节点。
- 避免
<div> 套 <code><div> 超过三层,能用 Flex/Grid 直接布局的,不额外加包裹层<li>高频刷新模块(如实时日志表格)必须从主 DOM 树中剥离,用 <code>documentFragment或独立<div id="log-view"> 托管<li> <code><canvas></canvas>和<svg></svg>容器不要放在语义标签内部做样式继承,容易触发不必要的重绘 -
phantomHeight(占位高度)必须严格等于totalCount * rowHeight,否则滚动条比例失真 - 缓冲区大小至少为
Math.ceil(viewportHeight / rowHeight) + 2,上下各多渲染两屏,防止快速滚动时闪白 - 滚动监听绝不能直接写
onscroll,要用requestAnimationFrame包一层,否则高刷屏上每帧多次触发计算 - 回收池中的
<tr> 必须清空 <code>textContent和dataset,否则旧数据残留会导致错行ECharts 图表初始化和 resize 绑定极易出错
图表能画出来,但窗口一拉伸就变形、坐标轴错位、文字糊成一片——90% 是没正确绑定
resize。ECharts 不自动响应窗口变化,必须手动监听,且时机和节流方式不对,照样崩。Vue 场景下,用
ref拿到 DOM 后立刻echarts.init()很危险:DOM 可能尚未挂载完成,init返回 null。React 中类似,useEffect里未加依赖数组或清理逻辑,图表实例会泄漏。- resize 回调必须调用
chart.resize(),且不传参数;传入宽高反而干扰内部自适应逻辑 - 多个图表共存时,每个都要单独绑定,不能只绑第一个容器的
resize - 高频触发必须节流,推荐
throttle(chart.resize, 200),而不是用setTimeout延迟——那是掩盖问题 - 初始化前确认容器已渲染,Vue 中用
nextTick包一层,React 中用useLayoutEffect更稳妥
大屏最隐蔽的坑不在代码里,而在设备组合:Chrome on Windows 没问题,但同一份 HTML 在 iPadOS Safari 上可能因地址栏跳变导致 canvas 渲染偏移,或因
text-rendering: optimizeLegibility让数字发虚。上线前必须用目标设备真机跑满 10 分钟,看 WebSocket 断连恢复、缩放切换、滚动连续性是否稳定。 - resize 回调必须调用
表格类组件必须用虚拟滚动,万行数据不能直渲
直接渲染 10000 行 <tr> 不是慢,是根本不可控:每行触发一次样式计算 + layout + paint,DPR=2 的 4K 屏下内存分配更碎片化,GC 延迟常导致首屏 >2s 或滚动白屏。问题不在数据量,而在于你让浏览器把每一行都当作“必须立即参与渲染”的节点。<p>工业级方案只有一条路:固定行高 + 缓冲区 + requestAnimationFrame 节流。动态行高(如自动换行单元格)会让 <code>startIndex = Math.floor(scrollTop / rowHeight) 失效,必须预设统一 rowHeight: 48,并在 CSS 中强制 white-space: nowrap; overflow: hidden;。











