Data Tables: Design and Performance
People don't like complex visualizations as much as they like simple tables. For operational data (orders, users, transactions), tables are often the right answer. Designing and implementing good tables is an underrated skill.
Why Tables Are Often Right
Tables let users find exactly what they need: sort, filter, search. Complex visualizations impress but limit functionality. A table showing transaction details with sorting and search beats a beautiful pie chart most of the time.
Essential Table Features
Sorting: click column headers to sort ascending/descending. Users find patterns (top performers, latest entries).
Filtering: search box to find rows. Column-level filters. Global search.
Pagination: don't load 10,000 rows. Load 50 per page. Navigate with next/previous.
Row selection: checkboxes to select rows. Bulk actions: "delete selected", "export selected".
Row actions: buttons per row. "View", "Edit", "Delete".
Resizable columns: let users adjust column widths.
Fixed columns for horizontal scroll: freeze the first column when scrolling right.
Client-Side vs Server-Side Tables
Client-side: load all data once, sort/filter in the browser. Works for up to a few thousand rows.
Server-side: the server handles sort/filter/pagination. Necessary for large datasets.
Server-side tables are more complex but necessary when data is large.
Virtual Scrolling
Rendering all rows is slow. Virtual scrolling: only render visible rows. Scroll and rows are added/removed as needed.
This solves the "10,000 rows is slow" problem without pagination. Seamless scrolling through data.
TanStack Table (React Table)
TanStack Table is the most powerful headless table library for React. Headless means no built-in UI—you supply it. This gives complete control.
It handles sorting, filtering, pagination, row selection, virtual scrolling. Incredibly flexible.
shadcn/ui has a table component built on TanStack Table. Use it for a modern table with built-in styling.
Pagination Patterns
Page-based (1, 2, 3...): simple, familiar. Can't jump to page 1000 efficiently.
Cursor-based ("next 50 after this ID"): efficient for large datasets. No random page access but better performance.
Column Configuration
Let users show/hide columns. Reorder columns. Save preferences.
Power users love this. They customize tables for their workflow.
Row Density
Compact, normal, comfortable. Let users choose information density. This makes tables work for different use cases.
Export to CSV/Excel
Users want to export data. Provide a button. Export current view (respecting filters and sorts) as CSV.
This is surprisingly valuable. Users analyze data in Excel.
Performance Optimization
Virtualization for rendering. Pagination for data fetching. Memoization to prevent unnecessary re-renders.
For large tables, performance matters. Users won't use a sluggish table.
Empty and Error States
No data: show "No records found" with a message and CTA.
Error loading: show "Failed to load data" with retry button.
Loading: show skeleton or spinner.
Accessibility
Tables are complex for screen readers. Proper markup: table, thead, tbody, th, td. ARIA labels for buttons. Keyboard navigation.
Don't use divs styled to look like tables. Use semantic HTML.