首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

前端虚拟列表的实现原理

作者:字节跳动 fe @程翯 近期在某平台开发迭代的过程中遇到了超长List嵌套在antd Modal里加载慢,卡顿的情况。于是心血来潮决定从零自己实现一个虚拟滚动列表来优化一下整体的体验。...一个虚拟列表是指当我们有成千上万条数据需要进行展示但是用户的“视窗”(一次性可见内容)又不大时我们可以通过巧妙的方法只渲染用户最大可见条数+“BufferSize”个元素并在用户进行滚动时动态更新每个元素中的内容从而达到一个和长...在 phantom 中的每条数据都应该具有 position: absolute 属性 phantomContent 则是我们的“幻影”部分,其主要目的是为了还原真实List的内容高度从而模拟正常长列表滚动的行为...接着我们对 vListContainer 绑定一个onScroll的响应函数,并在函数中根据原生滚动事件的scrollTop 属性来计算我们的 startIndex 和 endIndex 列表总高度:...当用户当前的滚动offset未触发下标更新时,则因为本身phantom的长度关系让虚拟列表拥有和普通列表一样的滚动能力。

1.8K40

小程序-SaUi-遇到的坑

来点现实中遇到的坑儿吧~~~~~~~~~~~解决前 心中有千万个草泥马在奔跑。解决后,kao 这么简单!!!!!!!! 1、项目需要用到slider时,容易触发到右滑切换到上一页的问题。...幸好我们现在的框架就完全的支持到这一点,从item->list->tabs->…每个组件都对setData作了封装。更新解决了,后面你又会发现一次性更新所有的话,内容越多,反应越慢。不怕。...这时我们还有指定某一条的更新。封装得到了findAndUpdate的方法 3、原生组件,层级太高,在开发者工具正常显示,所以很努力去折腾完善,…完成后在真机想炫耀一翻…妈啊,这是什么鬼东西!!...在我们的框架中我们可以在组件里嵌组件。不仅可以写自己的组件, 也能自由的去嵌套别人已经写的组件。这个可以解决什么问题呢。在没有组件之间的嵌套,我们写业务时,会有n多个view 比如:关于我们。...,滚动屏幕,底部会跟着滚动,这时。

65630
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    关于虚拟列表,看这一篇就够了

    .虚拟列表 其核心思想就是在处理用户滚动时,只改变列表在可视区域的渲染部分,然后使用padding或者translate来让渲染的列表偏移到可视区域中,给用户平滑滚动的感觉。...虚拟列表原理 虚拟列表的核心步骤可以总结成五步: 不把长列表数据一次性全部直接渲染在页面上 截取长列表一部分数据用来填充可视区域 长列表数据不可视部分使用空白占位填充(下图中的startOffset和endOffset...区域) 监听滚动事件根据滚动位置动态改变可视列表 监听滚动事件根据滚动位置动态改变空白填充 固定高度 列表项高度固定的话,就无需每次都计算当前应该渲染多少条数据,视口的数据量始终是固定的,只需要通过用户滚动的距离...当用户滚动时,我们需要一直更新这个缓存数组中的列表项信息,目的是下次计算就能使用列表项的真实高度和位置,从而准确渲染出列表项。...并且需要注意的是,不只是需要更新视图中的列表项,还需要更新之后的所有列表项 // 每次滚动,都去更新缓存数组中dom的高度和位置   useEffect(     function () {

    4K32

    Vue项目中的虚拟滚动:提升页面渲染性能的最佳实践

    目录前言什么是虚拟滚动业务案例实现方式通过 npm安装main.js引入在Vue页面中使用效果预览总结前言在现代 Web前端开发中,性能优化一直是个重要话题。...什么是虚拟滚动虚拟滚动(Virtual Scrolling)是一种高效的渲染技术,主要用于处理大量数据的长列表或表格。其基本原理是只渲染当前视口内可见的元素,而对不可见的部分仅保留占位符。...这种方法大幅减少了DOM节点的数量,从而提升了渲染性能和滚动流畅度。虚拟滚动的核心有以下 4 点:渲染可见元素:虚拟滚动只会渲染当前视口内的元素,而不是整个列表或表格。...比方说,假设视口中只能显示10个元素,那么虚拟滚动技术只会渲染这10个元素,即使总数据量有上万个。动态更新视口内容:当用户进行滚动操作 时,使用虚拟滚动技术可以动态更新可视区域内的内容。...新进入视口的元素会被渲染,而离开视口的元素会被销毁,从而保持视口内元素的数量相对稳定。减少DOM操作:由于只渲染了可视区域内的元素,虚拟滚动大幅减少了DOM操作的频率。

    2.3K10

    用惰性加载优化 React 程序

    例如,如果我们有一个要显示的文章列表,开始时应该只渲染视口上的内容。这意味着其他元素将在以后按需呈现(当它们位于视口中或即将在视口上时)。 为什么要用懒惰性载?...大多数时候,我们的用户看不到整个网页,至少在开始时是这样。无论我们的程序 UI 如何构建,用户最初甚至永远都不需要某些组件!...所以先生成一些虚拟数据。在我们项目的 src 文件夹中创建一个名为 data.js 的文件。...但是由于当前的内容是文本,除非我们检查并看到 DOM 从 loading 转换为 loaded 时的变化,否则效果很难实现。 为了使延迟加载效果更加明显,让我们在列表中合并图像。...最终的App.js 现在我们可以用 inspect element open 来“滚动”列表,以查看这些组件在接近视口时如何变化的,还有怎样被渲染并且占位符怎样被实际内容替换。

    2.7K20

    初探富文本之基于虚拟滚动的大型文档性能优化方案

    初探富文本之基于虚拟滚动的大型文档性能优化方案 虚拟滚动是一种优化长列表性能的技术,其通过按需渲染列表项来提高浏览器运行效率。.... */} /> 通过简单分析Arco的通用列表虚拟滚动,我们可以发现实现虚拟滚动似乎并没有那么难,然而在我们的在线文档场景中,实现虚拟滚动可能并不是简单的事情。...DOM进行占位,可能大家会想着如果直接使用translate是更好的选择,效率会高一些并且能触发GPU加速,实际上对于普通的虚拟列表是没什么问题的,但是在文档结构中DOM结构会比较复杂,使用translate...,在固定高度时我们渲染的起始index游标是直接根据滚动容器高度和列表所有节点总高度算出来的,而在动态高度的虚拟滚动中,我们无法获得总高度,同样的渲染节点的长度也是如此,我们无法得知本次渲染究竟需要渲染多少节点...视口锁定 视口锁定是比较重要的模块,对于虚拟滚动来说,如果我们每次打开的时候都是从最列表内容的开始浏览,那么通常是不需要进行视口锁定的。

    34310

    HarmonyOS 开发实践 —— 基于webview的嵌套滚动及与ArkUI组件的联动

    场景描述在一些应用的首页或者详情页上,需要原生组件与网页进行一些嵌套或者展开收起的逻辑。...场景一:在滑动场景中原生组件与web页面嵌套,需要先让原生组件的高度变化,等原生组件到底后web页面高度随之变化。场景二:嵌套在列表的原生组件中的web页面,点击按钮可以展开或者收起。...方案描述将web组件放置在List或者Scroll组件中,通过web的嵌套滚动属性nestedScroll和Scroll的onScrollFrameBegin属性实现场景一的场景效果。...通过在Scroll组件每帧开始滚动时触发的回调onScrollFrameBegin中监听y轴高度,并通过一个变量传递到Image组件中,从而实现Image组件的高度动态变化。...因为web组件嵌套在父组件Scroll中并且向上滑动时,最开始并不需要web页面滑动,只需要手势作用的量传递到Image组件上,使其高度减少,当达到最小高度后就可以滚动了。

    10820

    Web前端:2022年十大React表库

    Rsuite-table 2、这是 React Table 的一个灵活组件,可促进虚拟化、固定列和标题、树视图等等。这个库的另一个最大优点是它使排序变得非常快速和简单。...除了在大多数视图上定制样式的能力外,移动/平板设备还可以使用两种“堆叠”和“滚动”响应模式。...因此,如果你希望在当前行为之上访问自己的样式,它会为你工作。 React-virtualized 6、它是一个开源库,为你提供了几个组件来窗口化你的一些应用程序列表、网格等。...借助行和列虚拟化,它可以在一秒钟内加载大量数据,几乎 100 万条以上的记录,而不会降低效率。...React-super-responsive-table 8、这会将你的表格数据转换为移动视图中的用户友好列表。

    12410

    移动端的touch事件处理

    clientY:触摸目标在视口中的y坐标。  identifier:标识触摸的唯一ID。  pageX:触摸目标在页面中的x坐标。  pageY:触摸目标在页面中的y坐标。         ...TouchList看了上面的列表中的内容,首先先注意到的一点就是,TouchList对象,一个新的也是唯有touch事件的event对象中,才会出现的一种对象,在了解changedTouches,targetTouches...更让我疑惑的是,此时,这三个属性,都能正确的获取到触点的个数,有几根手指,就能有在各个属性中,就会保存多少个touch对象。属性属性值touches保存当前一个触摸个数的列表。...使用原生的滚动事件Android 4.0 以下是不支持原生的 webview 滚动的,所以只能使用 iscroll 之类的工具来模拟元素滚动。...它的缺点就是有些过于的复杂,所以我还是会在条件允许的情况下使用原生的滚动。

    1.7K20

    性能:React 实战优化技巧

    如果依赖项没有发生改变,它将返回上次缓存的值;否则将再次调用 calculateValue,并返回最新结果。...在初次渲染时,useCallback 返回传入的 fn 函数;在之后的渲染中,如果依赖没有改变,useCallback 返回上一次渲染中缓存的 fn 函数;否则返回这一次渲染传入的 fn。...在列表渲染时 key 属性可以用于识别 React 的 diff 算法哪些列表项已更改,通过复用具有相同 key 的组件实例,React可以减少了不必要的DOM操作&重新渲染,从而提升界面更新的效率。...为了正确使用key属性,确保所提供的key是稳定、唯一且可预测的。 虚拟化 最常见的虚拟列表。仅渲染可见部分,而不是全部内容,实现性能的提升。...= useRef(null); const originalList = useMemo(() => Array.from(Array(99999).keys()), []); // 配置虚拟滚动

    10500

    移动端click事件300ms延迟

    也就是说,当我们点击页面的时候移动端浏览器并不是立即作出反应,而是会等上一小会儿才会出现点击的效果。在移动WEB兴起的初期,用户对300ms的延迟感觉不明显。...产生原因 移动浏览器上支持的双击缩放操作,以及IOS Safari 上的双击滚动操作,是导致300ms的点击延迟主要原因。...用户在 浏览器里边点击了一个链接。由于用户可以进行双击缩放或者双击滚动的操作,当用户一次点击屏幕之后,浏览器并不能立刻判断用户是确实要打开这个链接,还是想要进行双击操作。...然而,你若只想寻求一个解决 300 毫秒点击延迟的方法,上述方案可能就有点过了,因为它们要么是资源密集型的方案,要么是touch-action属性的非标准化模拟。...为了防止原生的click被触发,这里还通过event.preventDefault()屏蔽了原生的click事件。

    2.8K21

    htop(1) command

    -t, --tree 在树状视图中显示进程。可用于在使用选项 -s 按照指定列排序时强制生成树视状图。 -u, --user=USERNAME|UID 只显示给定用户的进程。...基本导航和视图控制 Tab, Shift-Tab 选择显示的下一个/上一个屏幕标签。可以在设置屏幕(F2)中启用显示屏幕标签名称。 Up, Alt-k 在进程列表中选择(高亮)上一个进程。...如有必要,滚动列表。 Down, Alt-j 在进程列表中选择(高亮)下一个进程。如有必要,滚动列表。 Left, Alt-h 向左滚动进程列表。 Right, Alt-l 向右滚动进程列表。...PgUp, PgDn 向上或向下滚动进程列表一个窗口。 Home 滚动到进程列表顶部并选择第一个进程。 End 滚动到进程列表底部并选择最后一个进程。...H 隐藏用户线程:在系统中不同于普通进程表示它们的系统(如基于最新的NPTL的系统),这可以隐藏用户空间进程的线程。 O 隐藏容器化进程:阻止显示在容器中运行的进程。

    15710

    vueJs中toRaw与markRaw函数的使用比较

    这是一个可以用临时读取而不引起代理访问/跟踪开销,或是写入而不触发更改的特殊方法,在官方文档里,是不建议保存对原始对象的持久引用 使用场景:用于读取响应式对象的普通对象,对这个普通对象的所有操作,不会引起页面的更新...,如果没有把整个对象对外暴露出去,模板中使用新增的变量是不生效的(针对setup函数形式) 02 markRaw()函数 接收一个原始数据,标记一个对象,使它永远不会再成为响应式对象,也就是数据在逻辑中即使修改变化了...有些值不应该被设置为响应式的,例如复杂的第三方类库或Vue组件对象 [2]....当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能 const foo = markRaw({}) console.log(isReactive(reactive(foo))) // false...与shallowReactive()这样浅层式API使你可以有选择的避开默认的深度响应/只读转换,并在状态关系谱中嵌入原始,非代理的对象 如果把一个嵌套的,没有标记的原始对象设置成一个响应式对象,然后再次访问它

    1.3K10

    2020vue面试题及答案_人际关系面试题及答案

    1、虚拟DOM中key的作用: key是虚拟DOM对象的标识,当状态中的数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,随后Vue进行【新虚拟DOM】的差异比较,比较规则如下...: 2、key的对比规则: 1、旧虚拟DOM中找到了与新虚拟DOM相同的key: 若虚拟DOM中内容没变,直接使用之前的真实DOM 若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实...在 components 目录新建组件文件 在需要用到的页面import中导入 使用component注册 在 template 视图中使用组件标签 17、Vue如何实现按需加载配合webpack设置...中,而Model 数据的变化也会立即反应到View 上。...iframe也称作嵌⼊式框架,嵌⼊式框架和框架⽹页类似,它可以把⼀个⽹页的框架和内容嵌⼊在现有的⽹页中。

    8.7K20

    记一次vue长列表的内存性能分析和优化

    使用了vue框架,框架内部的虚拟DOM和组件缓存已经做了一些优化,比起原生实现是有了一些优化处理。...但这个页面是用到element-ui的el-table组件,渲染出来的是表格数据列表,众所周知,表格在渲染的时候需要绘制整个表格区,所以, 第一步就是将表格实现改为其他元素标签实现 这一步操作之后,其实没什么大的变化的...通过数据数量和每条数据的高度计算出内容区的高度,内容区用padding或绝对定位撑开滚动区域,让容器可滚动,另外就是数据项了,滚动的时候,计算当前滚动位置scrollTop,再从数据项中找出各项的高度,...,但还是能从GC根访问的时候,就产生了内存泄漏,主要需要考虑两类内存泄漏:普通JS的对象,游离的DOM节点(本该被回收,却还有对象引用它) 垃圾回收的时间点是不固定的,随机的,我们在代码中没法控制 点击左边的第一个小圆圈就可以开始分析了...,查看一顿操作之后的内存增长情况,主要针对这个操作过程(这个时候可以结合Performance标签功能中来分析) 上图中左侧是两个快照的结果,64.5M是进入页面之后的内存快照,149M是各种操作之后的内存快照

    3.4K81

    一文彻底搞懂js中的位置计算

    引言 文章中涉及到的api列表: scroll相关Api client相关Api offset相关Api Element.getBoundingClientRectAPi Window.getComputedStyleApi...scrollHeight 的值等于该元素在不使用滚动条的情况下为了适应视口中所用内容所需的最小高度。...此时,当你从右到左拖动滚动条时,scrollLeft会从0变为负数。 scrollLeft/Top在日常工作中是比较频繁使用关于操作滚动条的相关api,他们是一个可以设置的值。...在实际工作中如果对于滚动操作有很频繁的需求,个人建议去使用better-scroll,它是一个移动/web端的通用js滚动库,内部是基于元素transform去操作的滚动并不会触发相关重塑/回流。...计算元素是否出现在视口内 利用的还是元素距离视口的位置小于视口的大小。 注意即便变成了负值,那么也表示元素曾经出现过在屏幕中只是现在不显示了而已。

    3.9K10

    何为 content-visibility?

    好,我们实际开始进行滚动,看看会发生什么: 由于下方的元素在滚动的过程中,出现在视口范围内才被渲染,因此,滚动条出现了明显的飘忽不定的抖动现象。...当然,在向下滚动的过程中,上方消失的已经被渲染过且消失在视口的元素,也会因为消失在视口中,重新被隐藏。因此,即便页面滚动到最下方,整体的滚动条高度还是没有什么变化的。...从上面的例子,也能看到,在利用 content-visibility: auto 处理长文本、长列表的时候。在滚动页面的过程中,滚动条一直在抖动,这不是一个很好的体验。...当然,这也是许多虚拟列表都会存在的一些问题。 好在,规范制定者也发现了这个问题。...所以,在实际使用中,如果你的业务中已经使用了比较完善的 Lazyload 处理长列表或者一些图片资源,那么 content-visibility: auto 不是更好的选择。

    1.6K10

    牛赞:音视频前端跨平台技术应用

    在之前Flutter技术设施尚不成熟时,PlatformView也为其注入了强大的生命力,在Native端不易实现的组件都可以通过PlatformView方案嵌入原生平台view中。...延迟能够控制在300ms以内,直播过程中提供高级美颜如瘦脸、微脸,图中可以明显看到微脸操作后的效果对比。视频会议适合交流工作。...由于FlutterWeb自身实现了一套页面滚动机制,页面滚动过程中,会频繁计算位置信息,引起滚动区域的重新渲染,最终导致页面滚动性能较差。...更丰富的使用场景,底层技术也可以复用到直播推流SDK和播放器SDK。 下一代Web的RTC引擎预计明年正式对外,大家可以期待一下。 在目前视频会议产品中,虚拟背景已经成为了标配能力。...腾讯云音视频在音视频领域已有超过21年的技术积累,持续支持国内90%的音视频客户实现云上创新,独家具备 RT-ONE™ 全球网络,在此基础上,构建了业界最完整的 PaaS 产品家族,并通过腾讯云视立方

    2.7K10

    这一次,彻底解决滚动穿透

    首先,一般而言滚动不是我们自己监听事件去改变元素的位置而实现的,当我们设置 overflow:scroll/auto时,实际上是浏览器原生实现的滚动效果。...,同时也没有 preventDefault掉原生的滚动/滑动事件,那么此时触发的是 viewport的滚动, position:fixed的元素并没有什么例外。...由此可见,滚动穿透问题其实并不是一个浏览器的bug(虽然在ios下fixed定位确实会导致很多bug),它是完全符合规范的,滚动的原则应该是 scrollforwhat can scroll,不应该因为某个元素的...(请注意蒙层出现时,底部列表发生的变化) 在这个交互过程中,浮层弹出时,底部列表首先滚动条被置为初始态,关闭浮层后重置为之前的记录位置。...可是从使用性质来考虑,还不是很便捷,尤其是现在如 React, Vue这类框架中,还需要考虑浮层什么时候实例化,什么时候应当调用 lock和 unlock显得有些麻烦,因此编写了一个React版本的组件

    2.8K21

    Taro | 高性能小程序的最佳实践

    01 前言 在今年的敏捷团队建设中,我通过Suite执行器实现了一键自动化单元测试。Juint除了Suite执行器还有哪些执行器呢?由此我的Runner探索之旅开始了!...作为一个开放式的跨端跨框架解决方案,Taro 在大量的小程序和 H5 应用中得到了广泛应用,同时也经常收到开发者的反馈,例如“渲染速度较慢”、“滑动不够流畅”、“性能与原生应用相比有差距” 等。...需要注意的是,由于这是全局设置,可能会带来一些问题,例如: •在跨原生自定义组件时,flex 布局会失效(这是影响最大的问题); •在 SelectorQuery.select 方法中,跨自定义组件的后代选择器写法需要增加...它们的原理是只渲染当前可见区域(Visible Viewport)的视图,非可见区域的视图在用户滚动到可见区域时再进行渲染,以提高长列表滚动的流畅性。...6.1 阻止滚动穿透 在小程序开发中,当存在滑动蒙层、弹窗等覆盖式元素时,滑动事件会冒泡到页面上,导致页面元素也会跟着滑动。通常我们会通过设置 catchTouchMove 来阻止事件冒泡。

    57610
    领券