feat: initial Speedboard implementation

sitespeed.io web UI with Express/Pug/SQLite — port 3132.
Includes job queue, SSE live log, full metrics dashboard,
site history, CO2/axe/CWV sections, and Docker support.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-06 19:36:13 +02:00
commit 280e5f133f
28 changed files with 1222 additions and 0 deletions

45
views/index.pug Normal file
View File

@@ -0,0 +1,45 @@
extends layout
block content
div(class='max-w-2xl mx-auto')
h1(class='text-3xl font-bold mb-2 text-indigo-700') Website Speed Test
p(class='text-gray-500 mb-8') Test any URL with sitespeed.io. Get Core Web Vitals, coach scores, resources, accessibility & CO₂ metrics.
form(action='/test' method='POST' class='bg-white border border-gray-200 rounded-xl p-6 shadow-sm space-y-5')
div
label(for='url' class='block text-sm font-semibold mb-1') URL
input#url(
type='url'
name='url'
required
placeholder='https://example.com'
value=prefillUrl
class='w-full border border-gray-300 rounded-lg px-4 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500'
)
div(class='grid grid-cols-3 gap-4')
div
label(for='browser' class='block text-sm font-semibold mb-1') Browser
select#browser(name='browser' class='w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500')
option(value='chrome') Chrome
option(value='firefox') Firefox
div
label(for='runs' class='block text-sm font-semibold mb-1') Runs
select#runs(name='runs' class='w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500')
option(value='1') 1 run
option(value='3' selected) 3 runs
option(value='5') 5 runs
option(value='9') 9 runs
div(class='flex items-end pb-0.5')
label(class='flex items-center gap-2 cursor-pointer')
input#mobile(type='checkbox' name='mobile' value='1' class='w-4 h-4 text-indigo-600')
span(class='text-sm font-semibold') Mobile mode
button(type='submit' class='w-full bg-indigo-600 hover:bg-indigo-700 text-white font-semibold py-2.5 rounded-lg transition')
| ⚡ Run Test
if prefillUrl
script.
document.getElementById('url').value = decodeURIComponent('!{encodeURIComponent(prefillUrl)}');