Permalink
Browse files

fix(table): use stable sort algorithm to prevent SSR issues (#1399)

* Create stable-sort.js

* add stable sort to utils

* [b-table] use stableSort
  • Loading branch information...
tmorehouse committed Nov 24, 2017
1 parent 6176be6 commit 552c438ed8a7cc10726a1d82f77e1e9bbfaa37a4
Showing with 32 additions and 2 deletions.
  1. +2 −2 src/components/table/table.vue
  2. +2 −0 src/utils/index.js
  3. +28 −0 src/utils/stable-sort.js
@@ -62,7 +62,7 @@
</style>
<script>
import { warn, looseEqual, KeyCodes } from '../../utils'
import { warn, looseEqual, stableSort, KeyCodes } from '../../utils'
import { keys, assign } from '../../utils/object'
import { isArray, concat } from '../../utils/array'
import { listenOnRootMixin } from '../../mixins'
@@ -712,7 +712,7 @@
}
// Apply local Sort
if (sortBy && localSorting) {
items = items.sort(function sortItemsFn(a, b) {
items = stableSort(items, function sortItemsFn(a, b) {
let ret = null
if (typeof sortCompare === 'function') {
// Call user provided sortCompare routine
@@ -13,6 +13,7 @@ import observeDom from './observe-dom'
import pluckProps from './pluckProps'
import prefixPropName from './prefixPropName'
import { registerComponent, registerComponents, registerDirective, registerDirectives, vueUse } from './plugins'
import stableSort from './stable-sort'
import suffixPropName from './suffixPropName'
import unPrefixPropName from './unPrefixPropName'
import upperFirst from './upperFirst'
@@ -37,6 +38,7 @@ export {
registerComponents,
registerDirective,
registerDirectives,
stableSort,
suffixPropName,
upperFirst,
unPrefixPropName,
@@ -0,0 +1,28 @@
/*
* Consitant and stable sort function across JavsaScript platforms
*
* Inconsistant sorts can cause SSR problems between client and server
* such as in <b-table> if sortBy is applied to the data on server side render.
* Chrome and V8 native sorts are inconsistant/unstable
*
* This function uses native sort with fallback to index compare when the a and b
* compare returns 0
*
* Algorithm bsaed on:
* https://stackoverflow.com/questions/1427608/fast-stable-sorting-algorithm-implementation-in-javascript/45422645#45422645
*
* @param {array} array to sort
* @param {function} sortcompare function
* @return {array}
*/
export default function stableSort (array, compareFn) {
// Using `.bind(compareFn)` on the wrapped anonymous function improves
// performance by avoiding the function call setup. We don't use an arrow
// function here as it binds `this` to the `stableSort` context rather than
// the `compareFn` context, which wouldn't give us the performance increase.
return array
.map((a, index) => [ index, a ])
.sort(function (a, b) { return this(a[1], b[1]) || a[0] - b[0] }.bind(compareFn))
.map(e => e[1])
}

0 comments on commit 552c438

Please sign in to comment.