Skip to content

perf: Enhance performance content size calculation, fixes #1223#1224

Open
muendlein wants to merge 2 commits into
6pac:masterfrom
muendlein:perf-enhance-content-size-calculation
Open

perf: Enhance performance content size calculation, fixes #1223#1224
muendlein wants to merge 2 commits into
6pac:masterfrom
muendlein:perf-enhance-content-size-calculation

Conversation

@muendlein

Copy link
Copy Markdown
Contributor

Fixes #1223

I called the function getCellValue for now but I'm open for any better name.

@muendlein

Copy link
Copy Markdown
Contributor Author

Speed up is >10x with this example:

<!DOCTYPE HTML>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  <link rel="shortcut icon" type="image/ico" href="favicon.ico" />
  <title>SlickGrid example: Column-oriented CustomDataView with getCellValue (Shadow DOM)</title>
  <link rel="stylesheet" href="../dist/styles/css/example-demo.css" type="text/css"/>
</head>
<body>
<h2 class="title">Column-oriented CustomDataView + getCellValue</h2>
<table width="100%">
  <tr>
    <td valign="top" width="50%">
      <div id="host"></div>
    </td>
  </tr>
</table>

<script src="https://cdn.jsdelivr.net/npm/sortablejs/Sortable.min.js"></script>
<script src="sortable-cdn-fallback.js"></script>

<script src="../dist/browser/slick.core.js"></script>
<script src="../dist/browser/slick.interactions.js"></script>
<script src="../dist/browser/slick.grid.js"></script>

<script>
  var grid;
  var ROW_COUNT = 1000000;
  var COL_COUNT = 10;

  var fields = [];
  for (var c = 0; c < COL_COUNT; c++) { fields.push('col' + c); }

  // Column-oriented backing store: one flat array per field instead of
  // an array of row objects. Values are random floats.
  var store = {};
  for (var i = 0; i < fields.length; i++) {
    store[fields[i]] = new Array(ROW_COUNT);
  }
  for (var r = 0; r < ROW_COUNT; r++) {
    for (var i = 0; i < fields.length; i++) {
      store[fields[i]][r] = Math.random() * Math.pow(10, 1 + (i % 6)); // varying magnitude per column
    }
  }

  // CustomDataView backed by the column-oriented store.
  // getItem() still builds a full row object (needed for normal cell
  // rendering, editors, etc.), but getCellValue() lets the grid read a
  // single field directly without paying for that when only one value
  // is needed (e.g. column content auto-sizing).
  var dataView = {
    getLength: function () { return ROW_COUNT; },
    getItem: function (i) {
      var row = {};
      for (var j = 0; j < fields.length; j++) {
        row[fields[j]] = store[fields[j]][i];
      }
      return row;
    },
    getItemMetadata: function () { return null; },
    getCellValue: function (i, field) {
      return store[field][i];
    }
  };

  var columns = fields.map(function (f, idx) {
    return {
      id: f,
      name: 'Column ' + idx,
      field: f,
      width: 300,
    };
  });

  /**
   * Build the shadow DOM. In this example, it will
   * have just a div for the grid, and a <link>
   * for the Alpine style.
   *
   * Notice that the <link> tag must be placed inside
   * the shadow DOM tree, it cannot be placed on the <head>
   * tag because the shadow DOM is unaffected by external
   * styles
   */

  var host = document.querySelector("#host");
  var shadow = host.attachShadow({ mode: "open" });
  var gridContainer = document.createElement("div");
  gridContainer.style.width = "1000px";
  gridContainer.style.height = "500px";
  gridContainer.classList.add("slick-container");
  shadow.appendChild(gridContainer);

  var linkElement = document.createElement("link");
  linkElement.type = "text/css";
  linkElement.rel = "stylesheet";
  linkElement.href = "../dist/styles/css/slick-alpine-theme.css";
  shadow.appendChild(linkElement);

  /**
   * Since the grid is inside a shadow DOM tree, we have
   * to pass the root of this tree to the option `shadowRoot`
   */

  var options = {
    enableCellNavigation: true,
    enableColumnReorder: false,
    colAutosizeTreatAsLockedBelowWidth: 0,
    autosizeColsMode: 'FCV',
    shadowRoot: shadow
  };

  /**
   * Since the <link> tag was loaded dynamically, it will take
   * some time to download the referenced css file. We must
   * wait for the style to finish loading, otherwise Slick.Grid
   * will break
   */

  linkElement.addEventListener("load", () => {
    grid = new Slick.Grid(gridContainer, dataView, columns, options);
    grid.autosizeColumns();
  });
</script>
</body>
</html>

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

getColContentSize is inefficient for column-oriented CustomDataView

1 participant