关于“虚拟滚动”效果

291 阅读2分钟

新版微博使用了一种叫「虚拟滚动」的技术。

简单来说,传统技术如果你的时间线上有 1000 条微博,即便你的屏幕只够显示 5 条,前端也要生成 1000 个 HTML 节点。这样当条数足够多对浏览器和电脑内存都是个不小的压力。这也是为什么旧版微博即便是一边往下翻一边渐进式加载,但是翻到一定距离后会出来个选页数的菜单强行要你按一下一页才会 (清屏并且) 继续加载的原因。

而为了解决这个问题诞生的虚拟滚动技术,根据你屏幕高度只创建稍微比你屏幕多那么一两条数量的节点。实时根据你的滚动距离,当某一条微博被滚出屏幕外立刻把它的 HTML 节点重新赋值成下一条微博的内容挪到屏幕另一侧等着被翻到。

但是虚拟滚动有个弊端,对于浏览器来说页面并不真的在「滚动」。它只不过是一些元素被脚本实时控制这位置在屏幕上挪来挪去而已。前端框架需要非常了解每一条微博的高度。当高度发生了变化时也要及时调整往下几条微博的位置 (把本来由浏览器排版引擎完成的工作做了)。

众所周知,当一个东西变复杂了,那么出问题的机会也就更多了。所以在新版微博里,你可以遇到以下一些神奇景象:

  1. 如果你注册时间比较早,翻一些很多年前的微博,会错位…我猜可能是早期的微博没有记录图片的大小,导致元素高度计算错误

  2. 点开大图要等它加载完了才变大…猜测可能是需要加载之后取得图片大小重新计算高度 (很奇怪,这理论上和第1点是矛盾的)

  3. 有些微博图被夹了,但是数据没同步更新。这导致点开图片时,前端还是会按照元数据里记录的图片大小调整高度

  4. 不知道这两天微博更新了啥,引入了个新 bug,首页翻着翻着也会错位…