Open yuxino opened 3 years ago
先从核心的模块SizeAndPositionManager说起。打开一下查看。不是很多400多行。
SizeAndPositionManager
先看公用函数getItemSizeAndPositionManager,看起来就是一个初始化的函数。
getItemSizeAndPositionManager
看完已经明白了如何初始化一个SizeAndPositionManager了。主要的三个选项是itemCount,itemSizeGetter, estimatedItemSize分别对应了文档上提到的几个属性,estimated是估算的意思,其他的都比较好理解,顺带一提这文件的源码其实来自react-virtualized,也就是说看了这玩意约等于也看了一下react-virtualized的源码。
itemCount
itemSizeGetter
estimatedItemSize
estimated
react-virtualized
回到这个函数里,itemCount是100,estimatedItemSize是15,itemSizeGetter是一段函数,目前用意不明。看起来每次调用都会给itemSizeGetterCalls增加东西。固定返回数字10(意义不明)。
itemSizeGetterCalls
更新: itemSizeGetterCalls就是拿来计算真是高度的。estimatedItemSize是预测高度。
这个函数会返回两个值sizeAndPositionManager, itemSizeGetterCalls。
sizeAndPositionManager
这是第一个测试我们先看它。
这个测视里并没有用到itemSizeGetterCalls,所以我们也不太好确定itemSizeGetterCalls目前是做什么的。这个测试的目的是测试寻找最近元素用的。仔细看了一下注释并不是最近元素而是nearest the specified offset也就是最近偏移量的元素位置。
最近元素
nearest the specified offset
最近偏移量的元素位置
初步结论
理解困惑之后
说白了这俩就是在找中间值。比如元素高10,目标位置是100那么最接近这个文素的就是第11个元素了,但是如果是101,那么第11个元素本身就是完美符合最接近偏移量的元素了。
初略看了一下代码实现,用到了二分(binarySearch)和指数查找(exponentialSearch)。准备之后去看看。
这块看起来蛮多的来研究一下。从名字来看是获取对应index的size和positon用的。
测试用例比较长,截图比较麻烦,一部分一部分来看。
噢噢噢,突然明白了,这个不是次数,是对应的 index 。因为访问的是 0 号,所以数组里面会有个 0。
那感觉上就会是访问一次加一条。。。我们试着多访问几次。。然鹅事实不是这样的。重复的访问只会有一条。
并且如果输入比较大的数字的话,比如3,就会变成[0,1,2,3]这样的结构。这应该要拜读源码才能理解了这个现象。感觉是为了获取正确的偏移量,需要按序的计算出之前元素的偏移量才能得出对应元素的偏移量。这个操作可能是感觉不是特别花时间,但是是可以优化的点。只要算过3,再获取2和1的时候就不需要重新计算了。不过整个算法复杂度看了一下也就O(n)吧。
下面的新的例子也印证了这一点。
优化测试。
好了本轮用例完结。
这是getSizeAndPositionForIndex衍生出来的东西,看起来是会把值缓存下来,记录元素对应的大小(size)和元素的实际偏移量(offset)。
size
offset
显而易见的用例。下一个。
先看源码吧,这个东西源码比较短。
Total size of all items being measured.This value will be completedly estimated initially. As items as measured the estimate will be updated. 先说结论这句话有帮助么,没啥帮助,还是看源码和测试用例更能理解,先说结论 totalSize 算的是可滚动的总大小,以下简称总大小。
计算公式是: lastMeasuredSizeAndPosition.offset + lastMeasuredSizeAndPosition.size + (this.itemCount - this.lastMeasuredIndex - 1) * this.estimatedItemSize
lastMeasuredSizeAndPosition.offset + lastMeasuredSizeAndPosition.size + (this.itemCount - this.lastMeasuredIndex - 1) * this.estimatedItemSize
简化一下。我们知道lastMeasuredSizeAndPosition就是上个单测里的东西,表示最后测量元素,包含size和offset两个属性。以下我们简称为lastOffset和lastSize。lastMeasuredIndex就是最后测量元素的索引,itemCount就是列表的总数。estimatedItemSize就是预计大小。
lastMeasuredSizeAndPosition
最后测量元素
lastOffset
lastSize
lastMeasuredIndex
最后测量元素的索引
那么屡一下。
lastOffset + lastSize + (this.itemCount - this.lastIndex - 1) * estimatedItemSize
对应中文:
最后一个元素的偏移量 + 最后一个元素的大小 + (总数 - 最后一个元素的位置 - 1) * 预计大小就是 总大小(totalSize) 了。
最后一个元素的偏移量 + 最后一个元素的大小 + (总数 - 最后一个元素的位置 - 1) * 预计大小
总大小(totalSize)
再简化一下:
总大小 = 最后一个元素的偏移量 + 最后一个元素的大小 + (剩余元素个数) * 预计大小
因为我们访问到最后元素的时候,说明我们此时渲染到了这个地方。也计算过前面的元素大小了。
因为这个特性我们可以推测,如果是动态算高度的性能会很差,因为必须真正的渲染出来再计算高度。但是真实情况如何,目前不清楚。
这又是一个非常大的测试块,说明这一块的功能很重要。
先从核心的模块
SizeAndPositionManager
说起。打开一下查看。不是很多400多行。getItemSizeAndPositionManager
先看公用函数
getItemSizeAndPositionManager
,看起来就是一个初始化的函数。看完已经明白了如何初始化一个
SizeAndPositionManager
了。主要的三个选项是itemCount
,itemSizeGetter
,estimatedItemSize
分别对应了文档上提到的几个属性,estimated
是估算的意思,其他的都比较好理解,顺带一提这文件的源码其实来自react-virtualized
,也就是说看了这玩意约等于也看了一下react-virtualized
的源码。回到这个函数里,
itemCount
是100,estimatedItemSize
是15,itemSizeGetter
是一段函数,目前用意不明。看起来每次调用都会给itemSizeGetterCalls
增加东西。固定返回数字10(意义不明)。更新:
itemSizeGetterCalls
就是拿来计算真是高度的。estimatedItemSize
是预测高度。这个函数会返回两个值
sizeAndPositionManager
,itemSizeGetterCalls
。findNearestItem
这是第一个测试我们先看它。
这个测视里并没有用到
itemSizeGetterCalls
,所以我们也不太好确定itemSizeGetterCalls
目前是做什么的。这个测试的目的是测试寻找最近元素用的。仔细看了一下注释并不是最近元素
而是nearest the specified offset
也就是最近偏移量的元素位置
。初步结论
理解困惑之后
说白了这俩就是在找中间值。比如元素高10,目标位置是100那么最接近这个文素的就是第11个元素了,但是如果是101,那么第11个元素本身就是完美符合最接近偏移量的元素了。
初略看了一下代码实现,用到了二分(binarySearch)和指数查找(exponentialSearch)。准备之后去看看。
getSizeAndPositionForIndex
这块看起来蛮多的来研究一下。从名字来看是获取对应index的size和positon用的。
测试用例比较长,截图比较麻烦,一部分一部分来看。
噢噢噢,突然明白了,这个不是次数,是对应的 index 。因为访问的是 0 号,所以数组里面会有个 0。
那感觉上就会是访问一次加一条。。。我们试着多访问几次。。然鹅事实不是这样的。重复的访问只会有一条。
并且如果输入比较大的数字的话,比如3,就会变成[0,1,2,3]这样的结构。这应该要拜读源码才能理解了这个现象。感觉是为了获取正确的偏移量,需要按序的计算出之前元素的偏移量才能得出对应元素的偏移量。这个操作可能是感觉不是特别花时间,但是是可以优化的点。只要算过3,再获取2和1的时候就不需要重新计算了。不过整个算法复杂度看了一下也就O(n)吧。
下面的新的例子也印证了这一点。
优化测试。
好了本轮用例完结。
getSizeAndPositionOfLastMeasuredItem
这是getSizeAndPositionForIndex衍生出来的东西,看起来是会把值缓存下来,记录元素对应的大小(
size
)和元素的实际偏移量(offset
)。显而易见的用例。下一个。
getTotalSize
先看源码吧,这个东西源码比较短。
计算公式是:
lastMeasuredSizeAndPosition.offset + lastMeasuredSizeAndPosition.size + (this.itemCount - this.lastMeasuredIndex - 1) * this.estimatedItemSize
简化一下。我们知道
lastMeasuredSizeAndPosition
就是上个单测里的东西,表示最后测量元素
,包含size
和offset
两个属性。以下我们简称为lastOffset
和lastSize
。lastMeasuredIndex
就是最后测量元素的索引
,itemCount
就是列表的总数。estimatedItemSize
就是预计大小。那么屡一下。
lastOffset + lastSize + (this.itemCount - this.lastIndex - 1) * estimatedItemSize
对应中文:
最后一个元素的偏移量 + 最后一个元素的大小 + (总数 - 最后一个元素的位置 - 1) * 预计大小
就是总大小(totalSize)
了。再简化一下:
总大小 = 最后一个元素的偏移量 + 最后一个元素的大小 + (剩余元素个数) * 预计大小
因为我们访问到最后元素的时候,说明我们此时渲染到了这个地方。也计算过前面的元素大小了。
因为这个特性我们可以推测,如果是动态算高度的性能会很差,因为必须真正的渲染出来再计算高度。但是真实情况如何,目前不清楚。
getUpdatedOffsetForIndex
这又是一个非常大的测试块,说明这一块的功能很重要。