Skip to content
Permalink
Browse files
perf(b-table, b-table-lite): improve render performance (closes #4211,
  • Loading branch information
tmorehouse committed Oct 9, 2019
1 parent b852bba commit f3f42f2780d56db2b7f6f89bd0af007f8f652668
Showing with 90 additions and 9 deletions.
  1. +35 −9 src/components/table/helpers/mixin-tbody-row.js
  2. +55 −0 src/components/table/table-sticky-column.spec.js
@@ -85,28 +85,54 @@ export default {
const hasDetailsSlot = this.hasNormalizedSlot(detailsSlotName)
const formatted = this.getFormattedValue(item, field)
const key = field.key
// We only uses the helper components for sticky columns to
// improve performance of BTable/BTableLite by reducing the
// total number of vue instances created during render
const cellTag = field.stickyColumn
? field.isRowHeader
? BTh
: BTd
: field.isRowHeader
? 'th'
: 'td'
const cellVariant =
item._cellVariants && item._cellVariants[key]
? item._cellVariants[key]
: field.variant || null
const data = {
// For the Vue key, we concatenate the column index and
// field key (as field keys could be duplicated)
// TODO: Although we do prevent duplicate field keys...
// So we could change this to: `row-${rowIndex}-cell-${key}`
key: `row-${rowIndex}-cell-${colIndex}-${key}`,
class: [field.class ? field.class : '', this.getTdValues(item, key, field.tdClass, '')],
props: {
stackedHeading: this.isStacked ? field.label : null,
stickyColumn: field.stickyColumn,
variant:
item._cellVariants && item._cellVariants[key]
? item._cellVariants[key]
: field.variant || null
},
props: {},
attrs: {
'aria-colindex': String(colIndex + 1),
...(field.isRowHeader
? this.getThValues(item, key, field.thAttr, 'row', {})
: this.getTdValues(item, key, field.tdAttr, {}))
}
}
if (field.stickyColumn) {
// We are using the helper BTd or BTh
data.props = {
stackedHeading: this.isStacked ? field.label : null,
stickyColumn: field.stickyColumn,
variant: cellVariant
}
} else {
// Using native TD or TH element, so we need to
// add in the attributes and variant class
data.attrs['data-label'] =
this.isStacked && !isUndefinedOrNull(field.label) ? toString(field.label) : null
data.attrs.role = field.isRowHeader ? 'rowheader' : 'cell'
data.attrs.scope = field.isRowHeader ? 'row' : null
// Add in the variant class
if (cellVariant) {
data.class.push(`${this.dark ? 'bg' : 'table'}-${cellVariant}`)
}
}
const slotScope = {
item: item,
index: rowIndex,
@@ -135,7 +161,7 @@ export default {
$childNodes = [h('div', {}, [$childNodes])]
}
// Render either a td or th cell
return h(field.isRowHeader ? BTh : BTd, data, [$childNodes])
return h(cellTag, data, [$childNodes])
},
renderTbodyRow(item, rowIndex) {
// Renders an item's row (or rows if details supported)
@@ -0,0 +1,55 @@
import { mount } from '@vue/test-utils'
import { BTable } from './table'
import { BTd } from './td'
import { BTh } from './th'

const items = [{ a: 1, b: 2, c: 3 }, { a: 4, b: 5, c: 6 }]
const fields = [
{ key: 'a', stickyColumn: true, isRowHeader: true },
{ key: 'b', stickyColumn: true },
'c'
]

describe('table > sticky columns', () => {
it('has expected classes when sticky column is enabled', async () => {
const wrapper = mount(BTable, {
propsData: {
responsive: true,
items: items,
fields: fields
}
})

expect(wrapper).toBeDefined()
expect(wrapper.is(BTable)).toBe(true)
expect(wrapper.is('div')).toBe(true)
expect(wrapper.classes()).toContain('table-responsive')
const table = wrapper.find('table')
expect(table.classes()).toContain('table')
expect(table.classes()).toContain('b-table')

const trs = wrapper.findAll('tbody > tr')
expect(trs.length).toBe(2)

const cells = trs.at(0).findAll('th, td')
expect(cells.length).toBe(3)

// First column should be BTh with sticky classes
expect(cells.at(0).is(BTh)).toBe(true)
expect(cells.at(0).is('th')).toBe(true)
expect(cells.at(0).classes()).toContain('b-table-sticky-column')

// Second column should be BTd with sticky classes
expect(cells.at(1).is(BTd)).toBe(true)
expect(cells.at(1).is('td')).toBe(true)
expect(cells.at(1).classes()).toContain('b-table-sticky-column')

// Third column should be td
expect(cells.at(2).is(BTd)).toBe(false)
expect(cells.at(2).is(BTh)).toBe(false)
expect(cells.at(2).is('td')).toBe(true)
expect(cells.at(2).classes()).not.toContain('b-table-sticky-column')

wrapper.destroy()
})
})

0 comments on commit f3f42f2

Please sign in to comment.