TreeView Performance (Vue)

The TreeView control creates DOM elements for each node in the itemsSource array. This sample below shows the performance of the TreeView when binding to sources of different sizes.

This example uses Vue.

<template> <div class="container-fluid"> <div class="row"> <div class="col-xs-5"> <label for="cmbLevels">Levels:</label> <wj-combo-box :items-source="levels" :selected-value="level" :text-changed="levelChanged" /> <br> <label for="cmbLevels">Nodes/Level:</label> <wj-combo-box :items-source="nodesPerLevel" :selected-value="nodes" :text-changed="nodesChanged" /> <br /> <label></label> <button class="btn btn-primary" id="bind" @click="refresh"> Bind Tree </button> <div id="bindingMsg" v-html="bindingMsg"></div> </div> <div class="col-xs-7"> <wj-tree-view display-member-path="header" child-items-path="items" :items-source="treeData" :initialized="initTree" /> </div> </div> </div> </template> <script> import "bootstrap.css"; import "@grapecity/wijmo.styles/wijmo.css"; import Vue from "vue"; import "@grapecity/wijmo.vue2.input"; import "@grapecity/wijmo.vue2.nav"; import { format } from "@grapecity/wijmo"; let App = Vue.extend({ name: "app", data: function() { return { levels: [1, 2, 3], level: 2, nodesPerLevel: [5, 10, 20, 40], nodes: 5, treeData: this.getData(5, 2), bindingMsg: null, treeView: null }; }, methods: { levelChanged: function(s) { this.level = s.selectedValue; }, nodesChanged: function(s) { this.nodes = s.selectedValue; }, initTree: function(s) { this.treeView = s; }, // get an array with hierarchical data for the tree getData: function(cnt, levels) { var nodes = []; for (var i = 0; i < cnt; i++) { nodes.push(this.getNode(0, i, cnt, levels)) } return nodes; }, getNode: function(level, id, cnt, levels) { // create parent node var node = { header: 'Node ' + (level + 1) + '.' + (id + 1), }; // create child nodes if (level < levels - 1) { node.items = []; for (var i = 0; i < cnt; i++) { node.items.push(this.getNode(level + 1, i, cnt, levels)) } } // done return node; }, // bind the tree to a new data source and measure how long it took refresh: function() { var start = Date.now(); this.treeView.itemsSource = this.getData(this.nodes, this.level); this.treeView.loadTree(); // force immediate refresh this.bindingMsg = format('Bound to <b>{cnt:no}</b> nodes in <b>{ms:n0}</b> ms.', { cnt: this.treeView.totalItemCount, ms: Date.now() - start }); } } }); new Vue({ render: h => h(App) }).$mount("#app"); </script> <style> .container-fluid .wj-treeview { height: 350px; font-size: 120%; margin-top: 8px; margin-bottom: 8px; padding: 6px; background: #f0f0f0; box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23); } .container-fluid .wj-combobox { width: 120px; } .container-fluid label { width: 120px; text-align: right; margin-bottom: 12px; } body { margin-bottom: 24pt; } </style>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity Wijmo TreeView Performance</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app.vue'); </script> </head> <body> <div id="app"> </div> </body> </html>
(function (global) { System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true }, meta: { '*.css': { loader: 'css' }, '*.vue': { loader: 'vue-loader' } //'*.vue': { loader: 'systemjs-plugin-vue' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { '@grapecity/wijmo': 'npm:@grapecity/wijmo/index.js', '@grapecity/wijmo.input': 'npm:@grapecity/wijmo.input/index.js', '@grapecity/wijmo.styles': 'npm:@grapecity/wijmo.styles', '@grapecity/wijmo.cultures': 'npm:@grapecity/wijmo.cultures', '@grapecity/wijmo.chart': 'npm:@grapecity/wijmo.chart/index.js', '@grapecity/wijmo.chart.analytics': 'npm:@grapecity/wijmo.chart.analytics/index.js', '@grapecity/wijmo.chart.animation': 'npm:@grapecity/wijmo.chart.animation/index.js', '@grapecity/wijmo.chart.annotation': 'npm:@grapecity/wijmo.chart.annotation/index.js', '@grapecity/wijmo.chart.finance': 'npm:@grapecity/wijmo.chart.finance/index.js', '@grapecity/wijmo.chart.finance.analytics': 'npm:@grapecity/wijmo.chart.finance.analytics/index.js', '@grapecity/wijmo.chart.hierarchical': 'npm:@grapecity/wijmo.chart.hierarchical/index.js', '@grapecity/wijmo.chart.interaction': 'npm:@grapecity/wijmo.chart.interaction/index.js', '@grapecity/wijmo.chart.radar': 'npm:@grapecity/wijmo.chart.radar/index.js', '@grapecity/wijmo.chart.render': 'npm:@grapecity/wijmo.chart.render/index.js', '@grapecity/wijmo.chart.webgl': 'npm:@grapecity/wijmo.chart.webgl/index.js', '@grapecity/wijmo.gauge': 'npm:@grapecity/wijmo.gauge/index.js', '@grapecity/wijmo.grid': 'npm:@grapecity/wijmo.grid/index.js', '@grapecity/wijmo.grid.detail': 'npm:@grapecity/wijmo.grid.detail/index.js', '@grapecity/wijmo.grid.filter': 'npm:@grapecity/wijmo.grid.filter/index.js', '@grapecity/wijmo.grid.search': 'npm:@grapecity/wijmo.grid.search/index.js', '@grapecity/wijmo.grid.grouppanel': 'npm:@grapecity/wijmo.grid.grouppanel/index.js', '@grapecity/wijmo.grid.multirow': 'npm:@grapecity/wijmo.grid.multirow/index.js', '@grapecity/wijmo.grid.transposed': 'npm:@grapecity/wijmo.grid.transposed/index.js', '@grapecity/wijmo.grid.pdf': 'npm:@grapecity/wijmo.grid.pdf/index.js', '@grapecity/wijmo.grid.sheet': 'npm:@grapecity/wijmo.grid.sheet/index.js', '@grapecity/wijmo.grid.xlsx': 'npm:@grapecity/wijmo.grid.xlsx/index.js', '@grapecity/wijmo.grid.selector': 'npm:@grapecity/wijmo.grid.selector/index.js', '@grapecity/wijmo.grid.cellmaker': 'npm:@grapecity/wijmo.grid.cellmaker/index.js', '@grapecity/wijmo.nav': 'npm:@grapecity/wijmo.nav/index.js', '@grapecity/wijmo.odata': 'npm:@grapecity/wijmo.odata/index.js', '@grapecity/wijmo.olap': 'npm:@grapecity/wijmo.olap/index.js', '@grapecity/wijmo.pdf': 'npm:@grapecity/wijmo.pdf/index.js', '@grapecity/wijmo.viewer': 'npm:@grapecity/wijmo.viewer/index.js', '@grapecity/wijmo.xlsx': 'npm:@grapecity/wijmo.xlsx/index.js', '@grapecity/wijmo.undo': 'npm:@grapecity/wijmo.undo/index.js', '@grapecity/wijmo.interop.grid': 'npm:@grapecity/wijmo.interop.grid/index.js', '@grapecity/wijmo.touch': 'npm:@grapecity/wijmo.touch/index.js', '@grapecity/wijmo.cloud': 'npm:@grapecity/wijmo.cloud/index.js', "@grapecity/wijmo.vue2.chart.analytics": "npm:@grapecity/wijmo.vue2.chart.analytics/index.js", "@grapecity/wijmo.vue2.chart.animation": "npm:@grapecity/wijmo.vue2.chart.animation/index.js", "@grapecity/wijmo.vue2.chart.annotation": "npm:@grapecity/wijmo.vue2.chart.annotation/index.js", "@grapecity/wijmo.vue2.chart.finance.analytics": "npm:@grapecity/wijmo.vue2.chart.finance.analytics/index.js", "@grapecity/wijmo.vue2.chart.finance": "npm:@grapecity/wijmo.vue2.chart.finance/index.js", "@grapecity/wijmo.vue2.chart.hierarchical": "npm:@grapecity/wijmo.vue2.chart.hierarchical/index.js", "@grapecity/wijmo.vue2.chart.interaction": "npm:@grapecity/wijmo.vue2.chart.interaction/index.js", "@grapecity/wijmo.vue2.chart.radar": "npm:@grapecity/wijmo.vue2.chart.radar/index.js", "@grapecity/wijmo.vue2.chart": "npm:@grapecity/wijmo.vue2.chart/index.js", "@grapecity/wijmo.vue2.core": "npm:@grapecity/wijmo.vue2.core/index.js", "@grapecity/wijmo.vue2.gauge": "npm:@grapecity/wijmo.vue2.gauge/index.js", "@grapecity/wijmo.vue2.grid.detail": "npm:@grapecity/wijmo.vue2.grid.detail/index.js", "@grapecity/wijmo.vue2.grid.filter": "npm:@grapecity/wijmo.vue2.grid.filter/index.js", "@grapecity/wijmo.vue2.grid.grouppanel": "npm:@grapecity/wijmo.vue2.grid.grouppanel/index.js", '@grapecity/wijmo.vue2.grid.search': 'npm:@grapecity/wijmo.vue2.grid.search/index.js', "@grapecity/wijmo.vue2.grid.multirow": "npm:@grapecity/wijmo.vue2.grid.multirow/index.js", "@grapecity/wijmo.vue2.grid.sheet": "npm:@grapecity/wijmo.vue2.grid.sheet/index.js", '@grapecity/wijmo.vue2.grid.transposed': 'npm:@grapecity/wijmo.vue2.grid.transposed/index.js', "@grapecity/wijmo.vue2.grid": "npm:@grapecity/wijmo.vue2.grid/index.js", "@grapecity/wijmo.vue2.input": "npm:@grapecity/wijmo.vue2.input/index.js", "@grapecity/wijmo.vue2.olap": "npm:@grapecity/wijmo.vue2.olap/index.js", "@grapecity/wijmo.vue2.viewer": "npm:@grapecity/wijmo.vue2.viewer/index.js", "@grapecity/wijmo.vue2.nav": "npm:@grapecity/wijmo.vue2.nav/index.js", "@grapecity/wijmo.vue2.base": "npm:@grapecity/wijmo.vue2.base/index.js", 'bootstrap.css': 'npm:bootstrap/dist/css/bootstrap.min.css', 'jszip': 'npm:jszip/dist/jszip.js', 'css': 'npm:systemjs-plugin-css/css.js', 'vue': 'npm:vue/dist/vue.min.js', 'vue-loader': 'npm:systemjs-vue-browser/index.js', //'systemjs-plugin-vue': 'npm:systemjs-plugin-vue/index.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', 'systemjs-babel-build': 'npm:systemjs-plugin-babel/systemjs-babel-browser.js' }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'js' }, rxjs: { defaultExtension: 'js' }, "node_modules": { defaultExtension: 'js' }, wijmo: { defaultExtension: 'js', } } }); })(this);