Przeglądaj źródła

memoize colGroupNode

Adam Shaw 6 lat temu
rodzic
commit
7b7e1c7353

+ 3 - 1
packages/core/src/scrollgrid/SimpleScrollGrid.tsx

@@ -5,6 +5,7 @@ import Scroller, { OverflowValue } from './Scroller'
 import RefMap from '../util/RefMap'
 import RefMap from '../util/RefMap'
 import { ColProps, SectionConfig, renderMicroColGroup, computeShrinkWidth, getScrollGridClassNames, getSectionClassNames, getNeedsYScrolling,
 import { ColProps, SectionConfig, renderMicroColGroup, computeShrinkWidth, getScrollGridClassNames, getSectionClassNames, getNeedsYScrolling,
   renderChunkContent, getChunkVGrow, computeForceScrollbars, ChunkConfig, hasShrinkWidth, CssDimValue, getChunkClassNames } from './util'
   renderChunkContent, getChunkVGrow, computeForceScrollbars, ChunkConfig, hasShrinkWidth, CssDimValue, getChunkClassNames } from './util'
+import { memoize } from '../util/memoize'
 
 
 
 
 export interface SimpleScrollGridProps {
 export interface SimpleScrollGridProps {
@@ -32,6 +33,7 @@ const STATE_IS_SIZING = {
 
 
 export default class SimpleScrollGrid extends BaseComponent<SimpleScrollGridProps> {
 export default class SimpleScrollGrid extends BaseComponent<SimpleScrollGridProps> {
 
 
+  renderMicroColGroup = memoize(renderMicroColGroup) // yucky to memoize VNodes, but much more efficient for consumers
   scrollerRefs = new RefMap<Scroller>()
   scrollerRefs = new RefMap<Scroller>()
   scrollerElRefs = new RefMap<HTMLElement, [ChunkConfig]>(this._handleScrollerEl.bind(this))
   scrollerElRefs = new RefMap<HTMLElement, [ChunkConfig]>(this._handleScrollerEl.bind(this))
 
 
@@ -42,7 +44,7 @@ export default class SimpleScrollGrid extends BaseComponent<SimpleScrollGridProp
 
 
   render(props: SimpleScrollGridProps, state: SimpleScrollGridState, context: ComponentContext) {
   render(props: SimpleScrollGridProps, state: SimpleScrollGridState, context: ComponentContext) {
     let sectionConfigs = props.sections || []
     let sectionConfigs = props.sections || []
-    let microColGroupNode = renderMicroColGroup(props.cols, state.shrinkWidth)
+    let microColGroupNode = this.renderMicroColGroup(props.cols, state.shrinkWidth)
 
 
     return (
     return (
       <table class={getScrollGridClassNames(props.vGrow, context).join(' ')} style={{ height: props.height }}>
       <table class={getScrollGridClassNames(props.vGrow, context).join(' ')} style={{ height: props.height }}>

+ 26 - 3
packages/core/src/util/memoize.ts

@@ -1,11 +1,10 @@
-import { isArraysEqual } from './array'
 
 
-export function memoize<T>(workerFunc: T): T {
+export function memoize<T>(workerFunc: T, equality?): T {
   let args
   let args
   let res
   let res
 
 
   return function() {
   return function() {
-    if (!args || !isArraysEqual(args, arguments)) {
+    if (!args || !isArgsEqual(args, arguments, equality)) {
       args = arguments
       args = arguments
       res = (workerFunc as any).apply(this, arguments)
       res = (workerFunc as any).apply(this, arguments)
     }
     }
@@ -14,9 +13,33 @@ export function memoize<T>(workerFunc: T): T {
   } as any
   } as any
 }
 }
 
 
+// TODO: merge with isArraysEqual?
+// TODO: better solution that links the function with the equality checks. like subrenderer?
+function isArgsEqual(args0, args1, equality?) {
+  let len = args0.length
+
+  if (len !== args1.length) {
+    return false
+  }
+
+  for (let i = 0; i < len; i++) {
+    if (
+      (equality && equality[i]) ?
+        !equality[i](args0[i], args1[i]) :
+        args0[i] !== args1[i]
+    ) {
+      return false
+    }
+  }
+
+  return true
+}
+
+
 /*
 /*
 always executes the workerFunc, but if the result is equal to the previous result,
 always executes the workerFunc, but if the result is equal to the previous result,
 return the previous result instead.
 return the previous result instead.
+TODO: somehow use memoize with equality funcs instead?
 */
 */
 export function memoizeOutput<T>(workerFunc: T, equalityFunc: (output0, output1) => boolean): T {
 export function memoizeOutput<T>(workerFunc: T, equalityFunc: (output0, output1) => boolean): T {
   let cachedRes = null
   let cachedRes = null