Core/Dash CI/CD ytelsessjekker

Stopp en tung side før den går live. La så data fra ekte brukere fortelle deg hva hver lansering gjorde.

Prøv gratis

Trusted by market leaders · Client results

workivasaturnhappyhorizonsnvnestlevpndpg mediamy work featured on web.deverasmusmcfotocasaperionwhowhatwearharvardcomparemonarchmarktplaatsaleteialoopearplugskpnebayadevintanina care

Hvilken deploy gjorde den tregere?

LCP-en din var 2,1 sekunder i juni. Nå er den 2,9 sekunder. I løpet av disse åtte ukene rullet du ut kode førti ganger, og ingenting i overvåkingen din viser hvilken av de førti som hadde skylden.

Det er ikke et dataproblem. CoreDash måler allerede hver sidevisning fra hver ekte besøkende. Det verktøyet ikke klarer å finne ut på egen hånd, er hva som endret seg hos deg klokken 14:32 på en tirsdag. Uten denne informasjonen forblir en regresjon «noe ble tregere forrige måned» i stedet for «v2.4.1 gjorde dette». Så du feilsøker etter hukommelsen, spør teamet hva som ble lansert, og gir som oftest opp og optimaliserer noe helt urelatert.

CI/CD-integrasjonen tetter dette gapet fra to sider. Før en deploy skanner Core/Dash preview-bygget ditt og stopper pipelinen hvis en side overskrider budsjettet. Etter en deploy blir hver sidevisning merket med versjonen som serverte den, slik at hver lansering måles mot sin egen trafikk.

Begge er valgfrie og uavhengige. Kjør én, kjør begge, eller ingen av dem. Ingen av dem krever at du endrer en eneste linje med frontend-kode eller legger til et ekstra script på sidene dine.

To sjekker rundt én deploy

De to halvdelene fanger opp forskjellige feil, og det er dette det er verdt å forstå før du kobler opp noe.

Pre-deploy-sjekken er syntetisk. Den laster inn preview-miljøet ditt i Lighthouse og ser på ting som er sanne om selve bygget: hvor mange bytes siden sender, hvor mye script, hvor store bildene er, hvor mange DOM-noder som finnes. Dette er regresjonene en menneskelig gjennomgang går glipp av. Ingen legger merke til i en diff at det nye hero-bildet er en 4MB PNG, eller at en markedsføringstag dro 300KB med ekstra JavaScript inn i bundlen.

Sammenligningen av lanseringer er field data. Ekte enheter, ekte nettverk, ekte brukere, målt etter at koden er live. Det er det eneste stedet LCP, INP og CLS faktisk eksisterer. En syntetisk kjøring på Googles infrastruktur kan ikke fortelle deg at Android-trafikken din fra Indonesia ble 900 ms tregere, fordi et datasenter i Iowa ikke er en Android-telefon på en 4G-tilkobling.

Du vil ha begge fordi ingen av dem kan erstatte den andre. Syntetiske målinger fanger opp de åpenbare feilene tidlig og billig. Field data forteller deg hva brukerne dine fikk, og det er det eneste Google rangerer på.

Før en deploy: pre-deploy-sjekken

Ett POST-kall fra pipelinen din mot preview-URL-en din. Core/Dash kjører Lighthouse mot de overvåkede sidene dine på den preview-originen, vurderer dem mot Lighthouse-budsjettene du allerede har, og svarer pass eller breach. Det tar rundt 30 til 45 sekunder.

Hva som blir sjekket

Core/Dash tar de første fire overvåkede Lighthouse-sidene som har en budsjettlinje verktøyet kan score. Den beholder hver sides egen bane, query-streng og enhetsinnstilling, og bytter ut hosten med den preview-originen du sendte inn. Så siden du sjekker er den samme ruten som den nattlige skanningen din sjekker, på bygget som ikke har blitt rullet ut ennå.

Fire sider er taket, og det er bevisst. De fire skanningene kjører i parallell mot PageSpeed Insights-API-et, og hver av dem avbrytes etter 75 sekunder slik at én enkelt treg side ikke kan forsinke bygget ditt.

Hva som scores, og hva som ikke scores

Kun målinger som ikke varierer mellom to kjøringer av det samme bygget:

ScoresScores ikke
Total sidevektTotal Blocking Time
TredjepartsvektBootup Time
Script-vektMain Thread Work
BildevektLighthouse performance-score
CSS-vekt
Font-vekt
Ubrukt JavaScript
DOM-størrelse

En Lighthouse performance-score i CI er nesten som en tilfeldig tallgenerator. Kjør den samme uendrede siden fem ganger, og du kan se den svinge ti poeng. Dette skjer fordi scoren domineres av CPU-bundne tider, og maskinen som kjørte testen er aldri den samme maskinen to ganger. Blokker byggene dine på det, og du får røde pipelines som ikke betyr noe. Det lærer bare alle til å kjøre jobben på nytt til den blir grønn. Det er verre enn ingen sjekk i det hele tatt.

Bytes gjør ikke slikt. Hvis bygget ditt sender ut 1,4 MB med script i dag og 1,9 MB i morgen, er det din commit, ikke Googles maskinvare. Derfor er det disse linjene sjekken vurderer, og tidsmålingene forblir der de hører hjemme: på de ekte brukerdataene, der CPU-en er den besøkendes faktiske telefon.

Filteret fungerer per budsjettlinje. Et budsjett som blander begge typer, bidrar med de linjene som kan scores, og hver respons lister opp hva den hoppet over og hvorfor.

Kall det fra pipelinen din

Opprett først en prosjekt-API-nøkkel (i appen: prosjektet ditt, deretter AI Insights, så Connect Your AI) og lagre den i dine CI-secrets som COREDASH_API_KEY. Nøklene starter med cdk_ og er avgrenset til ett prosjekt. En master byrå-nøkkel blir avvist her, fordi den ikke er knyttet til et prosjekt for å feste lanseringen til.

STATUS=$(curl -sS -o gate.json -w '%{http_code}' -X POST "https://app.coredash.app/api/project/releases/check" \
  -H "Authorization: Bearer $COREDASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"tag":"v1.2.3","origin":"https://preview.example.app"}')

if [ "$STATUS" != "200" ]; then
  echo "Gate call failed with HTTP $STATUS: $(cat gate.json)" >&2
  exit 1
fi

jq -e '.data.check.status != "breach"' gate.json > /dev/null

Ikke forkort den kodesnutten ved å pipe curl direkte inn i jq. En ugyldig nøkkel svarer med 401 og en ugyldig tag svarer med 400. Disse responsene inneholder ikke noe data-objekt i det hele tatt. Å lese .data.check.status fra manglende data gir deg null i jq. Null er ikke «breach», og pipen avslutter med status 0. En utløpt API-nøkkel ville dermed blitt lest som et godkjent pass, og gaten din ville i stillhet sluttet å blokkere. HTTP-statussjekken er det som forhindrer dette.

Parametere

FeltPåkrevdBeskrivelse
tagjaDin versjonsstreng. Bokstaver, tall, . _ / -, opptil 64 tegn.
originjaPreview-originen, for eksempel https://pr-42.example.app. Kun protokoll (scheme) og host.
sha, branch, actor, repo, prNumber, runUrlneiGit-kontekst. Lagres for dyp-lenking i appen. Ingen logikk styres av dette.

Originen må være ren. En sti, en query-streng, et fragment eller basic-auth påloggingsinformasjon i URL-en gir alle 400 som svar. Det er med vilje: skanneren kopierer kun protokollen og hosten over på hver overvåket sides URL. Et preview servert under /pr-42/ ville dermed i stillhet blitt skannet på feil URL-er og rapportert som godkjent på sider som ikke finnes.

Hva du får tilbake

En gyldig forespørsel svarer alltid med HTTP 200. Dommen ligger i body-en under data.check.status:

StatusBetydningBygget ditt
passAlle scorede linjer er innenfor budsjettetFortsett
breachMinst én linje er over budsjettetStopp
errorIngen side kunne skannes i det hele tattFortsett
no-budgetsIngen overvåket side har et budsjett som sjekken kan scoreFortsett

Ugyldig tag eller ugyldig origin svarer med 400. En ugyldig eller manglende nøkkel svarer med 401. Disse body-ene inneholder kun status og message.

Sjekken har en fail-open-tilnærming per side. Hvis PageSpeed Insights timer ut på én av de fire sidene dine, blir den siden rapportert som en feil, mens de tre andre fortsatt blir scoret. Bygget ditt blir ikke blokkert bare fordi Google hadde et dårlig minutt. Feilen blir rapportert fremfor å skjules, slik at du kan se i responsen hvilken side som ikke ble målt.

To ting til det er verdt å vite. Preview-miljøet må være tilgjengelig fra det åpne internettet, fordi PageSpeed Insights henter det fra Googles side. Et passordbeskyttet eller IP-hvitelistet preview kan ikke skannes, og det finnes ingen omvei (hvis preview-miljøene dine er bak autentisering, kjør heller sjekken mot et åpent staging-origin). Og sjekken skriver aldri til budsjett-tavlen din i produksjon. Preview-tall holdes utenfor tallene du bruker for å bedømme den live siden din.

900x500?text=Pre deploy+Lighthouse+check+card+on+release+detail

Etter en deploy: registrer lanseringen

Når deployen er fullført, fortell Core/Dash at versjonen er live:

curl -sS -X POST "https://app.coredash.app/api/project/releases/ingest" \
  -H "Authorization: Bearer $COREDASH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"tag":"v1.2.3"}'

I GitHub Actions, med git-referansen som versjon:

- name: Report release to CoreDash
  if: success()
  env:
    COREDASH_API_KEY: ${{ secrets.COREDASH_API_KEY }}
  run: |
    curl -sS -f -X POST "https://app.coredash.app/api/project/releases/ingest" \
      -H "Authorization: Bearer ${COREDASH_API_KEY}" \
      -H "Content-Type: application/json" \
      -d "{\"tag\":\"${{ github.ref_name }}\"}"

Enhver CI som kan kjøre curl vil fungere. GitLab, Jenkins, CircleCI, et bash-deploy-script på en maskin et sted.

FeltPåkrevdBeskrivelse
tagjaSamme regler som for sjekken. Bruk den samme strengen som du sendte til sjekken.
deployedAtneiISO-tidsstempel. Standard er nå. Sett den i fortiden for å tilbakedatere en deploy du allerede har gjort.
notesneiHva som ble lansert. Opptil 2000 tegn.
sha, branch, actor, repo, prNumber, runUrlneiGit-kontekst, samme som for sjekken.

En lansering er unik per prosjekt og tag. Å poste den samme taggen på nytt oppdaterer den eksisterende raden i stedet for å opprette en ny. Slik vil en rollback som gjenbruker en versjon, flette dataene tilbake i lanseringen den tilhører.

Ingen pipeline? Lanseringssiden (Releases) har et Tag deployment-skjema: versjon, tidspunktet den gikk live, valgfrie notater. Det er den samme raden, bare med site som kilde i stedet for ci. Bruk det for å etterregistrere deploies du allerede har rullet ut. Det er det svakeste alternativet, og det er verdt å være ærlig om, for det registrerer kun lanseringene noen husker å skrive inn, og lanseringstidspunktet er bare så nøyaktig som hukommelsen deres.

Hvordan trafikk knyttes til en lansering

Når du registrerer en lansering, stemples den på prosjektet som gjeldende versjon. Hosten som serverer sporingsscriptet ditt, leser dette stempelet og injiserer taggen i scriptet som sendes ut. Hver sidevisning fra det tidspunktet vil dermed bære versjonen i rel-dimensjonen. Edge-kopien av scriptet tømmes fra Cloudflare i det øyeblikket stempelet flyttes, slik at du slipper å vente på at en CDN-cache skal oppdatere seg.

Sidene dine endres ikke. Det er ingen byggeprosess, ingen data-attributt som må legges inn, ingen ekstra SDK.

Hvis du heller vil styre verdien selv, kan du sette window.__CWVREL før trackeren laster, og den vil overstyre den injiserte. Det er løsningen for oppsett der appen kjenner sin egen build id og CI ikke gjør det. Hold det til en reell versjonsstreng. Å koble den til en build-hash per forespørsel gir deg en ny dimensjonsverdi på hver sidevisning, noe som ødelegger hver eneste grupperte spørring du kjører i etterkant.

Metrikkene finner lanseringen sin gjennom den taggen, og ingenting annet. Det er ingen tidsvindu-fallback der Core/Dash gjetter at trafikk mellom to tidsstempler sannsynligvis tilhører en lansering. Hvis en lansering ikke har noen tagget trafikk, viser raden bindestreker. Det er det ærlige svaret, og det er mye bedre enn et tall som i stillhet tilskriver den forrige versjonens brukere til din nye.

Gi det omtrent 200 sidevisninger før du forventer en dom. Under det vil p75 flytte seg på grunn av enkeltbrukere, og en pass eller fail vil bare være støy.

Dommen kommer fra RUM-budsjettene du allerede kjører på siden for varsler og notifikasjoner. Det er ingen andre terskler som må konfigureres for lanseringer, og det er umulig for de to å vise forskjellige resultater.

Lanseringstilstander

Begge halvdelene skriver til den samme lanseringsraden, så en versjon har en livssyklus fra sjekket til lansert:

TilstandSatt avBetydning
blockedSjekken, ved en breachIngenting er lansert under denne taggen
pendingSjekken, på alt annetGodkjent, ingen deploy rapportert ennå
releasedIngest, eller skjemaet i appenLive, med et ekte lanseringstidspunkt

Det er kun når den når released at prosjektet stemples og tracker-scriptet tømmes. Ikke-lanserte rader vises fortsatt på tidslinjen, merket som «Blocked» eller «Awaiting deploy», uten lanseringstidspunkt og uten field data fra ekte brukere. En blokkert rad inneholder metrikkene som overskred budsjettet, slik at du en uke senere fortsatt kan se hvorfor den versjonen aldri gikk live.

Å kjøre sjekken på nytt mot en tag som allerede er lansert, registrerer det nye resultatet uten å endre tilstanden eller lanseringstidspunktet. Lanseringer du registrerte før dette ble rullet ut, har ingen tilstand i det hele tatt og leses som lansert.

Hele prosessen, ende-til-ende

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # ... build and publish your preview here ...

      - name: Check the preview against budgets
        env:
          COREDASH_API_KEY: ${{ secrets.COREDASH_API_KEY }}
        run: |
          STATUS=$(curl -sS -o gate.json -w '%{http_code}' -X POST \
            "https://app.coredash.app/api/project/releases/check" \
            -H "Authorization: Bearer $COREDASH_API_KEY" \
            -H "Content-Type: application/json" \
            -d '{"tag":"${{ github.ref_name }}","origin":"https://preview.example.app","sha":"${{ github.sha }}","runUrl":"${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"}')

          if [ "$STATUS" != "200" ]; then
            echo "Gate call failed with HTTP $STATUS: $(cat gate.json)" >&2
            exit 1
          fi

          jq -e '.data.check.status != "breach"' gate.json > /dev/null

      # ... deploy to production here ...

      - name: Report release to CoreDash
        if: success()
        env:
          COREDASH_API_KEY: ${{ secrets.COREDASH_API_KEY }}
        run: |
          curl -sS -f -X POST "https://app.coredash.app/api/project/releases/ingest" \
            -H "Authorization: Bearer ${COREDASH_API_KEY}" \
            -H "Content-Type: application/json" \
            -d "{\"tag\":\"${{ github.ref_name }}\",\"sha\":\"${{ github.sha }}\"}"

Bruk den samme tag-en i begge kall. Det er det som fletter sjekkresultatet og metrikkene fra ekte brukere inn i én lansering i stedet for to.

Dette ser du i Core/Dash

Lanseringssiden (Releases) lister opp de siste 30 dagene, med de nyeste først. Per lansering får du versjonen, om den kom fra CI eller appen, lanseringstidspunktet, p75 for hver Core Web Vitals-metrikk, differansen mot forrige lansering, og den live budsjettstatusen. Ikke-lanserte versjoner ligger i den samme listen med en brikke (chip) som viser tilstanden deres.

Lanseringsdetaljene (Release detail) setter lanseringen opp mot hele nettstedet under de samme filtrene, med resultatene fra pre-deploy-sjekken øverst: én rad per skannet side per budsjettlinje, pluss metrikkene som ble hoppet over. Under der finner du en live-oversikt over hvert RUM-budsjett du ikke har mutet.

Performance Snapshots har en Releases-bryter som tegner inn deploy-markører i grafene. Markørene vises bare for versjoner som faktisk ble lansert, så et blokkert bygg vil aldri dukke opp som en linje i en graf ved siden av trafikk den aldri serverte.

1200x600?text=Releases+list+with+deltas+and+state+chips

Én endring i budsjettforslagene for Lighthouse

Foreslåtte Lighthouse-budsjetter får nå 30 % margin over den målte verdien, opp fra 15 %. Både auto-setup og crawl-forslagene bruker det nye tallet. Budsjetter du allerede har satt, forblir urørt.

Årsaken er pre-deploy-sjekken. Et budsjett satt 15 % over det siden måler den dagen du opprettet det, vil ryke på den første reelle endringen. En gate som utløses på helt vanlig arbeid, blir skrudd av i løpet av en uke. 30 % gir rom for en ekte feature, og fanger likevel opp 4MB-bildet.

Når en lansering ikke viser noe

Bindestreker på en lanseringsrad betyr at det ikke er noen tagget trafikk ennå, og det er bare et par grunner til at dette skjer. Lanseringen ble rapportert før koden faktisk var live, slik at sidevisningene som kom inn fortsatt ble servert av den gamle versjonen. Eller lanseringen ble registrert for noen minutter siden, og 200 sidevisninger har ikke rukket å skje ennå. Eller så er taggen som CI-en din postet ikke den samme taggen som ligger i beacons, noe som skjer når en side setter window.__CWVREL til noe annet og overstyrer.

Grupper en datatabell etter dimensjonen Release for å se det direkte. Hvis taggen din er i den listen med sidevisninger bak seg, fungerer attribusjonen, og du venter bare på volum.

Se også: Core/Dash-API-et for å hente ut disse dataene fra et script eller en AI-agent, varsler og notifikasjoner for budsjettene disse dommene bruker, og installasjon hvis du ikke har lagt trackeren på nettstedet ditt ennå.