Skip to content

Instantly share code, notes, and snippets.

@tj
Last active April 29, 2023 14:53
Show Gist options
  • Star 31 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tj/7e135a1357982edd1fd0a5649578f6ec to your computer and use it in GitHub Desktop.
Save tj/7e135a1357982edd1fd0a5649578f6ec to your computer and use it in GitHub Desktop.
shouldComponentUpdate utility
let rows = {}
export default function(props = [], state = []) {
return function(target) {
const proto = Object.create(target.prototype)
proto.shouldComponentUpdate = function(newProps, newState) {
let id = (this._update_id = this._update_id || Math.random())
for (var i = 0; i < props.length; i++) {
const name = props[i]
const oldVal = this.props[name]
const newVal = newProps[name]
if (newVal !== oldVal) {
if (localStorage.traceUpdates == '*') {
const rowName = `${target.name} prop '${name}'`
rows[rowName] = rows[rowName] || { renders: 0, instances: {} }
rows[rowName].renders++
rows[rowName].instances[id] = rows[rowName].instances[id] || 0
rows[rowName].instances[id]++
}
return true
}
}
for (var i = 0; i < state.length; i++) {
const name = state[i]
const oldVal = this.state[name]
const newVal = newState[name]
if (newVal !== oldVal) {
if (localStorage.traceUpdates == '*') {
const rowName = `${target.name} state '${name}'`
rows[rowName] = rows[rowName] || { renders: 0, instances: {} }
rows[rowName].renders++
rows[rowName].instances[id] = rows[rowName].instances[id] || 0
rows[rowName].instances[id]++
}
return true
}
}
return false
}
target.prototype = proto
}
}
function enable() {
console.log('enabled update tracing')
localStorage.traceUpdates = '*'
}
function disable() {
console.log('disabled update tracing')
localStorage.traceUpdates = ''
}
function print() {
if (Object.keys(rows).length == 0) {
console.log('nothing to print')
return
}
for (var k in rows) {
rows[k].instances = Object.keys(rows[k].instances).length
rows[k]['renders per instance'] = rows[k].renders / rows[k].instances
}
console.table(rows, ['renders', 'instances', 'renders per instance'])
rows = {}
}
window.updates = {
enable,
disable,
print
}
@update(['foo', 'bar'])
@update(['foo', 'bar'], ['state'])
@tj
Copy link
Author

tj commented May 6, 2016

screen shot 2016-05-05 at 5 25 33 pm

@tj
Copy link
Author

tj commented May 6, 2016

too lazy to npm, also pretty ad-hoc ¯_(ツ)_/¯

@kkemple
Copy link

kkemple commented May 6, 2016

awesome, thanks for this!

@Restuta
Copy link

Restuta commented Jul 13, 2016

@kkemple @tj not sure I understand how to hook it up to my components, could you please point me?

@LiuuY
Copy link

LiuuY commented Jul 21, 2016

@Restuta

import update from 'update' // TJ's update.js

@update([props1, props2]) // props1 and props2 are two props of YourComponent
class YourComponent extend React.component {
  // some logic...
}

export default YourComponent 

and in browser's console, input "updates.enable()" to enable recording, and input "updates.print()" to print result.

of course, to run this, you must use babel to compile decorator(ES2016) to ES5,
my webpack config:

    loaders:[
      {
        test: /\.js[x]?$/,
        exclude: /node_modules/,
        loader: 'babel',
        query: {
          plugins: [
            'transform-runtime',
            'transform-decorators-legacy',
          ],
          presets: ['es2015', 'react', 'stage-1'],
        }
      }
   ]

:)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment