From 90f15dc04d51f60aa2c07ba04e3fa776b4008095 Mon Sep 17 00:00:00 2001 From: Luke Cotter <4013877+lukecotter@users.noreply.github.com> Date: Fri, 11 Apr 2025 17:49:04 +0100 Subject: [PATCH 1/2] perf: use weak map to track circular refs Instead of a list. On a large tree with a circular ref on every node this took deeop clone from > 5 mins to < 1 sec for me. --- src/js/core/tools/Helpers.js | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/src/js/core/tools/Helpers.js b/src/js/core/tools/Helpers.js index 078e17508..da80d41de 100644 --- a/src/js/core/tools/Helpers.js +++ b/src/js/core/tools/Helpers.js @@ -32,7 +32,7 @@ export default class Helpers{ return output; } - static deepClone(obj, clone, list = []){ + static deepClone(obj,clone, circularRefs = new WeakMap()){ var objectProto = {}.__proto__, arrayProto = [].__proto__; @@ -41,22 +41,14 @@ export default class Helpers{ } for(var i in obj) { - let subject = obj[i], - match, copy; - + let subject = obj[i]; if(subject != null && typeof subject === "object" && (subject.__proto__ === objectProto || subject.__proto__ === arrayProto)){ - match = list.findIndex((item) => { - return item.subject === subject; - }); - - if(match > -1){ - clone[i] = list[match].copy; + const match = circularRefs.get(subject); + if(match){ + clone[i] = match; }else{ - copy = Object.assign(Array.isArray(subject) ? [] : {}, subject); - - list.unshift({subject, copy}); - - clone[i] = this.deepClone(subject, copy, list); + const copy = Object.assign(Array.isArray(subject) ? [] : {}, subject); + clone[i] = this.deepClone(subject, copy, circularRefs); } } } From c293c0f44b4cbc9f24a7d481b190a711c48d2e3e Mon Sep 17 00:00:00 2001 From: Luke Cotter <4013877+lukecotter@users.noreply.github.com> Date: Tue, 15 Apr 2025 16:09:08 +0100 Subject: [PATCH 2/2] fix: add missing set in map --- src/js/core/tools/Helpers.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/js/core/tools/Helpers.js b/src/js/core/tools/Helpers.js index da80d41de..7f326017d 100644 --- a/src/js/core/tools/Helpers.js +++ b/src/js/core/tools/Helpers.js @@ -1,30 +1,28 @@ -export default class Helpers{ - - static elVisible(el){ +export default class Helpers { + static elVisible(el) { return !(el.offsetWidth <= 0 && el.offsetHeight <= 0); } - static elOffset(el){ + static elOffset(el) { var box = el.getBoundingClientRect(); return { top: box.top + window.pageYOffset - document.documentElement.clientTop, - left: box.left + window.pageXOffset - document.documentElement.clientLeft + left: box.left + window.pageXOffset - document.documentElement.clientLeft, }; } - static retrieveNestedData(separator, field, data){ + static retrieveNestedData(separator, field, data) { var structure = separator ? field.split(separator) : [field], - length = structure.length, - output; - - for(let i = 0; i < length; i++){ + length = structure.length, + output; + for (let i = 0; i < length; i++) { data = data[structure[i]]; output = data; - if(!data){ + if (!data) { break; } } @@ -48,6 +46,8 @@ export default class Helpers{ clone[i] = match; }else{ const copy = Object.assign(Array.isArray(subject) ? [] : {}, subject); + circularRefs.set(obj, copy); + clone[i] = this.deepClone(subject, copy, circularRefs); } }