Performance

Tips for performance improvements for usual JointJS applications.

by Roman Bruckner

HTML

<html>

  <body>
    <!-- content -->


    <div id="canvas"></div>
    <div id="perf"></div>

    <!-- dependencies -->
    <script src="https://cdn.jsdelivr.net/npm/@joint/[email protected]/dist/joint.min.js"></script>

  </body>

</html>

CSS

#perf {
  position: fixed;
  top: 10px;
  left: 10px;
  background: lightgray;
}

JavaScript

// JointJS Performance tips

// Overall goals
// -------------
// 1. reduce number of DOM elements (See async.html demo)
// 2. avoid asking the browser for element bounding boxes as much as possible

// Number of elements 0 - ?
var COUNT = 5000;
var RELATIONS = 1;
// Async rendering true/false
// true: does not block the UI
var ASYNC = true;

var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({
  el: document.getElementById('canvas'),
  model: graph,
  async: ASYNC,
  frozen: true,
  // Avoid using joint.dia.Paper.sorting.EXACT
  // It's extremely slow for large amounts of elements.
  // There is no big difference between sorting APPROX and NONE in terms of performance.
  sorting: joint.dia.Paper.sorting.APPROX,
  // To avoid measuring of the SVGElement magnet size, you can calculate
  // the anchor point for the links manually.
/*   defaultConnectionPoint: {
    name: 'anchor'
  },
   *//*   defaultAnchor: (view, _0, _1, _2, endType) => {
    const bbox = view.model.getBBox();
    return endType === 'source' ? bbox.bottomMiddle() : bbox.topMiddle();
  }, */
  defaultRouter: { name: 'orthogonal' }
});

var Shape = joint.shapes.standard.Rectangle;
var Link = joint.shapes.standard.Link;

var el = new Shape({ size: { width: 100, height: 50 }});
var l = new Link();

var cells = [];

Array.from({
  length: COUNT / 2
}).forEach(function(_, n) {
  var cols = 100;
  var x = (n % cols) * 110;
  var y = Math.floor(n / cols);
  var a = el.clone().position(x, 100 + y * 300);
  var b = el.clone().position(x, 300 + y * 300);
  // Since at this point the elements are not in the graph / are not rendered
  // we can change the text label silently (instead of calling attr(), that would deep clone all `attrs`)
  a.attributes.attrs.label.text = n + 1;
  b.attributes.attrs.label.text = n + 1 + (COUNT / 2);

  cells.push(a, b);

  Array.from({
    length: RELATIONS
  }).forEach(function(_, m) {
    var dx = (m - RELATIONS / 2 + 0.5) * 15 + 50;
    var ab =...