Created
June 19, 2017 06:45
-
-
Save paulfalgout/c8f00cb8a3deb352381a20534d193f0a to your computer and use it in GitHub Desktop.
js-benchmark speed-up
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const _ = require('underscore'); | |
const Bb = require('backbone'); | |
const Mn = require('backbone.marionette'); | |
const morphdom = require('morphdom'); | |
const rowTemplate = function(data) { | |
//return `<td class="col-md-1">${ data.id }</td> | |
//<td class="col-md-4"> | |
// <a class="js-link">${ data.label }</a> | |
//</td> | |
//<td class="col-md-1"> | |
// <a class="js-del" data-id="${ data.id }"> | |
// <span class="glyphicon glyphicon-remove" aria-hidden="true"></span> | |
// </a> | |
//</td> | |
//<td class="col-md-6"></td>`; | |
//} | |
const tr = document.createElement('tr'); | |
const td1 = document.createElement('td'); | |
td1.className = 'col-md-1'; | |
td1.innerText = data.id; | |
tr.appendChild(td1); | |
const td2 = document.createElement('td'); | |
td2.className = 'col-md-4'; | |
tr.appendChild(td2); | |
const a2 = document.createElement('a'); | |
a2.className = 'js-link'; | |
td2.appendChild(a2); | |
a2.innerText = data.label; | |
const td3 = document.createElement('td'); | |
td3.className = 'col-md-1'; | |
tr.appendChild(td3); | |
const a = document.createElement('a'); | |
a.className = 'js-del'; | |
a.dataset.id = data.id; | |
td3.appendChild(a); | |
const span = document.createElement('span'); | |
span.className = 'glyphicon glyphicon-remove'; | |
span.setAttribute('aria-hidden', 'true'); | |
a.appendChild(span); | |
const td4 = document.createElement('td'); | |
td4.className = 'col-md-6'; | |
tr.appendChild(td4); | |
return tr; | |
} | |
var startTime; | |
var lastMeasure; | |
var startMeasure = function(name) { | |
console.profile(name); | |
startTime = performance.now(); | |
lastMeasure = name; | |
} | |
var stopMeasure = function() { | |
var last = lastMeasure; | |
if (lastMeasure) { | |
console.profileEnd(lastMeasure); | |
window.setTimeout(function () { | |
lastMeasure = null; | |
var stop = performance.now(); | |
var duration = 0; | |
console.log(last+" took "+(stop-startTime)); | |
}, 0); | |
} | |
} | |
function _random(max) { | |
return Math.round(Math.random()*1000)%max; | |
} | |
const Store = Bb.Collection.extend({ | |
initialize() { | |
this.id = 1; | |
this.on('reset update', this.clearSelected); | |
}, | |
buildData(count = 1000) { | |
var adjectives = ["pretty", "large", "big", "small", "tall", "short", "long", "handsome", "plain", "quaint", "clean", "elegant", "easy", "angry", "crazy", "helpful", "mushy", "odd", "unsightly", "adorable", "important", "inexpensive", "cheap", "expensive", "fancy"]; | |
var colours = ["red", "yellow", "blue", "green", "pink", "brown", "purple", "brown", "white", "black", "orange"]; | |
var nouns = ["table", "chair", "house", "bbq", "desk", "car", "pony", "cookie", "sandwich", "burger", "pizza", "mouse", "keyboard"]; | |
var data = []; | |
for (var i = 0; i < count; i++) | |
data.push({id: this.id++, label: adjectives[_random(adjectives.length)] + " " + colours[_random(colours.length)] + " " + nouns[_random(nouns.length)] }); | |
return data; | |
}, | |
clearSelected() { | |
if(this.curSelected) { | |
this.curSelected.classList.remove('danger'); | |
this.curSelected = null; | |
} | |
}, | |
updateData(mod = 10) { | |
startMeasure("update"); | |
for (let i=0;i<this.models.length;i+=10) { | |
const label = this.models[i].get('label'); | |
this.models[i].set('label', label + ' !!!'); | |
} | |
stopMeasure(); | |
}, | |
delete(id) { | |
startMeasure("delete"); | |
this.trigger('removeRow', this.get(id)); | |
this.remove(id, { silent: true }); | |
stopMeasure(); | |
}, | |
run() { | |
startMeasure("run"); | |
this.trigger('clear'); | |
this.reset(this.buildData()); | |
stopMeasure(); | |
}, | |
addData() { | |
startMeasure("add"); | |
this.add(this.buildData(1000)); | |
stopMeasure(); | |
}, | |
select(target) { | |
startMeasure("select"); | |
if(this.curSelected) this.curSelected.classList.remove('danger'); | |
this.curSelected = target.parentNode.parentNode; | |
this.curSelected.classList.add('danger'); | |
stopMeasure(); | |
}, | |
runLots() { | |
startMeasure("runLots"); | |
this.trigger('clear'); | |
this.reset(this.buildData(10000)); | |
stopMeasure(); | |
}, | |
clear() { | |
startMeasure("clear"); | |
this.trigger('clear'); | |
this.reset(); | |
stopMeasure(); | |
}, | |
swapRows() { | |
startMeasure("swapRows"); | |
if (this.length > 10) { | |
const a = this.models[4]; | |
this.models[4] = this.models[9]; | |
this.models[9] = a; | |
this.trigger('swapRows', this.models[4], this.models[9]); | |
} | |
stopMeasure(); | |
} | |
}); | |
const store = new Store(); | |
const ChildView = Mn.View.extend({ | |
_areViewEventsMonitored: true, // TODO: need opt-out view monitor | |
initialize() { | |
this.listenTo(this.model, 'change:label', this.render); | |
}, | |
setElement() {}, | |
_setAttributes() {}, | |
template: rowTemplate, | |
serializeData() { | |
return this.model.attributes; | |
}, | |
attachElContent(el) { | |
if(this.isRendered()) morphdom(this.el, el, { onlyChildren: true }); | |
else this.el = el; | |
}, | |
destroy() { | |
this.stopListening(); | |
} | |
}); | |
const CollectionView = Mn.NextCollectionView.extend({ | |
viewComparator: false, // TODO new API | |
el: '#tbody', | |
childView: ChildView, | |
initialize() { | |
this.listenTo(this.collection, { | |
'clear': this.onClear, | |
'swapRows': this.onSwapRows, | |
'removeRow': this.onRemoveRow | |
}); | |
}, | |
events: { | |
'click .js-link'(e) { | |
this.collection.select(e.currentTarget); | |
}, | |
'click .js-del'(e) { | |
this.collection.delete(e.currentTarget.dataset.id); | |
} | |
}, | |
childViewEventPrefix: false, | |
appendChildren(el, els) { | |
el.appendChild(els); | |
}, | |
attachHtml(view, els) { | |
this.appendChildren(this.el, els); | |
}, | |
onClear() { | |
this.el.textContent = ''; | |
}, | |
onSwapRows(model1, model2) { | |
const el1 = this.children.findByModel(model1).el; | |
const el2 = this.children.findByModel(model2).el; | |
const parent1 = el1.parentNode; | |
const next1 = el1.nextSibling; | |
const parent2 = el2.parentNode; | |
const next2 = el2.nextSibling; | |
parent1.insertBefore(el2, next1); | |
parent2.insertBefore(el1, next2); | |
}, | |
onRemoveRow(model) { | |
const view = this.children.findByModel(model); | |
this.el.removeChild(view.el); | |
this.removeChildView(view); | |
} | |
}); | |
const collectionView = new CollectionView({ | |
collection: store | |
}); | |
collectionView.render(); | |
const MainView = Mn.View.extend({ | |
el : '.jumbotron', | |
triggers: { | |
'click #run': 'run', | |
'click #runlots': 'runLots', | |
'click #add': 'add', | |
'click #update': 'update', | |
'click #clear': 'clear', | |
'click #swaprows': 'swapRows' | |
}, | |
onRun() { | |
store.run(); | |
}, | |
onRunLots() { | |
store.runLots(); | |
}, | |
onAdd() { | |
store.addData(); | |
}, | |
onUpdate() { | |
store.updateData(); | |
}, | |
onClear() { | |
store.clear(); | |
}, | |
onSwapRows() { | |
store.swapRows(); | |
} | |
}); | |
new MainView(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment