Adam Shaw 6 лет назад
Родитель
Сommit
7b7e1c7353

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

@@ -5,6 +5,7 @@ import Scroller, { OverflowValue } from './Scroller'
 import RefMap from '../util/RefMap'
 import { ColProps, SectionConfig, renderMicroColGroup, computeShrinkWidth, getScrollGridClassNames, getSectionClassNames, getNeedsYScrolling,
   renderChunkContent, getChunkVGrow, computeForceScrollbars, ChunkConfig, hasShrinkWidth, CssDimValue, getChunkClassNames } from './util'
+import { memoize } from '../util/memoize'
 
 
 export interface SimpleScrollGridProps {
@@ -32,6 +33,7 @@ const STATE_IS_SIZING = {
 
 export default class SimpleScrollGrid extends BaseComponent<SimpleScrollGridProps> {
 
+  renderMicroColGroup = memoize(renderMicroColGroup) // yucky to memoize VNodes, but much more efficient for consumers
   scrollerRefs = new RefMap<Scroller>()
   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) {
     let sectionConfigs = props.sections || []
-    let microColGroupNode = renderMicroColGroup(props.cols, state.shrinkWidth)
+    let microColGroupNode = this.renderMicroColGroup(props.cols, state.shrinkWidth)
 
     return (
       <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 res
 
   return function() {
-    if (!args || !isArraysEqual(args, arguments)) {
+    if (!args || !isArgsEqual(args, arguments, equality)) {
       args = arguments
       res = (workerFunc as any).apply(this, arguments)
     }
@@ -14,9 +13,33 @@ export function memoize<T>(workerFunc: T): T {
   } 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,
 return the previous result instead.
+TODO: somehow use memoize with equality funcs instead?
 */
 export function memoizeOutput<T>(workerFunc: T, equalityFunc: (output0, output1) => boolean): T {
   let cachedRes = null