]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
[perf] cache resolved data element options (#6579)
authorJukka Kurkela <jukka.kurkela@gmail.com>
Sat, 19 Oct 2019 13:19:12 +0000 (16:19 +0300)
committerEvert Timberg <evert.timberg+github@gmail.com>
Sat, 19 Oct 2019 13:19:12 +0000 (09:19 -0400)
* [perf] cache resolved data element options
* Address review comments
* Move uninitialized variables, update comments

src/controllers/controller.bubble.js
src/core/core.datasetController.js
src/helpers/helpers.options.js

index 8882969d48a399d808bb5517e85bfc4f92bbc97f..508e9bb34363e0a202a30c43e618a41f07e1a9d9 100644 (file)
@@ -154,6 +154,11 @@ module.exports = DatasetController.extend({
                        datasetIndex: me.index
                };
 
+               // In case values were cached (and thus frozen), we need to clone the values
+               if (me._cachedDataOpts === values) {
+                       values = helpers.extend({}, values);
+               }
+
                // Custom radius resolution
                values.radius = resolve([
                        custom.radius,
index 03a249a3fde4abff41e6609c130a60015cbb388f..0df3ed60206b6b8aaf435e4ac9b17edd853020f0 100644 (file)
@@ -290,6 +290,7 @@ helpers.extend(DatasetController.prototype, {
        _update: function(reset) {
                var me = this;
                me._configure();
+               me._cachedDataOpts = null;
                me.update(reset);
        },
 
@@ -389,13 +390,16 @@ helpers.extend(DatasetController.prototype, {
         */
        _resolveDataElementOptions: function(element, index) {
                var me = this;
+               var custom = element && element.custom;
+               var cached = me._cachedDataOpts;
+               if (cached && !custom) {
+                       return cached;
+               }
                var chart = me.chart;
                var datasetOpts = me._config;
-               var custom = element.custom || {};
                var options = chart.options.elements[me.dataElementType.prototype._type] || {};
                var elementOptions = me._dataElementOptions;
                var values = {};
-               var keys, i, ilen, key;
 
                // Scriptable options
                var context = {
@@ -405,6 +409,13 @@ helpers.extend(DatasetController.prototype, {
                        datasetIndex: me.index
                };
 
+               // `resolve` sets cacheable to `false` if any option is indexed or scripted
+               var info = {cacheable: !custom};
+
+               var keys, i, ilen, key;
+
+               custom = custom || {};
+
                if (helpers.isArray(elementOptions)) {
                        for (i = 0, ilen = elementOptions.length; i < ilen; ++i) {
                                key = elementOptions[i];
@@ -412,7 +423,7 @@ helpers.extend(DatasetController.prototype, {
                                        custom[key],
                                        datasetOpts[key],
                                        options[key]
-                               ], context, index);
+                               ], context, index, info);
                        }
                } else {
                        keys = Object.keys(elementOptions);
@@ -423,10 +434,14 @@ helpers.extend(DatasetController.prototype, {
                                        datasetOpts[elementOptions[key]],
                                        datasetOpts[key],
                                        options[key]
-                               ], context, index);
+                               ], context, index, info);
                        }
                }
 
+               if (info.cacheable) {
+                       me._cachedDataOpts = Object.freeze(values);
+               }
+
                return values;
        },
 
index 0e96a71079cab624451dc3494bad85feefe19329..0bca84dba51f8d16bf1edc87ffee38a0a4957cd2 100644 (file)
@@ -115,9 +115,12 @@ module.exports = {
         * is called with `context` as first argument and the result becomes the new input.
         * @param {number} [index] - If defined and the current value is an array, the value
         * at `index` become the new input.
+        * @param {object} [info] - object to return information about resolution in
+        * @param {boolean} [info.cacheable] - Will be set to `false` if option is not cacheable.
         * @since 2.7.0
         */
-       resolve: function(inputs, context, index) {
+       resolve: function(inputs, context, index, info) {
+               var cacheable = true;
                var i, ilen, value;
 
                for (i = 0, ilen = inputs.length; i < ilen; ++i) {
@@ -127,11 +130,16 @@ module.exports = {
                        }
                        if (context !== undefined && typeof value === 'function') {
                                value = value(context);
+                               cacheable = false;
                        }
                        if (index !== undefined && helpers.isArray(value)) {
                                value = value[index];
+                               cacheable = false;
                        }
                        if (value !== undefined) {
+                               if (info && !cacheable) {
+                                       info.cacheable = false;
+                               }
                                return value;
                        }
                }