You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Update test examples and document virtualized windowed fetching
- Make DuckDB test Rmd chunks self-contained (inline data generation)
- Add Parquet + virtual scrolling test example
- Update virtual scrolling test to use backend API
- Document pre-render jank with virtual + pagination=FALSE
- Add virtualized windowed fetching as future Phase 5
Copy file name to clipboardExpand all lines: design/duckdb-wasm-engine/duckdb-wasm-engine.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1099,6 +1099,10 @@ and memory than it saves on queries.
1099
1099
- **Debounce tuning:** The POC debounces search input at 300ms. For large datasets, increasing the debounce or
1100
1100
requiring a minimum query length (3+ chars) would reduce perceived lag.
1101
1101
1102
+
### Future: virtualized windowed fetching
1103
+
1104
+
With `virtual = TRUE, pagination = FALSE`, DuckDB currently fetches all rows at once (`pageSize: null` omits LIMIT/OFFSET). For Parquet, this means downloading the entire file over HTTP before the table renders. A future enhancement would use scroll-position-driven queries to fetch only a sliding window of rows around the viewport, leveraging Parquet HTTP range requests for efficient partial reads. See Phase 5 in `design/server-side-data/server-side-data.md` for the full plan.
1105
+
1102
1106
## End-to-end benchmark: DuckDB vs default backend
1103
1107
1104
1108
Measured in Chrome (Windows), serving rendered R Markdown documents over HTTP. Both documents use the same dataset
Copy file name to clipboardExpand all lines: design/server-side-data/server-side-data.md
+19-22Lines changed: 19 additions & 22 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -133,37 +133,22 @@ For multi-level grouping, nested data frames contain their own `.subRows`.
133
133
### 1. Bug Fixes and Polish
134
134
135
135
#### 1.1 Documentation Typo
136
-
**File:**`man/reactable-server.Rd` line 52-53
137
136
138
-
Current text incorrectly says:
139
-
```
140
-
- `reactableServerData()` should return a `resolvedData()` object.
141
-
- `reactableServerData()` should not return any value.
142
-
```
137
+
~~**File:**`man/reactable-server.Rd` line 52-53~~
143
138
144
-
Should be:
145
-
```
146
-
- `reactableServerData()` should return a `resolvedData()` object.
147
-
- `reactableServerInit()` should not return any value.
148
-
```
139
+
**Done.** The Rd already correctly says `reactableServerInit()` should not return any value.
149
140
150
141
#### 1.2 df Backend groupBy Bug
151
-
**File:**`R/server-df.R`
152
142
153
-
When `Reactable.toggleGroupBy()` is called via JavaScript API, the df backend returns grouped rows without the `__state` property needed for proper row identification. The V8 backend handles this correctly.
143
+
~~**File:**`R/server-df.R`~~
154
144
155
-
**Fix:** In `dfGroupBy()`, add state information to grouped rows:
**Done.**`dfGroupBy()` now adds `__state` with `id`, `grouped`, and `subRowCount` to grouped rows.
162
146
163
147
#### 1.3 Pagination Display with Empty Results
164
-
**File:**`srcjs/Reactable.js`
165
148
166
-
When server-side search returns zero results, pagination shows "1-10 of 0 rows" instead of "0-0 of 0 rows".
149
+
~~**File:**`srcjs/Reactable.js`~~
150
+
151
+
**Done.**`Pagination.js` uses `Math.min(page * pageSize + 1, rowCount)` to correctly show "0-0 of 0 rows" when `rowCount = 0`.
167
152
168
153
#### 1.4 Stop Sending Unused State
169
154
**File:**`srcjs/Reactable.js`
@@ -197,6 +182,8 @@ When server-side search returns zero results, pagination shows "1-10 of 0 rows"
197
182
198
183
**Future simplification: consider removing pre-rendered first page.** The R-side pre-rendering of the first page (to avoid a blank flash while WASM loads) adds significant JS complexity: `canSkipInitialDuckDBQuery`, `duckdbQueryCount`, `stateMatchesPrerender` comparison against `defaultSorted`, the groupBy special case (pre-rendered data is flat so we must query immediately), and race conditions when users interact before DuckDB is ready. Without pre-rendering, the query effect fires unconditionally after init and the entire skip optimization disappears. The tradeoff is showing a loading/empty state during WASM init instead of instant first-page display.
199
184
185
+
Pre-rendering is also problematic with **virtual scrolling + `pagination = FALSE`**: the pre-rendered `defaultPageSize` rows (e.g., 10) display immediately, then several seconds later the full dataset loads from DuckDB and the table jumps to show all rows. This creates a jarring partial-load effect. Deferring table readiness until all client-side data is fetched (showing a loading indicator instead of the partial pre-render) would give a smoother experience for this combination.
186
+
200
187
Another issue: **floating point precision mismatch** between the two data paths. The pre-rendered page goes through `jsonlite::toJSON(digits = NA)` which uses C's `%.15g` format (15 significant digits), while DuckDB query results come through Arrow's `row.toJSON()` which uses JavaScript's `Number.toString()` (up to 17 significant digits for exact float64 round-trip). Since 15 significant digits isn't always enough to recover the exact float64 value, numbers with many decimal places can visibly change when the user first interacts and DuckDB takes over from the pre-rendered data. This is unsolvable without either (a) increasing jsonlite's digits to 17 for exact round-trip, (b) rounding DuckDB results to 15 significant digits to match jsonlite, or (c) removing pre-rendering so there's only one data path.
201
188
202
189
**Option B: Full server-side implementation (future)**
0 commit comments