This is because the <table> element introduces a lot of design constraints.
There is a lot of inhernt styling that would have to be overridden if a table element was to be used. it could also mess with the standard behaviour of other table elements that have been generically styled.
Importantly when you start building interactive complex tables there are 100's of different types of elements needed to make the table function correctly that a standard HTML element simple isn't designed to handle, event making the header and the body scroll separately requirements more elements that a standard table can handle and it would invalid HTML to use the tags inside the table that would be needed to achieve it.
Especially when you move into the world of the virtual DOM a standard table element simply wont cut it
With the inclusion of aria tags there are no accessibility issues as screen readers treat them just as any other tables.
The virtual DOM, while very impressive, isn't necessary as well. Really depends on what problem you are solving there and what level of support you need for browsers. What problem are you solving? Many entries? Minimal cell mutation control?
For large data sets it makes the table work regardless of the number of rows
Lets say we are working with 10,000 rows
Yes loading that many elements into the DOM is slow and your approach would stop it blocking, however what it dosnt do is stop the sheer number of elements from overloading the DOM.
Most browsers simply cant handle that many elements in the DOM, if you try and scroll a div containing that may elements at best it will be sluggish and at worst it will simply crash the browser. on devices without much memory it is very likely that the whole DOM will freeze up and make the site unusable.
By adding and deleting the elements as they become visible/hidden it keeps the number of elements in the DOM to a minimum, while improving load time and adding only a bit of extra processing to the scroll event, which modern browsers can handle with ease. giving all round the best solution
I did this myself when writing a chat client's infinite history scrollback. Chat messages that aren't on the screen still have a pure-data "event" representation of them loaded, but their DOM representation (virtual or otherwise) is entirely discarded. Rather than the physical DOM nodes for chat-message divs having fixed positions such that they're able to disappear without affecting their peers' layout, I instead just have the chat messages stacked as regular block elements under reflow, with two fixed-size "scroll pad" divs just above and below the viewport "consuming" and "releasing" the vertical height that had been taken up by message divs as they're added and removed. You can have millions of rows "loaded" (in the sense of parsed data sitting in JS memory) for instant access, with not much browser memory usage at all.
Though, even that memory usage was too much (this chat client is supposed to run beside memory-intensive apps like games), so as well, in my setup, nodes that are far enough off the screen can have their parsed "event" representation discarded, and replaced with a single URL representing the serialized "history chunk" that those events came from. When the scroll distance comes close to them, the chunks are reloaded by re-requesting and re-parsing the chunk (which, helpfully, is usually still in the browser cache.)
- With <div>, you have complete control over the positioning of the cells. With <table>, you delegate the layout to the browser engine. - <table> has lots of semantic meaning, which makes it slower to render than a <div>, because the browser engine needs to make a sense of it. - There are differences in how <table>s are rendered in various browsers. This is especially a problem with old browsers such as IE6. - It is trickier to implement things like floating headers, virtual scrolling with <table>
Still, Handsontable uses <table> because you can overcome these problems if you're motivated enough. The biggest benefit is that <table> gives you enhanced semantics, which are good for Accessibility, SEO or any other form of code processing.
Complex interactive tables need a great number of elements to make them run and these wont conform to the standards of using a table (you cant just put a div inside a tbody element) but that is exactly what you would need to to to get a table with a virtual DOM to work correctly.
There are a lot of different styling tweaks that would need to be overriden for each element, some of which arnt consistent across each browser.
Also people have a tendency to put styles on the generic table tab to style tables across the site. if Tabulator was to then be used on the page, it could have any number of unknown CSS properties set on it, so would essentially have to look at overriding all possible style properties.
where as no one generically styles divs or spans and they come with very little built in styling making them the ideal choice for a library that wants to keeps its functionality isolated from the rest of the site
I have to ask: is this really slower overall? I didn't try to make an exact 1:1 comparison, but in my experience, all JS-powered table libraries I've seen start choking around a couple hundred elements. With HTML tables + minimal styling, I can dump 10k+ rows with no performance penalty.
But when you start dealing with large volumes of data they quickly become the only option.
Even a plain html table with say 10 columns will crash out /massively slow down a browser if you load in 100,000 rows of data.
Browsers simply aren't able to process that may elements being added to the DOM.
In the case of Tabulator you can handle many thousands of rows because it only adds the rows you can see to the DOM, removing/adding them as you scroll.
So yes this means there is more processing when you scroll but at the same time you aren't trying to move 100,000 od DOM elements at once which reduces the load on the browser when loading/scrolling.
Depending on the complexity of what you are dealing with there becomes a point where the trade off in processing/memory usage makes it worthwile
I suspect that may be the primary reason, not JS. When you start juggling details that impact a cell, that in turn impacts all the rest of the table, so you can add up with an additive impact based on the number of cells. <divs> still have that, but actually fall under the well-optimized engine for rendering, well, divs (and other straightforward elements that only impact other elements via positioning, not by things like colspan and rowspan)
But this is speculation on my part. I can say that while I appreciate the semantic definition of table and use the tag appropriately in my own work, I never look forward to it because it's always more work than doing so with divs. There is a reason everyone was happy to leave table-based layout behind and it wasn't (just) a desire for semantic purity.
It is not neccessarily a bottleneck, as long as your datagrid library uses the browser's ability to render the table. But if you want a custom look and feel, such as overlapping cells, irregular shaped cells, animated cells, it's far better to do it based on <div>s instead of fighting the browser engine.
Performance is solid, it's easy to work with for ~90% of the times I use it and there are other ways to handle that last 10%.
I probably wouldn't have used datatables on greenfield but the legacy (in every sense) project I inherited already used it so I went with it anyway.
The front end requests to the backend each chart on the current dashboad, then the backend, depending of the type of chart, gets the data from the database and passes it to the front who renders it, it could be a pie chart, a bar chart, a table, etc.
We hade 2 or 3 different types of table charts, al using different js based solutions, one of them using bootstrap, i don't remeber the others.
The javascript solutions had responsiveness issues, when you changed the size of the window, or used something that is not Chrome, column headers messed everything up.
One day i decided to end that and added a new type of chart, it expected one table resultset from the db, and once in the front it rendered a traditional <table> with it's content.
We have no more problems with table charts. It works in every browser and every screen resolution.
It was possible to fix the current js tables of course, but is it realy necessary? We have been using tables since forever, and they are just to correct way to display table data on the web.
Thats it, it just works.
We've since rewritten Dynatable to use vanilla JS and are in the process of renaming it to simply Dynatable instead of jQuery Dynatable.