Skip to content

perf: Defer OTel CDN loading to after first paint (#57) #80

perf: Defer OTel CDN loading to after first paint (#57)

perf: Defer OTel CDN loading to after first paint (#57) #80

Workflow file for this run

name: Benchmark
on:
push:
branches: [main]
paths:
- 'Abies/**'
- 'Abies.Benchmarks/**'
- 'scripts/extract-allocations.py'
- 'scripts/merge-benchmark-results.py'
- 'scripts/compare-benchmarks.py'
- '.github/workflows/benchmark.yml'
pull_request:
branches: [main]
paths:
- 'Abies/**'
- 'Abies.Benchmarks/**'
- 'scripts/extract-allocations.py'
- 'scripts/merge-benchmark-results.py'
- 'scripts/compare-benchmarks.py'
- '.github/workflows/benchmark.yml'
workflow_dispatch:
permissions:
contents: write
deployments: write
pull-requests: write
jobs:
benchmark:
name: Run Benchmarks
runs-on: ubuntu-latest
steps:
- name: Checkout PR branch
uses: actions/checkout@v4
with:
fetch-depth: 0 # Need full history for branch comparison
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
# ============================================
# BASELINE BENCHMARKS (main branch)
# ============================================
- name: Checkout main branch for baseline
if: github.event_name == 'pull_request'
run: |
git checkout origin/main
echo "Running baseline benchmarks on main branch..."
- name: Restore dependencies (baseline)
if: github.event_name == 'pull_request'
run: dotnet restore Abies.Benchmarks/Abies.Benchmarks.csproj
- name: Build benchmarks (baseline)
if: github.event_name == 'pull_request'
run: dotnet build Abies.Benchmarks/Abies.Benchmarks.csproj -c Release --no-restore
- name: Run DOM Diffing benchmarks (baseline)
if: github.event_name == 'pull_request'
run: >
dotnet run --project Abies.Benchmarks -c Release --no-build --
--filter '*DomDiffingBenchmarks*'
--exporters json
--artifacts ./benchmark-baseline/diffing
- name: Run Rendering benchmarks (baseline)
if: github.event_name == 'pull_request'
run: >
dotnet run --project Abies.Benchmarks -c Release --no-build --
--filter '*RenderingBenchmarks*'
--exporters json
--artifacts ./benchmark-baseline/rendering
- name: Run Event Handler benchmarks (baseline)
if: github.event_name == 'pull_request'
run: >
dotnet run --project Abies.Benchmarks -c Release --no-build --
--filter '*EventHandlerBenchmarks*'
--exporters json
--artifacts ./benchmark-baseline/handlers
- name: Merge baseline benchmark results
if: github.event_name == 'pull_request'
run: python3 scripts/merge-benchmark-results.py ./benchmark-baseline
# ============================================
# PR BENCHMARKS (current PR branch)
# ============================================
- name: Checkout PR branch
if: github.event_name == 'pull_request'
run: |
git checkout ${{ github.head_ref }}
echo "Running PR benchmarks on ${{ github.head_ref }} branch..."
- name: Restore dependencies (PR)
run: dotnet restore Abies.Benchmarks/Abies.Benchmarks.csproj
- name: Build benchmarks (PR)
run: dotnet build Abies.Benchmarks/Abies.Benchmarks.csproj -c Release --no-restore
- name: Run DOM Diffing benchmarks (PR)
run: >
dotnet run --project Abies.Benchmarks -c Release --no-build --
--filter '*DomDiffingBenchmarks*'
--exporters json
--artifacts ./benchmark-results/diffing
- name: Run Rendering benchmarks (PR)
run: >
dotnet run --project Abies.Benchmarks -c Release --no-build --
--filter '*RenderingBenchmarks*'
--exporters json
--artifacts ./benchmark-results/rendering
- name: Run Event Handler benchmarks (PR)
run: >
dotnet run --project Abies.Benchmarks -c Release --no-build --
--filter '*EventHandlerBenchmarks*'
--exporters json
--artifacts ./benchmark-results/handlers
- name: Merge PR benchmark results
run: python3 scripts/merge-benchmark-results.py ./benchmark-results
# ============================================
# SAME-JOB COMPARISON (accurate, no runner variance)
# ============================================
- name: Compare benchmarks (same-job comparison)
if: github.event_name == 'pull_request'
run: |
python3 scripts/compare-benchmarks.py \
./benchmark-baseline/merged \
./benchmark-results/merged \
--throughput-threshold 115 \
--allocation-threshold 120
# ============================================
# HISTORICAL TRACKING (gh-pages, for trends only)
# ============================================
- name: Check if gh-pages exists
id: gh-pages-check
run: |
if git ls-remote --exit-code --heads origin gh-pages > /dev/null 2>&1; then
echo "exists=true" >> $GITHUB_OUTPUT
else
echo "exists=false" >> $GITHUB_OUTPUT
fi
- name: Store throughput to gh-pages (PR - no fail)
uses: benchmark-action/github-action-benchmark@v1
if: github.event_name == 'pull_request' && steps.gh-pages-check.outputs.exists == 'true'
with:
name: Rendering Engine Throughput
tool: benchmarkdotnet
output-file-path: ./benchmark-results/merged/throughput.json
github-token: ${{ secrets.GITHUB_TOKEN }}
auto-push: false
save-data-file: false
alert-threshold: '105%'
comment-on-alert: true
fail-on-alert: false # Don't fail here - same-job comparison handles pass/fail
summary-always: true
alert-comment-cc-users: '@MCGPPeters'
- name: Store allocations to gh-pages (PR - no fail)
uses: benchmark-action/github-action-benchmark@v1
if: github.event_name == 'pull_request' && steps.gh-pages-check.outputs.exists == 'true'
with:
name: Rendering Engine Allocations
tool: customSmallerIsBetter
output-file-path: ./benchmark-results/merged/allocations.json
github-token: ${{ secrets.GITHUB_TOKEN }}
auto-push: false
save-data-file: false
skip-fetch-gh-pages: true
alert-threshold: '110%'
comment-on-alert: true
fail-on-alert: false # Don't fail here - same-job comparison handles pass/fail
summary-always: true
alert-comment-cc-users: '@MCGPPeters'
- name: Store throughput baseline (main)
uses: benchmark-action/github-action-benchmark@v1
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main'
with:
name: Rendering Engine Throughput
tool: benchmarkdotnet
output-file-path: ./benchmark-results/merged/throughput.json
github-token: ${{ secrets.GITHUB_TOKEN }}
auto-push: true
save-data-file: true
skip-fetch-gh-pages: ${{ steps.gh-pages-check.outputs.exists != 'true' }}
alert-threshold: '105%'
comment-on-alert: true
fail-on-alert: true
fail-threshold: '110%'
alert-comment-cc-users: '@MCGPPeters'
- name: Store allocation baseline (main)
uses: benchmark-action/github-action-benchmark@v1
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main'
with:
name: Rendering Engine Allocations
tool: customSmallerIsBetter
output-file-path: ./benchmark-results/merged/allocations.json
github-token: ${{ secrets.GITHUB_TOKEN }}
auto-push: true
save-data-file: true
skip-fetch-gh-pages: false
alert-threshold: '110%'
comment-on-alert: true
fail-on-alert: true
fail-threshold: '120%'
alert-comment-cc-users: '@MCGPPeters'
- name: Upload benchmark artifacts
uses: actions/upload-artifact@v4
if: always()
with:
name: benchmark-results
path: |
./benchmark-results/
./benchmark-baseline/
retention-days: 30