Cory Rylan

My name is , Software Developer and Speaker. Building Design Systems and Web Components.

Follow @coryrylan
Lit Web Components

High Performance HTML Tables with Lit and Virtual Scrolling

By Cory Rylan

- 2 minutes

Updated

Web applications often need to handle large amounts of data, with HTML tables being a common method for presentation. However, traditional HTML tables can become slow and unresponsive when dealing with thousands of rows. Fortunately, with Lit, a modern, lightweight web component library, and the magic of virtual scrolling, you can create high performance tables with ease.

Setting the Table

Let's start with a basic LitElement named ui-element:

import { html, LitElement } from 'lit';
import { customElement } from 'lit/decorators/custom-element.js';
import { virtualize } from '@lit-labs/virtualizer/virtualize.js';
import { styles } from './element.css.js';

@customElement('ui-element')
class Element extends LitElement {
  static styles = [styles];

  #items = new Array(10000).fill('').map((_i, n) => ({ column: `${n}-0`, column1: `${n}-1`, column2: `${n}-2`, column3: `${n}-3` }));

  render() {
    //...
  }
}

Our custom element ui-element has an array #items containing 10,000 objects, with each object having four key-value pairs. That's a lot of data for an HTML table!

Rendering with Lit

Next, we use Lit's html tagged template to create the table. We define a header using <thead>, and for each key in our item object, we render a table header <th>:

render() {
  return html`
  <table>
    <thead>
      <tr>
        ${Object.keys(this.#items[0]).map(i => html`<th>${i}</th>`)}
      </tr>
    </thead>
    <tbody>
      //...
    </tbody>
  </table>
  `;
}

Virtual Scrolling

Here comes the tricky part. If we tried to render all 10,000 rows, our application would become sluggish. Virtual scrolling is a technique that only renders the items that are currently visible in the viewport.

We leverage @lit-labs/virtualizer, a library that provides a function virtualize to achieve this:

${virtualize({ scroller: true, items: this.#items, renderItem: (i: any) => html`
  <tr>
    ${Object.keys(i).map(key => html`<td>${i[key]}</td>`)}
  </tr>`
})}

We tell virtualize to create a scrollable area with scroller: true and pass our #items array. The renderItem function takes an item and returns a template literal to generate a row <tr> with a cell <td> for each key-value pair in the item.

import { html, LitElement } from 'lit';
import { customElement } from 'lit/decorators/custom-element.js';
import { virtualize } from '@lit-labs/virtualizer/virtualize.js';
import { styles } from './element.css.js';

@customElement('ui-element')
class Element extends LitElement {
  static styles = [styles];

  #items = new Array(10000).fill('').map((_i, n) => ({ column: `${n}-0`, column1: `${n}-1`, column2: `${n}-2`, column3: `${n}-3` }));

  render() {
    return html`
    <table>
      <thead>
        <tr>
          ${Object.keys(this.#items[0]).map(i => html`<th>${i}</th>`)}
        </tr>
      </thead>
      <tbody>
        ${virtualize({ scroller: true, items: this.#items, renderItem: (i: any) => html`
          <tr>
            ${Object.keys(i).map(key => html`<td>${i[key]}</td>`)}
          </tr>`
        })}
      </tbody>
    </table>
    `;
  }
}

Conclusion

With Lit and virtual scrolling, you can efficiently manage and present large amounts of data in HTML tables. These techniques enable smooth user experiences, making your web application more responsive and performant. Check out the full working demo below!

View Demo Code   
Bluesky Facebook LinkedIn Email
 

Related Posts

Lit Web Components

Building Web Components with lit-html

A tutorial on building reusable Web Components with Lit.

Read Article
Lit Web Components

Using Import Maps and Lit Element Web Components

Learn how to use Lit based Web Components without a build step using import maps.

Read Article
Lit Web Components

Using Event Decorators with lit-element and Web Components

Learn how to make an event decorator to make it easy to emit custom events with improved type safety in Lit Web Components.

Read Article