From 22dd861233f2418a0d15d9a2f7dc478c27d2a838 Mon Sep 17 00:00:00 2001 From: Soreine Date: Tue, 1 Nov 2016 12:40:01 +0100 Subject: [PATCH 01/10] Small optimization for normalize Avoid calling refreshNode needlessly --- src/transforms/normalize.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/transforms/normalize.js b/src/transforms/normalize.js index a9b6f633c..8e6e786fc 100644 --- a/src/transforms/normalize.js +++ b/src/transforms/normalize.js @@ -105,11 +105,19 @@ export function normalizeNodeWith(transform, schema, node, prevNode) { return transform } + // For performance considerations, we will check if the transform was changed + const opCount = transform.operations.length + // Iterate over its children transform = _normalizeChildrenWith(transform, schema, node, prevNode) - // Refresh the node reference, and normalize it - node = _refreshNode(transform, node) + const hasChanged = transform.operations.length != opCount + if (hasChanged) { + // Refresh the node reference + node = _refreshNode(transform, node) + } + + // Now normalize the node itself if it still exist if (node) { transform = _normalizeNodeWith(transform, schema, node) } @@ -160,8 +168,8 @@ export function normalizeWith(transform, schema, prevDocument) { const { state } = transform const { document } = state - // Schema was not rule to edit the document if (!schema.isNormalization) { + // Schema has no normalization rules return transform } From fea1e69e726e128482b1d0a236d430e5a2859f67 Mon Sep 17 00:00:00 2001 From: Soreine Date: Tue, 1 Nov 2016 12:45:17 +0100 Subject: [PATCH 02/10] Unmemoize findDescendant --- src/models/node.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/models/node.js b/src/models/node.js index 7a7bf00a1..1cc41be47 100644 --- a/src/models/node.js +++ b/src/models/node.js @@ -1315,8 +1315,6 @@ memoize(Node, [ 'assertDescendant', 'filterDescendants', 'filterDescendantsDeep', - 'findDescendant', - 'findDescendantDeep', 'getAncestors', 'getBlocks', 'getBlocksAtRange', From 136867d2403f522a0832bc514836a8453c02cb0f Mon Sep 17 00:00:00 2001 From: Soreine Date: Tue, 1 Nov 2016 13:19:39 +0100 Subject: [PATCH 03/10] Only lookup entry once on memoize cache hit --- src/utils/memoize.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/utils/memoize.js b/src/utils/memoize.js index 059cc4e0f..47f1f63bd 100644 --- a/src/utils/memoize.js +++ b/src/utils/memoize.js @@ -11,6 +11,13 @@ import { Map } from 'immutable' const LEAF = {} +/** + * An unique value used to detect cache misses + * + * @type {Object} + */ +const NO_SET = {} + /** * Memoize all of the `properties` on a `object`. * @@ -31,7 +38,10 @@ function memoize(object, properties) { const keys = [property, ...args, LEAF] const cache = this.__cache = this.__cache || new Map() - if (cache.hasIn(keys)) return cache.getIn(keys) + const cachedValue = cache.getIn(keys, NO_SET) + if (cachedValue !== NO_SET) { + return cachedValue + } const value = original.apply(this, args) this.__cache = cache.setIn(keys, value) From 5c6e4b944c394e89e903b35b6b66bfa4870624d1 Mon Sep 17 00:00:00 2001 From: Soreine Date: Tue, 1 Nov 2016 13:30:12 +0100 Subject: [PATCH 04/10] Memoize getDescendantAtPath --- src/models/node.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/models/node.js b/src/models/node.js index 1cc41be47..32f793a9c 100644 --- a/src/models/node.js +++ b/src/models/node.js @@ -1333,6 +1333,7 @@ memoize(Node, [ 'getDecorators', 'getDepth', 'getDescendant', + 'getDescendantAtPath', 'getDescendantDecorators', 'getFirstText', 'getFragmentAtRange', From 966e2c472dcc8ee395deb7ffe0e1f00b2ed191ab Mon Sep 17 00:00:00 2001 From: Soreine Date: Tue, 1 Nov 2016 14:28:45 +0100 Subject: [PATCH 05/10] Unmemoize getClosest --- src/models/node.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/models/node.js b/src/models/node.js index 32f793a9c..a44262566 100644 --- a/src/models/node.js +++ b/src/models/node.js @@ -1326,7 +1326,6 @@ memoize(Node, [ 'getChildrenBeforeIncluding', 'getChildrenBetween', 'getChildrenBetweenIncluding', - 'getClosest', 'getClosestBlock', 'getClosestInline', 'getComponent', From c50b124d582fbde1e8eac98d4b37060f2c00911b Mon Sep 17 00:00:00 2001 From: Soreine Date: Tue, 1 Nov 2016 14:33:14 +0100 Subject: [PATCH 06/10] Unmemoize getFurthest and make it use getAncestors --- src/models/node.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/models/node.js b/src/models/node.js index a44262566..ceead7cf0 100644 --- a/src/models/node.js +++ b/src/models/node.js @@ -524,14 +524,13 @@ const Node = { */ getFurthest(key, iterator) { - let node = this.assertDescendant(key) - let furthest = null - - while (node = this.getClosest(node, iterator)) { - furthest = node + let ancestors = this.getAncestors(key) + if (!ancestors) { + throw new Error(`Could not find a descendant node with key "${key}".`) } - return furthest + // Exclude this node itself + return ancestors.rest().find(iterator) }, /** @@ -1336,7 +1335,6 @@ memoize(Node, [ 'getDescendantDecorators', 'getFirstText', 'getFragmentAtRange', - 'getFurthest', 'getFurthestBlock', 'getFurthestInline', 'getHighestChild', From f9eda89c3362bfdbf0c18062b242549dbdc547ba Mon Sep 17 00:00:00 2001 From: Soreine Date: Tue, 1 Nov 2016 14:35:44 +0100 Subject: [PATCH 07/10] Unmemoize filterDescendant --- src/models/node.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/models/node.js b/src/models/node.js index ceead7cf0..116acf6da 100644 --- a/src/models/node.js +++ b/src/models/node.js @@ -1312,8 +1312,6 @@ const Node = { memoize(Node, [ 'assertChild', 'assertDescendant', - 'filterDescendants', - 'filterDescendantsDeep', 'getAncestors', 'getBlocks', 'getBlocksAtRange', From 321a71ef2589bfab777f4ec41b4e4acd23368fa5 Mon Sep 17 00:00:00 2001 From: Soreine Date: Tue, 1 Nov 2016 14:56:02 +0100 Subject: [PATCH 08/10] Remove old validate methods --- src/models/node.js | 15 +-------------- src/models/text.js | 15 +-------------- 2 files changed, 2 insertions(+), 28 deletions(-) diff --git a/src/models/node.js b/src/models/node.js index 116acf6da..56af09654 100644 --- a/src/models/node.js +++ b/src/models/node.js @@ -1290,19 +1290,7 @@ const Node = { } else { return result } - }, - - /** - * Validate the node against a `schema`. - * - * @param {Schema} schema - * @return {Object || Void} - */ - - validate(schema) { - return schema.__validate(this) } - } /** @@ -1356,8 +1344,7 @@ memoize(Node, [ 'hasChild', 'hasDescendant', 'hasVoidParent', - 'isInlineSplitAtRange', - 'validate' + 'isInlineSplitAtRange' ]) /** diff --git a/src/models/text.js b/src/models/text.js index dd3bca369..343e24a9a 100644 --- a/src/models/text.js +++ b/src/models/text.js @@ -328,18 +328,6 @@ class Text extends new Record(DEFAULTS) { return this.merge({ characters }) } - - /** - * Validate the node against a `schema`. - * - * @param {Schema} schema - * @return {Object || Void} - */ - - validate(schema) { - return schema.__validate(this) - } - } /** @@ -349,8 +337,7 @@ class Text extends new Record(DEFAULTS) { memoize(Text.prototype, [ 'getDecorations', 'getDecorators', - 'getRanges', - 'validate', + 'getRanges' ]) /** From 6f49c3fcbc6155c81909bc3783273c54987de665 Mon Sep 17 00:00:00 2001 From: Soreine Date: Tue, 1 Nov 2016 15:50:44 +0100 Subject: [PATCH 09/10] Memoize Schema.__validate --- src/models/schema.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/models/schema.js b/src/models/schema.js index 0bd18c549..2715c23ae 100644 --- a/src/models/schema.js +++ b/src/models/schema.js @@ -1,6 +1,7 @@ import React from 'react' import isReactComponent from '../utils/is-react-component' +import memoize from '../utils/memoize' import typeOf from 'type-of' import { Record } from 'immutable' @@ -121,7 +122,6 @@ class Schema extends new Record(DEFAULTS) { value, } } - } /** @@ -222,6 +222,14 @@ function normalizeMarkComponent(render) { } } +/** + * Memoize validation for a schema + */ + +memoize(Schema.prototype, [ + '__validate' +]) + /** * Export. * From 17fa7218016242216bfca36aee2b35ab6cd4e555 Mon Sep 17 00:00:00 2001 From: Soreine Date: Tue, 1 Nov 2016 15:51:21 +0100 Subject: [PATCH 10/10] Revert "Memoize Schema.__validate" It's useless because we already compare with previous node in normalize This reverts commit 6f49c3fcbc6155c81909bc3783273c54987de665. --- src/models/schema.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/models/schema.js b/src/models/schema.js index 2715c23ae..0bd18c549 100644 --- a/src/models/schema.js +++ b/src/models/schema.js @@ -1,7 +1,6 @@ import React from 'react' import isReactComponent from '../utils/is-react-component' -import memoize from '../utils/memoize' import typeOf from 'type-of' import { Record } from 'immutable' @@ -122,6 +121,7 @@ class Schema extends new Record(DEFAULTS) { value, } } + } /** @@ -222,14 +222,6 @@ function normalizeMarkComponent(render) { } } -/** - * Memoize validation for a schema - */ - -memoize(Schema.prototype, [ - '__validate' -]) - /** * Export. *