@@ -28,14 +28,13 @@ export interface Range {
2828
2929type Key = number | string
3030
31- export interface VirtualItem < TItemElement extends Element > {
31+ export interface VirtualItem {
3232 key : Key
3333 index : number
3434 start : number
3535 end : number
3636 size : number
3737 lane : number
38- measureElement : ( node : TItemElement | null | undefined ) => void
3938}
4039
4140export interface Rect {
@@ -319,7 +318,7 @@ export interface VirtualizerOptions<
319318 scrollMargin ?: number
320319 gap ?: number
321320 indexAttribute ?: string
322- initialMeasurementsCache ?: Array < VirtualItem < TItemElement > >
321+ initialMeasurementsCache ?: Array < VirtualItem >
323322 lanes ?: number
324323 isScrollingResetDelay ?: number
325324 enabled ?: boolean
@@ -336,7 +335,7 @@ export class Virtualizer<
336335 targetWindow : ( Window & typeof globalThis ) | null = null
337336 isScrolling = false
338337 private scrollToIndexTimeoutId : number | null = null
339- measurementsCache : Array < VirtualItem < TItemElement > > = [ ]
338+ measurementsCache : Array < VirtualItem > = [ ]
340339 private itemSizeCache = new Map < Key , number > ( )
341340 private pendingMeasuredCacheIndexes : Array < number > = [ ]
342341 scrollRect : Rect | null = null
@@ -346,7 +345,7 @@ export class Virtualizer<
346345 shouldAdjustScrollPositionOnItemSizeChange :
347346 | undefined
348347 | ( (
349- item : VirtualItem < TItemElement > ,
348+ item : VirtualItem ,
350349 delta : number ,
351350 instance : Virtualizer < TScrollElement , TItemElement > ,
352351 ) => boolean )
@@ -414,22 +413,34 @@ export class Virtualizer<
414413 }
415414 }
416415
417- private notify = ( force : boolean , sync : boolean ) => {
418- const { startIndex, endIndex } = this . range ?? {
419- startIndex : undefined ,
420- endIndex : undefined ,
421- }
422- const range = this . calculateRange ( )
423-
424- if (
425- force ||
426- startIndex !== range ?. startIndex ||
427- endIndex !== range ?. endIndex
428- ) {
429- this . options . onChange ?.( this , sync )
430- }
416+ private notify = ( sync : boolean ) => {
417+ this . options . onChange ?.( this , sync )
431418 }
432419
420+ private maybeNotify = memo (
421+ ( ) => {
422+ this . calculateRange ( )
423+
424+ return [
425+ this . isScrolling ,
426+ this . range ? this . range . startIndex : null ,
427+ this . range ? this . range . endIndex : null ,
428+ ]
429+ } ,
430+ ( isScrolling ) => {
431+ this . notify ( isScrolling )
432+ } ,
433+ {
434+ key : process . env . NODE_ENV !== 'production' && 'maybeNotify' ,
435+ debug : ( ) => this . options . debug ,
436+ initialDeps : [
437+ this . isScrolling ,
438+ this . range ? this . range . startIndex : null ,
439+ this . range ? this . range . endIndex : null ,
440+ ] as [ boolean , number | null , number | null ] ,
441+ } ,
442+ )
443+
433444 private cleanup = ( ) => {
434445 this . unsubs . filter ( Boolean ) . forEach ( ( d ) => d ! ( ) )
435446 this . unsubs = [ ]
@@ -454,7 +465,7 @@ export class Virtualizer<
454465 this . cleanup ( )
455466
456467 if ( ! scrollElement ) {
457- this . notify ( false , false )
468+ this . maybeNotify ( )
458469 return
459470 }
460471
@@ -474,7 +485,7 @@ export class Virtualizer<
474485 this . unsubs . push (
475486 this . options . observeElementRect ( this , ( rect ) => {
476487 this . scrollRect = rect
477- this . notify ( false , false )
488+ this . maybeNotify ( )
478489 } ) ,
479490 )
480491
@@ -487,11 +498,9 @@ export class Virtualizer<
487498 : 'backward'
488499 : null
489500 this . scrollOffset = offset
490-
491- const prevIsScrolling = this . isScrolling
492501 this . isScrolling = isScrolling
493502
494- this . notify ( prevIsScrolling !== isScrolling , isScrolling )
503+ this . maybeNotify ( )
495504 } ) ,
496505 )
497506 }
@@ -524,11 +533,11 @@ export class Virtualizer<
524533 }
525534
526535 private getFurthestMeasurement = (
527- measurements : Array < VirtualItem < TItemElement > > ,
536+ measurements : Array < VirtualItem > ,
528537 index : number ,
529538 ) => {
530539 const furthestMeasurementsFound = new Map < number , true > ( )
531- const furthestMeasurements = new Map < number , VirtualItem < TItemElement > > ( )
540+ const furthestMeasurements = new Map < number , VirtualItem > ( )
532541 for ( let m = index - 1 ; m >= 0 ; m -- ) {
533542 const measurement = measurements [ m ] !
534543
@@ -645,7 +654,6 @@ export class Virtualizer<
645654 end,
646655 key,
647656 lane,
648- measureElement : this . measureElement ,
649657 }
650658 }
651659
@@ -737,7 +745,7 @@ export class Virtualizer<
737745 }
738746
739747 resizeItem = ( index : number , size : number ) => {
740- const item = this . getMeasurements ( ) [ index ]
748+ const item = this . measurementsCache [ index ]
741749 if ( ! item ) {
742750 return
743751 }
@@ -763,7 +771,7 @@ export class Virtualizer<
763771 this . pendingMeasuredCacheIndexes . push ( item . index )
764772 this . itemSizeCache = new Map ( this . itemSizeCache . set ( item . key , size ) )
765773
766- this . notify ( true , false )
774+ this . notify ( false )
767775 }
768776 }
769777
@@ -784,7 +792,7 @@ export class Virtualizer<
784792 getVirtualItems = memo (
785793 ( ) => [ this . getIndexes ( ) , this . getMeasurements ( ) ] ,
786794 ( indexes , measurements ) => {
787- const virtualItems : Array < VirtualItem < TItemElement > > = [ ]
795+ const virtualItems : Array < VirtualItem > = [ ]
788796
789797 for ( let k = 0 , len = indexes . length ; k < len ; k ++ ) {
790798 const i = indexes [ k ] !
@@ -857,7 +865,7 @@ export class Virtualizer<
857865 getOffsetForIndex = ( index : number , align : ScrollAlignment = 'auto' ) => {
858866 index = Math . max ( 0 , Math . min ( index , this . options . count - 1 ) )
859867
860- const item = this . getMeasurements ( ) [ index ]
868+ const item = this . measurementsCache [ index ]
861869 if ( ! item ) {
862870 return undefined
863871 }
@@ -1004,7 +1012,7 @@ export class Virtualizer<
10041012
10051013 measure = ( ) => {
10061014 this . itemSizeCache = new Map ( )
1007- this . options . onChange ?. ( this , false )
1015+ this . notify ( false )
10081016 }
10091017}
10101018
@@ -1034,12 +1042,12 @@ const findNearestBinarySearch = (
10341042 }
10351043}
10361044
1037- function calculateRange < TItemElement extends Element > ( {
1045+ function calculateRange ( {
10381046 measurements,
10391047 outerSize,
10401048 scrollOffset,
10411049} : {
1042- measurements : Array < VirtualItem < TItemElement > >
1050+ measurements : Array < VirtualItem >
10431051 outerSize : number
10441052 scrollOffset : number
10451053} ) {
0 commit comments