From 0c6f5f8217d3e69adfca75ef19bd9e8206da3084 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 3 Sep 2019 18:21:46 -0300 Subject: [PATCH 1/7] perf(b-table): cache cell slot names each render --- src/components/table/helpers/mixin-tbody.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/components/table/helpers/mixin-tbody.js b/src/components/table/helpers/mixin-tbody.js index fe304ed8a49..547fa005374 100644 --- a/src/components/table/helpers/mixin-tbody.js +++ b/src/components/table/helpers/mixin-tbody.js @@ -30,6 +30,27 @@ export default { } else { // Table isn't busy, or we don't have a busy slot + // Create a slot cache for improved performace when looking up cell slot names. + // Values will be keyed by the field's `key` and will store the slot's name. + // Slots could be dynamic (i.e. `v-if`), so we must compute on each render. + // Used by tbodyRow mixin render helper. + const cache = {} + this.computedFields.forEach(field => { + const key = field.key + // Default cell slot name + cache[key] = 'cell()' + // Data cell slot names can also be one of the following: + const slotNames = [`cell(${key})`, `cell(${key.toLowerCase()})`] + for (let i = 0; i < slotNames.length && !cache[key]; i++) { + const name = slotNames[i] + if (this.hasNormalizedSlot(name)) { + cache[key] = name + } + } + }) + // Created as a non-reactive property so to not trigger component updates. + this.$_bodyFieldSlotNameCache = cache + // Add static Top Row slot (hidden in visibly stacked mode as we can't control data-label attr) $rows.push(this.renderTopRow ? this.renderTopRow() : h()) From a5c07b52c9d0ad9243833cda134d38da68f4a347 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 3 Sep 2019 18:33:35 -0300 Subject: [PATCH 2/7] Update mixin-tbody.js --- src/components/table/helpers/mixin-tbody.js | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/components/table/helpers/mixin-tbody.js b/src/components/table/helpers/mixin-tbody.js index 547fa005374..e6453c56abb 100644 --- a/src/components/table/helpers/mixin-tbody.js +++ b/src/components/table/helpers/mixin-tbody.js @@ -37,16 +37,14 @@ export default { const cache = {} this.computedFields.forEach(field => { const key = field.key - // Default cell slot name - cache[key] = 'cell()' - // Data cell slot names can also be one of the following: - const slotNames = [`cell(${key})`, `cell(${key.toLowerCase()})`] - for (let i = 0; i < slotNames.length && !cache[key]; i++) { - const name = slotNames[i] - if (this.hasNormalizedSlot(name)) { - cache[key] = name - } - } + const fullName = `cell(${key})` + const lowerName = `cell(${key.toLowerCase()})` + cache[key] = + this.hasNormalizedSlot(fullName) + ? fullName + : this.hasNormalizedSlot(lowerName) + ? lowerName + : 'cell()' }) // Created as a non-reactive property so to not trigger component updates. this.$_bodyFieldSlotNameCache = cache From 3b659bb328b63a7fd8172a7de6ce702fc7025ac2 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 3 Sep 2019 18:34:56 -0300 Subject: [PATCH 3/7] Update mixin-tbody.js --- src/components/table/helpers/mixin-tbody.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/table/helpers/mixin-tbody.js b/src/components/table/helpers/mixin-tbody.js index e6453c56abb..f7452ea1279 100644 --- a/src/components/table/helpers/mixin-tbody.js +++ b/src/components/table/helpers/mixin-tbody.js @@ -47,6 +47,7 @@ export default { : 'cell()' }) // Created as a non-reactive property so to not trigger component updates. + // Must be a fresh object each render. this.$_bodyFieldSlotNameCache = cache // Add static Top Row slot (hidden in visibly stacked mode as we can't control data-label attr) From 244e7c28328260c2a815e0b10ff97e9eff78587b Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 3 Sep 2019 18:37:51 -0300 Subject: [PATCH 4/7] Update mixin-tbody.js --- src/components/table/helpers/mixin-tbody.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/components/table/helpers/mixin-tbody.js b/src/components/table/helpers/mixin-tbody.js index f7452ea1279..5de4b33cccb 100644 --- a/src/components/table/helpers/mixin-tbody.js +++ b/src/components/table/helpers/mixin-tbody.js @@ -39,12 +39,11 @@ export default { const key = field.key const fullName = `cell(${key})` const lowerName = `cell(${key.toLowerCase()})` - cache[key] = - this.hasNormalizedSlot(fullName) - ? fullName - : this.hasNormalizedSlot(lowerName) - ? lowerName - : 'cell()' + cache[key] = this.hasNormalizedSlot(fullName) + ? fullName + : this.hasNormalizedSlot(lowerName) + ? lowerName + : 'cell()' }) // Created as a non-reactive property so to not trigger component updates. // Must be a fresh object each render. From f3b9b72c0e76bfca032479dd385b19a200a3bb32 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 3 Sep 2019 18:49:33 -0300 Subject: [PATCH 5/7] Update mixin-tbody.js --- src/components/table/helpers/mixin-tbody.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/table/helpers/mixin-tbody.js b/src/components/table/helpers/mixin-tbody.js index 5de4b33cccb..45e83bc07a0 100644 --- a/src/components/table/helpers/mixin-tbody.js +++ b/src/components/table/helpers/mixin-tbody.js @@ -35,6 +35,7 @@ export default { // Slots could be dynamic (i.e. `v-if`), so we must compute on each render. // Used by tbodyRow mixin render helper. const cache = {} + const defaultSlotName = this.hasNormalizedSlot('cell()') ? 'cell()' : null this.computedFields.forEach(field => { const key = field.key const fullName = `cell(${key})` @@ -43,7 +44,7 @@ export default { ? fullName : this.hasNormalizedSlot(lowerName) ? lowerName - : 'cell()' + : defaultSlotName }) // Created as a non-reactive property so to not trigger component updates. // Must be a fresh object each render. From 160465025cb5ddf0cf8e927a8da962c593cbad32 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 3 Sep 2019 18:51:51 -0300 Subject: [PATCH 6/7] Update mixin-tbody-row.js --- src/components/table/helpers/mixin-tbody-row.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/table/helpers/mixin-tbody-row.js b/src/components/table/helpers/mixin-tbody-row.js index 88dc3f74b2e..917f264fa51 100644 --- a/src/components/table/helpers/mixin-tbody-row.js +++ b/src/components/table/helpers/mixin-tbody-row.js @@ -205,10 +205,11 @@ export default { // v-slot attributes are lower-cased by the browser. // Switched to round bracket syntax to prevent confusion with // dynamic slot name syntax. - const slotNames = [`cell(${key})`, `cell(${key.toLowerCase()})`, 'cell()'] - let $childNodes = this.hasNormalizedSlot(slotNames) - ? this.normalizeSlot(slotNames, slotScope) - : toString(formatted) + // const slotNames = [`cell(${key})`, `cell(${key.toLowerCase()})`, 'cell()'] + // Slot names are now cached by mixin tbody in `this.$_bodyFieldSlotNameCache` + // Will be `null` if no slot (or fallback slot) exists + const slotName = this.$_bodyFieldSlotNameCache[key] + let $childNodes = slotName ? this.normalizeSlot(slotName, slotScope) : toString(formatted) if (this.isStacked) { // We wrap in a DIV to ensure rendered as a single cell when visually stacked! $childNodes = [h('div', {}, [$childNodes])] From f07bfad0c4a9e2d34265eb78a91403f331077bf7 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 3 Sep 2019 22:10:48 -0300 Subject: [PATCH 7/7] Update mixin-tbody-row.js --- src/components/table/helpers/mixin-tbody-row.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/table/helpers/mixin-tbody-row.js b/src/components/table/helpers/mixin-tbody-row.js index 917f264fa51..f5f86f3bdc1 100644 --- a/src/components/table/helpers/mixin-tbody-row.js +++ b/src/components/table/helpers/mixin-tbody-row.js @@ -205,7 +205,7 @@ export default { // v-slot attributes are lower-cased by the browser. // Switched to round bracket syntax to prevent confusion with // dynamic slot name syntax. - // const slotNames = [`cell(${key})`, `cell(${key.toLowerCase()})`, 'cell()'] + // We look for slots in this order: `cell(${key})`, `cell(${key.toLowerCase()})`, 'cell()' // Slot names are now cached by mixin tbody in `this.$_bodyFieldSlotNameCache` // Will be `null` if no slot (or fallback slot) exists const slotName = this.$_bodyFieldSlotNameCache[key]