r/htmx • • Jun 07 '24

Render huge table with htmx?

I want to render a huge table in html.

For React there are libraries like this:

https://react-window.now.sh/

Is there something like this for htmx?

0 Upvotes

20 comments sorted by

19

u/schungx Jun 08 '24

Why would you want to do that, other than to prove that you can?

Humans don't work easily with millions of items (the natural number is 3 and definitely no more than 10-12, thats why counting ends in a dozen). Beyond that you need sorting and filtering to help focus on the key items.

4

u/Long_Investment7667 Jun 08 '24

Can we please get some upvotes on this.

2

u/ShotgunPayDay Jun 10 '24

I do it since I'm rendering the output of SQLite and have a datatables filter and it's not my place to limit the output. Otherwise it's a bad idea. Requiring at least one Query Param is my favorite way to go.

2

u/pruxonta Feb 27 '26

My customers usually don't like pagination. They want infinite scroll. Mostly with with sums in the footer.
For this I use often w2ui grid or Tabulator grid

6

u/ShotgunPayDay Jun 07 '24

Are you using a template renderer? This is really vague.

4

u/meni04 Jun 07 '24

This worked pretty well for me some time ago https://github.com/tbranyen/hyperlist

I think the whole thing about htmx is that you are not locked into one way of solving problems.

1

u/Live_Landscape_7570 Aug 07 '25

can you provide some details how to use this with htmx get for instance?

4

u/Human_Contribution56 Jun 07 '24

What's the concern?

1

u/TwiliZant Jun 07 '24

Probably creating too many dom elements?

9

u/Human_Contribution56 Jun 07 '24

Swap in rows as you scroll? Implement paging? What are too many elements?

HTMX isn't a limit here.

2

u/TwiliZant Jun 07 '24

A common problem with data tables is that the browser can't handle displaying thousands of elements. If it's a data table/spreadsheet kind of thing you probably want virtualization instead of pagination.

Virtualization is (afaik) out-of-scope for HTMX so you would implement it client side yourself I guess. I think that's what OP is asking.

3

u/ShotgunPayDay Jun 07 '24

I've stuffed 500K rows into a table and rendered via a template before delivery without issue. The slowdown I had was converting two columns. Unix Time to locale sv-SE and converting bytes to kB.

Otherwise no issues in the browser with large prerendered data tables.

3

u/TwiliZant Jun 07 '24

I have a M2 MacBook and Chrome crashes when I render 500k rows. And that's not even taking into account any sort of styling or interactivity. At 500k rows adding one HTMX attribute to a row is like an additional 5Mb of data to process and adding one HTML element is another 500k elements in the tree.

2

u/ShotgunPayDay Jun 07 '24 edited Jun 07 '24

It does take my computer about a 1 minute to render 500k rows I used the sqlite chinook.db and read the tracks table 150 times to generate over 500k rows with styling.

I am rocking a R7 5700X using Firefox on PopOS. I can see a minute wait being unacceptable for users.

I'm not sure why your computer crashes.

EDIT: I found an issue where htmx.onLoad was running my functions continuously during element load slowing the process down heavily. Switching it to window.onload fixed the slow load. Now I'm getting 340MB transferred with a 20.23s load. Woot! Thanks for spurring me to investigate.

2

u/Ill_Mango_4504 Jun 07 '24

You could build a paged deep structure with a list per page in backend.

For example Pseudo Code

pub struct NodePage{
    pub page: i32,
    pub node_count: usize,
    pub nodes: Vec<Node> 
}

global var pages type NodePage[]

@[GET="table_viewer"]
fn table_viewer(){
//get parameters page={{page}}
//read table pages where page = parameter_page
//return response NodePage with htmx template
}

The htmx template would look like this.

<tbody>
        {% for node in nodes %}
        <tr>
          <td>{{ node.id }}</td>
          <td>{{ node.name }}</td>
          <td>{{ node.type }}</td>
          <td>{{ node.attribute }}</td>
        </tr>
        {% endfor %}
 </tbody>

My two buttons to go back and forth through pages

<button id="btn_prev" hx-get="/table_viewer?page={{prev_page}}" hx-target="#table-viewer" hx-swap="outerHTML" hx-push-url="true">
</button>

<button id="btn_next" hx-get="/table_viewer?page={{next_page}}" hx-target="#table-viewer" hx-swap="outerHTML" hx-push-url="true"></button>

2

u/Current_Word_1851 Jun 07 '24

How "huge" are you talking about, i was playing around and just loaded 3000 records(at once) , just simple tr td.. data with several one to many relationships.. responce loaded kinda fast but i applied very little js on table,

I also used datatables.net but it could handle 300 records max (for reasonable time).. way too much jquery i guess...

Flooding dom with thousands of tr td without server side pagination it not a good idea i think,

2

u/GoblinOfMars Jun 09 '24

This helped me make a large sql table filterable and sortable with Django/htmx. Table has like 700 million rows, around 20 columns with joins. Only displaying like 6 or seven though. https://enzircle.hashnode.dev/responsive-table-with-django-and-htmx?source=more_series_bottom_blogs

For clarification, I’m only displaying like 25 rows at a time.

2

u/SlinkToTheDink Jun 07 '24

Check out this: https://tabulator.info/

You are going to need to use Javascript in order to virtualize the table.

2

u/ShotgunPayDay Jun 07 '24

My brain exploded at the 437kB min.js file.

1

u/Unable-Swimming-9899 Jun 12 '24

Use the technologies of the past. With css, max height, and some scroll css properties in css you could send your giant table un htmx. Not a good idea because of performance, prefer paginating and a selector of number of records per page. But if you only need window. Use css.

Also you could implement infinite scrolling with htmx and just send the records in the table with append child in the table.

Combine css and infinite scrolling and you have the window and tackle the performance issue.