项目难题:
项目上基本上没遇到过特别难以解决的问题,整个的开发过程还是比较顺畅的,但是也遇到一些坑以及比较有意思的场景可以说一下
1、处理excel的问题,需求需要把原来的excel样式也导出,而且增加水印,使用过几个库,最后使用exceljs,excejs支持解析样式
2、大屏可视化项目,使用了scale缩放适配大屏,有优缺点,缺点也能接受问题不大,
3、taro/uniapp跨端项目,处理兼容性问题
- onReady问题,只有页面组件才会触发onReady生命周期,子组件不会触发,子组件需要通过消息机制去监听页面组件的onReady
- onPageScroll事件,只有页面组件才会触发,在子组件不触发
- h5再钉钉导航栏问题,需要使用钉钉的SDK才可以修改钉钉导航栏
4、大数据渲染问题,采用了虚拟滚动方案 5、文件上传问题
6、视频相关难点 【短剧小程序项目】
虚拟滚动方案
方案1、虚拟列表滚动,滚动到可视区域的时候 就会添加到节点,不在可视区域的话 就会删掉节点
如果你的应用存在非常长或者无限滚动的列表,那么需要采用 窗口化 的技术来优化性能,只需要渲染少部分区域的内容,减少重新渲染组件和创建 dom 节点的时间。
虚拟列表其实是按需显示的一种实现,即只对可见区域进行渲染,对非可见区域中的数据不渲染或部分渲染的技术,从而达到极高的渲染性能。 假设有1万条记录需要同时渲染,我们屏幕的可见区域的高度为500px,而列表项的高度为50px,则此时我们在屏幕中最多只能看到10个列表项,那么在首次渲染的时候,我们只需加载10条即可。 虚拟列表滚动实现 参考:https://github.com/dwqs/blog/issues/70
虚拟列表定义:只渲染可视区域的列表,非可见区域中的数据不渲染,大大的提高了渲染的性能
实现虚拟列表就是在处理用户滚动时,要改变列表在可视区域的渲染部分
明确两个概念:可视区域、可滚动区域
可滚动区域 = 计算真实容器高度 = 数据总数 * 每条 item 的高度
具体实现步骤:
首先需要用变量来保存当前完整的列表数据、以及渲染的列表数据
- 1、需要计算可视区域起始数据的位置(可视区域第一项位置)startIndex
假设元素的高度是固定的:那么startIndex = scrollTop (滚动条的高度) / itemHeight (列表项的高度)
- 2、需要计算可视区域结束数据(可视区最后一个数据的位置)endIndex
endIndex = startIndex +(clientHeight/itemHeight)
-
3、计算当前可视区域的数据,渲染到可视区域中
-
4、计算可视区域第一项位置 startIndex 对应的数据在整个列表中的偏移位置 startOffset,并设置到列表上
- 刚开始渲染的时候,startOffset默认是0
- 当开始滚动的时候,startOffset = 可视区域第一个元素 到 列表的第一个元素 的距离
-
5、计算 endIndex 对应的数据在整个列表中的偏移位置 endOffset,并设置到列表上
- 刚开始渲染的时候,endOffset默认是0
- 当开始滚动的时候,endOffset =(整个列表的数据长度 - endIndex (可视区域最后一个元素的位置) )* height(列表高度) startOffset和endOffset是一个隐藏的区域,会撑开容器元素的内容高度,让其可持续的滚动
注意:
如果元素高度不是固定,那么如何计算startIndex?
给每一个item绑定一个方法(可以利用事件委托 【将一个元素的响应事件委托到父元素上或者外层元素】) 当节点加载渲染后调用此方法来动态获取元素高度,并且将startIndex开始位置和height高度信息缓存保存起来 缓存的作用是 避免重复计算
什么场景,后端需要返回大量数据/后端无法通过数据库分页
在某些情况下,后端可能无法直接通过数据库分页,并需要前端进行分页处理来处理返回的大量数据。以下是一些可能的场景:
需要前端分页/虚拟滚动,后端无法通过数据库分页
实时数据流
- 实时数据流:如果后端提供的是实时数据流,例如实时销售、实时监控等,这些数据可能没有固定的数据库结构和分页方式。后端可能需要返回一定数据量给前端,并在前端进行分页和展示。
为什么实时数据,数据库无法做分页?
数据库在处理实时数据时可以进行分页,但实时数据的特点可能导致数据库分页的效果不佳或无法满足需求的情况。
以下是一些可能的原因:
- 数据流式更新:实时数据通常是流式更新的,新数据不断到达,而不是像传统数据库中的静态数据。在这种情况下,数据库分页的结果可能会不断变化,导致分页结果不稳定或不一致。
- 实时性要求:实时数据需要及时地反映最新的状态和变化。数据库分页通常需要执行查询和排序等操作,这些操作可能引入一定的延迟,无法满足实时性要求。
- 数据量过大:实时数据往往是大规模的,数据库在执行分页查询时可能需要处理大量的数据,导致查询效率低下。特别是当数据量不断增长时,数据库分页的性能可能会受到限制
异步加载树节点
树加载的时候,异步加载树,父节点异步加载子节点,子节点可能有大量数据 【子节点有上万条数据】
场景:
- 1、区域管理树 【展示城市-门店树】
- 2、省/城市区域树
虚拟列表如何优化
- 1、可变高度项处理:如果列表中的项具有不同的高度,这可能会导致滚动时的用户体验。通过使用动态高度计算和缓存,可以减少这些问题,并提高滚动的平滑度
- 2、节流和防抖:为滚动事件和数据加载事件应用节流和防抖技术。节流可以限制事件的触发频率,而防抖可以在一定时间内只执行最后一次触发的事件。这可以减少频繁的数据加载和渲染操作,提高性能
- 3、预加载:当用户接近列表末尾时,可以通过预加载一些数据,提前获取下一页或多个页面的数据,以减少用户等待时间并提供平滑的滚动体验。
视频难点
- 视频播放优化
- 缓存视频
- 预加载视频
视频播放优化
预加载视频
- 预加载下一个视频,提高视频的加载的速度
- 在用户正常观看当前剧集时,自动为用户加载并解锁下一集内容,并将内容缓存到内存中,便于用户在看完当前剧集后切换到下一集可以更快地观看
缓存队列
- 用于剧集数据的缓存,通过剧集id episodeid及剧集内容进行关联,存到缓存队列中,当队列长度超过指定的值时,按照先进先出的方式丢弃元素,保持缓存队列的个数,避免缓存持续增长,造成内存占用过大
请求预加载逻辑
- 1、请求时先查找缓存中是否存在当前剧集信息,如果不存在,则请求该剧集信息,并存到缓存中
- 2、如果存在当前剧集信息,返回该剧集信息
- 3、如果缓存的剧集信息存在下一集的剧集id,就预加载并解锁下一集
- 4、剧集预加载时不会产生观看记录,需要前端手动调用观看记录上报接口进行上报
一屏内显示多个视频
- 只加载可视区域的视频
- 其他不在可视范围内,,就不渲染
- 提高视频的加载速度