clientIO/joint

[Performance]: Backbone's set is checking too many attributes

alexandernst opened this issue · 2 comments

What happened?

While in a debugging session, I stumbled across something that caught my attention. Backbone is performing checks against all attributes of a cell, even if is impossible for them to have been changed.

Let me setup a small example. Lets say we have something like this:

var c1 = new joint.shapes.standard.Rectangle({});
c1.addTo(graph);

c1.attr({
  label: {
    textWrap: {
      text: `foo`
    }
  }
});

The .attr() method will call Cell.mjs:attr() with the following parameters:

image

Then Cell.mjs:prop() will be called with the following parameters:

image

At the very end of that method, a call to this.set() will be issued:

image

That call will take us to the set method of Backbone.

image

Note that the key parameter is actually an object that contains all the attributes of my cell. This causes backbone to set the attrs variable to the entire object, which then leads to backbone iterating over each one of the attributes and issuing 2 _.isEqual() calls per attribute (which is a very expensive call).

I would expect the Cell.mjs:prop() method to call backbone's set method only with the keys that were actually modified (in my case that would be attrs).

Playground to debug the issue: https://codesandbox.io/s/jj-backbone-set-performance-bug-q9skz4?file=/src/index.js:527-700

Version

3.7.5

What browsers are you seeing the problem on?

Firefox, Chrome, Safari

What operating system are you seeing the problem on?

Mac

Good point!

Fixed in #2329.