Skip to content

perf(explore): virtualize compact list, shallow log state, lighter table renders#93

Draft
mr-karan wants to merge 1 commit into
mainfrom
chore/explore-perf
Draft

perf(explore): virtualize compact list, shallow log state, lighter table renders#93
mr-karan wants to merge 1 commit into
mainfrom
chore/explore-perf

Conversation

@mr-karan

Copy link
Copy Markdown
Owner

Implements the high-priority items from .plans/spec_explore_perf.md.

Headline

10k-row Explore query, browser-side:

Metric main this branch Delta
Row DOM nodes 10,000 29 99.71% fewer
Total DOM elements 271,211 2,157 99.20% fewer
Used JS heap 323.7 MB 95.0 MB 70.65% lower
Run → paint 2,459.0 ms 1,113.5 ms 54.72% faster
Long-task blocking 2,211.7 ms 109.0 ms 95.07% lower
Backend exec 58.0 ms 59.0 ms unchanged

Full methodology in docs/benchmarks/explore-10k-rendering.md.

Spec items shipped

  • Fix editor #1 — debounce path for persistDraft writes
  • Fixes #2 — virtualize CompactLogList with @tanstack/vue-virtual
  • Develop #4 — pre-compile per-column regex, memoize timestamp formatting
  • Bookmark Favorite Queries #5 — drop the /translate round-trip; backend now returns
    fields_used + parsed conditions with the execute response
  • Live Tail Logs #10 — log rows + columns held in shallow/raw shape (no deep Proxy)
  • Alerting Service #11:schema moved to a computed in LogExplorer.vue
  • parts of prepare release #3 — DataTable cleanup (no-op ResizeObserver removed,
    unused tableRef removed, lighter resize state churn)
  • parts of Backend #12 — extracted useExploreQueryParsing composable

Out of scope for this PR (tracked as follow-ups)

Backend change

internal/logchefql and internal/server/logchefql_handlers.go:
the execute response now carries fields_used and parsed conditions
inline, so the frontend can drop its second /translate call (item #5).

To verify locally before merging

  1. Compact view, 10k-row query — confirm smooth scroll + visible row
    count.
  2. Compact view, ~200 rows — verify no perceptible overhead at small
    sizes (virtualization fixed cost).
  3. Click-expand a row → context modal opens; collapse works.
  4. Switch table↔compact while data is loaded — state isolation intact.
  5. Type in the query editor — typing should feel snappier.

Draft for now — Karan is iterating.

…ble renders

Implements the high-priority items from .plans/spec_explore_perf.md.

Frontend:
- CompactLogListSimple: TanStack vue-virtual windowing + row formatting
  memo. DOM count for a 10k-row query drops from ~271k elements to ~2.1k.
- Stores: log rows held in a shallow/raw shape so Vue does not deep-proxy
  every cell. Heap on 10k-row query drops from ~324MB to ~95MB.
- data-table: hoist regex/formatter caching, drop the no-op
  ResizeObserver and unused refs, lighter resize state churn.
- columns.ts: pre-compile per-column regex and memoize timestamp
  formatting; cell renderer no longer re-allocates per cell render.
- LogExplorer: extract query-parsing logic into useExploreQueryParsing
  composable; drop the redundant /translate roundtrip in favor of
  inline metadata from the execute response.

Backend:
- logchefql translate / query: return fields_used + parsed conditions
  with the execute response so the frontend does not need a second
  round-trip for column highlighting.

Benchmark:
- docs/benchmarks/explore-10k-rendering.md captures before/after for
  10k-row queries. Long-task blocking time drops 95%, run-click-to-paint
  drops 55%, with backend execution time unchanged.

Spec items shipped: #1 (debounce persistDraft path), #2 (virtualize
compact list), #4 (cell renderer caching), #5 (drop translate
round-trip), #10 (shallow result state), #11 (computed :schema), and
parts of #3 (DataTable cleanup) and #12 (extract parsing composable).
Items #6, #7, #8, #9, #13 remain as follow-up.
mr-karan added a commit that referenced this pull request Jul 14, 2026
…lickHouse (closes #92, #93, #94, #98, #99, #100)

#92: transport-level dial (5s) + ResponseHeaderTimeout (30s) on the VL
client — non-tail calls fail fast on a wedged endpoint while streaming
tails (headers arrive immediately) are never severed; plus per-alert
context timeout in evaluateCycle so one hung source can't freeze all
alerting org-wide.
#93: enforce MaxResponseBytes byte budget + DefaultLimit in QueryLogs
with LIMIT_APPLIED/LIMIT_CAPPED warnings (was the CH OOM class, VL-side).
#98: RedactedConnectionConfig now blanks custom header VALUES (secret
leak to source viewers), with blank-means-keep on update.
#99: fields_limit=10 on histogram group-by (was unbounded series) + notice.
#94: applyAlertLookback skips prepend when the query already has a _time:
filter; tenant headers trimmed.
#100: auth-mode none clears creds, latest-ts sorted, buckets time-sorted,
health cached, host-required + numeric-tenant validation.
Closes #92, #93, #94, #98, #99, #100.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant