这个性能是 pc 端程序, 实现手机端微信聊天记录查看性能
性能问题点
1,默认看到的记录是倒序排列,页面最底下一条是最近一条音讯
2,聊天记录可能存在有限往上翻阅的状况,dom 无奈承载如此多音讯,须要应用虚构列表
3, 向上向下翻阅过程中,滑动到上一页或者下一页如何定位以后页面最初一条第一条在以后,丝滑加载,不呈现‘闪跳’状况
4,动静加载,思考接口性能,一次申请数据不能太多,如何保护整个音讯列表信息
一,音讯记录数据结构
须要一个 msgData
字段来存储所有从接口返回来的音讯,{data,random}
随机数用于示意数据向下传递时示意是更新,初始值是 0,每一条音讯都有一个 msgId
字段,用于标识以后收到的音讯记录中历史最远的一条记录 id。音讯上滑下滑依据滑动方向,以及 msgId
能够判断是从内存取数据还是额定申请接口。
二,数据展现
传入的 random
字段用于标识是第一次传入还是数据更新,如果是第一次传入,新建一个宏工作,计算传入数据展现成相应元素之后的高度,
const virtualItems = document.getElementById('vir-scroll');
virtualItems.scrollTop = timeFilter ? 0 : virtualItems.scrollHeight; // 如果 timefilter 为真,scroll 到顶部
currentScroll = timeFilter ? 0 : virtualItems.scrollHeight;
如果是更新,须要计算目前内存中数据条数(数量小于显示界面数据阈值就追加)以及滚动方向,来获取相应的显示数据。
计算过程中,累加元素的 getBoundingClientRect().height
来计算以后展现元素的高度,计算高度的同时,还须要把对应的 dom 元素渲染到页面中。
滚动
const scrollTop = virtualRef.current.scrollTop;
direction = scrollTop < currentScroll ? 'down' : 'up';
currentDirection = direction;
currentScroll = scrollTop;
// 计算滚动条到底部间隔,保障异步加载元素地位不变的要害
bottomDistance = virtualRef.current.scrollHeight - virtualRef.current.clientHeight - virtualRef.current.scrollTop;
const lastMsgId = direction === 'up' ? +items[items.length - 1]?.key : +items[0]?.key;
const indx = wrapperData?.data?.findIndex((elm:any) => elm.msgTime === lastMsgId);
滚动时须要计算以后滚动方向,依据方向再进行上面的计算,这里须要分为上滑和下滑。
下滑到底时,如果间隔顶部小于 50,就要触发计算,依据以后页面元素第一条的索引值去内存中找 15 条,以后页面元素尾部去掉 15 条从新拼凑成须要展现到页面的残缺数据,而后计算出 scrollHeight
, 实现顺滑滑动。
上滑到顶,间隔底部小于 50,触发计算,计算形式和下滑相同。