Implementation:Sgl project Sglang Performance Dashboard App
| Knowledge Sources | |
|---|---|
| Domains | Monitoring, Web UI, Benchmarking |
| Last Updated | 2026-02-10 00:00 GMT |
Overview
A JavaScript frontend application for the SGLang performance dashboard, providing interactive benchmark visualization with Chart.js time-series charts and filterable metric views.
Description
app.js is the core UI component of the SGLang performance dashboard. It implements a dark-themed single-page application that fetches benchmark metrics and renders them as interactive line charts using Chart.js.
The application supports six metric types:
- Overall Throughput (tokens/sec)
- Output Throughput (tokens/sec)
- Input Throughput (tokens/sec)
- Latency (ms)
- Time to First Token (ms)
- Accept Length (tokens)
Data is loaded from either a local server API (/api/metrics) or the GitHub Actions API as a fallback, fetching artifacts from nightly test workflow runs. Charts are organized by batch size, with each batch getting its own chart panel. Users can filter by GPU configuration, model, variant, I/O length, and batch size.
Key features include:
- XSS-safe DOM construction using
textContentandencodeURIComponent - Dynamic filter cascading: variant and I/O length options update based on GPU/model selection
- Tab-based metric switching between the six metric types
- Runs history table with links to GitHub Actions runs and commit SHAs
- Responsive layout with auto-resizing charts
Usage
This file is served alongside an HTML page and used with the companion server.py backend. It initializes on DOM load and renders the full dashboard interface.
Code Reference
Source Location
- Repository: Sgl_project_Sglang
- File: docs/performance_dashboard/app.js
- Lines: 1-837
Signature
async function init()
async function loadData()
async function fetchWorkflowRuns()
async function fetchMetricsForRun(run)
function populateFilters()
function updateCharts()
function prepareChartDataByBatch(gpuFilter, modelFilter, variantFilter, ioLenFilter, batchFilter)
function updateMetricChart(chartDataByBatch, metricType)
function getChartOptions(yAxisLabel)
function updateRunsTable()
async function refreshData()
Import
<!-- Chart.js is loaded via CDN in the HTML page -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| /api/metrics | JSON endpoint | No | Local server API returning benchmark metrics array |
| GitHub API | REST API | No | Fallback data source from workflow run artifacts |
| gpu-filter | select element | Yes | GPU configuration filter (e.g., "1xH100") |
| model-filter | select element | Yes | Model name filter (e.g., "meta-llama/Llama-3.1-8B") |
| variant-filter | select element | No | Test variant filter (default: "all") |
| io-len-filter | select element | No | Input/output length filter (default: "all") |
| batch-filter | select element | No | Batch size filter (default: "all") |
Outputs
| Name | Type | Description |
|---|---|---|
| Chart.js charts | Canvas elements | Time-series line charts grouped by batch size |
| Stats row | DOM elements | Summary cards showing total runs, models tested, and benchmark count |
| Runs table | HTML table | Recent workflow runs with dates, IDs, commits, and model badges |
Usage Examples
Metric Type Definitions
const metricTypes = {
throughput: { label: 'Overall Throughput', unit: 'tokens/sec', field: 'throughput' },
outputThroughput: { label: 'Output Throughput', unit: 'tokens/sec', field: 'outputThroughput' },
inputThroughput: { label: 'Input Throughput', unit: 'tokens/sec', field: 'inputThroughput' },
latency: { label: 'Latency', unit: 'ms', field: 'latency' },
ttft: { label: 'Time to First Token', unit: 'ms', field: 'ttft' },
accLength: { label: 'Accept Length', unit: 'tokens', field: 'accLength', filterInvalid: true }
};
Initializing the Dashboard
document.addEventListener('DOMContentLoaded', init);
async function init() {
await loadData();
document.getElementById('loading').style.display = 'none';
document.getElementById('content').style.display = 'block';
populateFilters();
updateStats();
updateCharts();
updateRunsTable();
}