Order GLQL dashboard panel requests by grid position

What does this MR do and why?

Behind the default-off glql_dashboard_panels_in_reading_order flag, GLQL dashboard panels stop deferring their queries with an IntersectionObserver. Every panel queues on mount, and the shared request queue runs waiting requests in reading order (top to bottom, then left to right). The order comes from the dashboard config's gridAttributes, never from the DOM.

Queue and GLQL

  • glql/utils/task_queue.js: enqueue takes a priority (default 0). Waiting tasks sort lowest first; equal priorities keep arrival order; running tasks are never interrupted.
  • glql/core/executor.js and glql/components/common/resolver.vue: priority is passed with the main query, the trend comparison query and every further page, so a panel's later requests keep its place.
  • analytics_dashboards/components/visualizations/glql.vue: new loadPriority prop. With the flag off it passes priority 0 and keeps the observer path, so behaviour matches master.
  • The queue option, executor/resolver pass-through, loadPriority config key and serializer strip are unflagged. They are inert at priority 0.

Priority assignment

  • explore/analytics_dashboards/utils.js: new assignLoadPriority(panels) adds a client-only loadPriority without reordering, reusing byReadingOrder (now exported from dashboard_preview_layout.js). Panels without a position sort top-left; ties keep config order.
  • Called from dashboard_loader.vue (Explore details and edit) and analytics_dashboard.vue (group and project). Numbering restarts per tabbed view.
  • details.vue, edit.vue and analytics_dashboard.vue pass :load-priority to analytics_dashboard_panel.vue, which forwards it to the visualization.
  • serializePanelsForMutation drops loadPriority alongside the client-only id, so saved dashboards never carry it.

A config key is used because GlDashboardLayout strips gridAttributes from its #panel slot but passes every other key through, the same trick the compliance and security dashboards use.

Why

Deferral (!257486 (merged)) needed a scroll-container root, a margin, and two follow-ups (!258673 (merged), !258139 (closed)). Measured on gitlab.com, the original full-viewport margin loaded every Adoption panel on tab switch anyway, and the observer does nothing in a hidden tab, so background tabs sat on spinners. Reading-order queueing gives the same visible-first order, keeps the queue full, lets a top panel's comparison and pagination requests keep their place, and loads background tabs. Measurements: note

Cost: every panel on a view loads even without scrolling, 33 requests per Work-tab switch instead of 17 plus 16 on scroll. !258139 (closed) would have sent the same 33 and is no longer needed. Pairs with !258678 (merged).

Embedded GLQL blocks in issues and MRs are unchanged (priority 0, arrival order).

No changelog entry: the behaviour is behind a default-off flag.

References

Screenshots or screen recordings

No visual change. The difference is when panels start loading.

How to set up and validate locally

  1. Feature.enable(:glql_dashboard_panels_in_reading_order), then open the DAP Impact dashboard at /explore/analytics_dashboards/dap_impact?scope=<top-level group> with ClickHouse data and switch to the Work tab.
  2. In DevTools, filter Network on /api/glql: requests start for the top panels first and continue down without scrolling. On master, panels more than half a viewport below the fold send nothing until you scroll.
  3. Scroll to the bottom: those panels already have data.
  4. Open the dashboard in a background tab and switch to it after a few seconds: it is loaded. On master it shows spinners until visible.
  5. Edit a custom dashboard, drag a panel and save: the mutation succeeds and the payload has no loadPriority.
  6. Disable the flag and reload: panels below half a viewport wait until you scroll, as on master.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

🤖 Generated with Claude Code

Edited by Brandon Labuschagne

Merge request reports

Loading
Loading