列表就是产品
金融界面的成败系于长列表:数百支自选股、持续刷新的盘口、无限增长的成交记录。Web Almanac 与 Lighthouse 的数据把危险说得很具体。移动端中位页面约 594–616 个 DOM 元素,最重的 10% 接近 1,700–1,900;Lighthouse 在超过 800 个节点时开始警告,超过 1,400–1,500 报错。一条 1,000 行的列表若按网页方式渲染,能轻松越过所有这些阈值——此后每次滚动、悬停、点击,浏览器都要为整棵树重算样式与布局,这正是 INP(Interaction to Next Paint)崩塌的方式。
WebView 把每一行都渲染成节点
WebView 按文档方式构建长列表:每一行是一个 DOM 节点,所有节点同时驻留内存。滚动时,浏览器要为数千个节点布局与绘制,每次交互的样式重算都会触及数百个元素。超过几百行后,表现就是掉帧、内存攀升,最终因渲染层跟不上而出现白屏。网页也有缓解手段——content-visibility: auto、react-window 这类虚拟列表库——但它们是叠加在一个「从未为节点回收而设计」的架构之上的补丁,还带来框架重量与无障碍陷阱。
小程序只回收屏幕上的行
受管 runtime 把长列表当作原生控件处理。微信的 recycle-view 只渲染当前视口内的行,并在滚动时回收节点实例——组件实例固定不变,只有数据在流动。基于 Skyline 渲染引擎的新版 scroll-view(type="list")彻底去掉了逻辑↔渲染的 JSBridge:滚动与渲染在同一线程、同步光栅化,快速滚动也不会白屏,且内存占用低。旧的 WebView 式 scroll-view 要付出 JSBridge 转换成本、采用异步分块光栅化,一旦跟不上就白屏。回收是默认行为,而非你事后装上的库。
逐项对比
| 维度 | H5 / WebView | 小程序(recycle-view / Skyline) |
|---|---|---|
| 1,000 行列表的节点 | 数千个常驻 DOM 节点 | 仅屏幕上的行(约数十个) |
| 滚动时的样式重算 | 每次交互整棵树 | 已回收,工作量极小 |
| 逻辑↔渲染桥 | JSBridge 转换成本 | 无(同线程,同步光栅) |
| 光栅化 | 异步;快速滚动白屏 | 同步;无白屏 |
| 内存 | 高;有崩溃风险 | 低 |
| INP 影响 | 大 DOM → INP 差 | 小 DOM → INP 好 |
对你的列表意味着什么
对数据密集、不断增长的地表——自选股、盘口、成交日志——节点回收就是「原生手感」与「幻灯片」之间的差别。一个从结构上就回收节点的 runtime,在低端 Android 上保持可预测的帧节奏,而全球装机主体量正生活在这里,1,000 行列表是常态。H5 仍是文档与开放网络的正确工具;宿主内「数据地表」喂入千行时,不该卡顿。
Cross Mini App 的位置
Cross Mini App 是这一模型的 runtime 与开放 catalog。你按标准 API 面构建小程序,它便在每一个嵌入的宿主里继承一条「只回收屏幕上行」的列表路径——而非一个实例化数千节点并卡死的 WebView。丝滑列表是被设计进去的,不是祈祷来的。H5 展示行,小程序让你滚动它们。