name: Report size on: workflow_run: workflows: ["Read size"] types: - completed # This workflow needs to be run with "pull-requests: write" permissions to # be able to comment on the pull request. We can't checkout the PR code # in this workflow. # Reference: # https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ permissions: pull-requests: write jobs: report-size: name: Comment on PR runs-on: ubuntu-latest if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' steps: - name: Log GitHub context env: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" # Using actions/download-artifact doesn't work here # https://github.com/actions/download-artifact/issues/60 - name: Download artifact uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 id: download-artifact with: result-encoding: string script: | const fs = require('fs/promises'); const artifacts = await github.rest.actions.listWorkflowRunArtifacts({ owner: context.repo.owner, repo: context.repo.repo, run_id: context.payload.workflow_run.id, }); const matchArtifact = artifacts.data.artifacts.find((artifact) => artifact.name === 'sizes'); const download = await github.rest.actions.downloadArtifact({ owner: context.repo.owner, repo: context.repo.repo, artifact_id: matchArtifact.id, archive_format: 'zip', }); await fs.writeFile('sizes.zip', Buffer.from(download.data)); await exec.exec('unzip sizes.zip'); const json = await fs.readFile('sizes.json', 'utf8'); return json; # This runs on the base branch of the PR, meaning "dev" - name: Git checkout uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Install Node uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4 with: node-version: 18 cache: 'npm' - name: Install dependencies run: npm ci - name: Build run: npm run build - name: === Test tree-shaking === run: npm run test-treeshake - name: Read sizes id: read-size run: | WEBGL_FILESIZE_BASE=$(stat --format=%s build/three.module.min.js) gzip -k build/three.module.min.js WEBGL_FILESIZE_BASE_GZIP=$(stat --format=%s build/three.module.min.js.gz) WEBGL_TREESHAKEN_BASE=$(stat --format=%s test/treeshake/index.bundle.min.js) gzip -k test/treeshake/index.bundle.min.js WEBGL_TREESHAKEN_BASE_GZIP=$(stat --format=%s test/treeshake/index.bundle.min.js.gz) WEBGPU_FILESIZE_BASE=$(stat --format=%s build/three.webgpu.min.js) gzip -k build/three.webgpu.min.js WEBGPU_FILESIZE_BASE_GZIP=$(stat --format=%s build/three.webgpu.min.js.gz) WEBGPU_TREESHAKEN_BASE=$(stat --format=%s test/treeshake/index.webgpu.bundle.min.js) gzip -k test/treeshake/index.webgpu.bundle.min.js WEBGPU_TREESHAKEN_BASE_GZIP=$(stat --format=%s test/treeshake/index.webgpu.bundle.min.js.gz) WEBGPU_NODES_FILESIZE_BASE=$(stat --format=%s build/three.webgpu.nodes.min.js) gzip -k build/three.webgpu.nodes.min.js WEBGPU_NODES_FILESIZE_BASE_GZIP=$(stat --format=%s build/three.webgpu.nodes.min.js.gz) WEBGPU_NODES_TREESHAKEN_BASE=$(stat --format=%s test/treeshake/index.webgpu.nodes.bundle.min.js) gzip -k test/treeshake/index.webgpu.nodes.bundle.min.js WEBGPU_NODES_TREESHAKEN_BASE_GZIP=$(stat --format=%s test/treeshake/index.webgpu.nodes.bundle.min.js.gz) # log to console echo "WEBGL_FILESIZE_BASE=$WEBGL_FILESIZE_BASE" echo "WEBGL_FILESIZE_BASE_GZIP=$WEBGL_FILESIZE_BASE_GZIP" echo "WEBGL_TREESHAKEN_BASE=$WEBGL_TREESHAKEN_BASE" echo "WEBGL_TREESHAKEN_BASE_GZIP=$WEBGL_TREESHAKEN_BASE_GZIP" echo "WEBGL_FILESIZE_BASE=$WEBGL_FILESIZE_BASE" >> $GITHUB_OUTPUT echo "WEBGL_FILESIZE_BASE_GZIP=$WEBGL_FILESIZE_BASE_GZIP" >> $GITHUB_OUTPUT echo "WEBGL_TREESHAKEN_BASE=$WEBGL_TREESHAKEN_BASE" >> $GITHUB_OUTPUT echo "WEBGL_TREESHAKEN_BASE_GZIP=$WEBGL_TREESHAKEN_BASE_GZIP" >> $GITHUB_OUTPUT echo "WEBGPU_FILESIZE_BASE=$WEBGPU_FILESIZE_BASE" echo "WEBGPU_FILESIZE_BASE_GZIP=$WEBGPU_FILESIZE_BASE_GZIP" echo "WEBGPU_TREESHAKEN_BASE=$WEBGPU_TREESHAKEN_BASE" echo "WEBGPU_TREESHAKEN_BASE_GZIP=$WEBGPU_TREESHAKEN_BASE_GZIP" echo "WEBGPU_FILESIZE_BASE=$WEBGPU_FILESIZE_BASE" >> $GITHUB_OUTPUT echo "WEBGPU_FILESIZE_BASE_GZIP=$WEBGPU_FILESIZE_BASE_GZIP" >> $GITHUB_OUTPUT echo "WEBGPU_TREESHAKEN_BASE=$WEBGPU_TREESHAKEN_BASE" >> $GITHUB_OUTPUT echo "WEBGPU_TREESHAKEN_BASE_GZIP=$WEBGPU_TREESHAKEN_BASE_GZIP" >> $GITHUB_OUTPUT echo "WEBGPU_NODES_FILESIZE_BASE=$WEBGPU_NODES_FILESIZE_BASE" echo "WEBGPU_NODES_FILESIZE_BASE_GZIP=$WEBGPU_NODES_FILESIZE_BASE_GZIP" echo "WEBGPU_NODES_TREESHAKEN_BASE=$WEBGPU_NODES_TREESHAKEN_BASE" echo "WEBGPU_NODES_TREESHAKEN_BASE_GZIP=$WEBGPU_NODES_TREESHAKEN_BASE_GZIP" echo "WEBGPU_NODES_FILESIZE_BASE=$WEBGPU_NODES_FILESIZE_BASE" >> $GITHUB_OUTPUT echo "WEBGPU_NODES_FILESIZE_BASE_GZIP=$WEBGPU_NODES_FILESIZE_BASE_GZIP" >> $GITHUB_OUTPUT echo "WEBGPU_NODES_TREESHAKEN_BASE=$WEBGPU_NODES_TREESHAKEN_BASE" >> $GITHUB_OUTPUT echo "WEBGPU_NODES_TREESHAKEN_BASE_GZIP=$WEBGPU_NODES_TREESHAKEN_BASE_GZIP" >> $GITHUB_OUTPUT - name: Format sizes id: format # It's important these are passed as env variables. # https://securitylab.github.com/research/github-actions-untrusted-input/ env: WEBGL_FILESIZE: ${{ fromJSON(steps.download-artifact.outputs.result).filesize }} WEBGL_FILESIZE_GZIP: ${{ fromJSON(steps.download-artifact.outputs.result).gzip }} WEBGL_FILESIZE_BASE: ${{ steps.read-size.outputs.WEBGL_FILESIZE_BASE }} WEBGL_FILESIZE_BASE_GZIP: ${{ steps.read-size.outputs.WEBGL_FILESIZE_BASE_GZIP }} WEBGL_TREESHAKEN: ${{ fromJSON(steps.download-artifact.outputs.result).treeshaken }} WEBGL_TREESHAKEN_GZIP: ${{ fromJSON(steps.download-artifact.outputs.result).treeshakenGzip }} WEBGL_TREESHAKEN_BASE: ${{ steps.read-size.outputs.WEBGL_TREESHAKEN_BASE }} WEBGL_TREESHAKEN_BASE_GZIP: ${{ steps.read-size.outputs.WEBGL_TREESHAKEN_BASE_GZIP }} WEBGPU_FILESIZE: ${{ fromJSON(steps.download-artifact.outputs.result).filesize2 }} WEBGPU_FILESIZE_GZIP: ${{ fromJSON(steps.download-artifact.outputs.result).gzip2 }} WEBGPU_FILESIZE_BASE: ${{ steps.read-size.outputs.WEBGPU_FILESIZE_BASE }} WEBGPU_FILESIZE_BASE_GZIP: ${{ steps.read-size.outputs.WEBGPU_FILESIZE_BASE_GZIP }} WEBGPU_TREESHAKEN: ${{ fromJSON(steps.download-artifact.outputs.result).treeshaken2 }} WEBGPU_TREESHAKEN_GZIP: ${{ fromJSON(steps.download-artifact.outputs.result).treeshakenGzip2 }} WEBGPU_TREESHAKEN_BASE: ${{ steps.read-size.outputs.WEBGPU_TREESHAKEN_BASE }} WEBGPU_TREESHAKEN_BASE_GZIP: ${{ steps.read-size.outputs.WEBGPU_TREESHAKEN_BASE_GZIP }} WEBGPU_NODES_FILESIZE: ${{ fromJSON(steps.download-artifact.outputs.result).filesize3 }} WEBGPU_NODES_FILESIZE_GZIP: ${{ fromJSON(steps.download-artifact.outputs.result).gzip3 }} WEBGPU_NODES_FILESIZE_BASE: ${{ steps.read-size.outputs.WEBGPU_NODES_FILESIZE_BASE }} WEBGPU_NODES_FILESIZE_BASE_GZIP: ${{ steps.read-size.outputs.WEBGPU_NODES_FILESIZE_BASE_GZIP }} WEBGPU_NODES_TREESHAKEN: ${{ fromJSON(steps.download-artifact.outputs.result).treeshaken3 }} WEBGPU_NODES_TREESHAKEN_GZIP: ${{ fromJSON(steps.download-artifact.outputs.result).treeshakenGzip3 }} WEBGPU_NODES_TREESHAKEN_BASE: ${{ steps.read-size.outputs.WEBGPU_NODES_TREESHAKEN_BASE }} WEBGPU_NODES_TREESHAKEN_BASE_GZIP: ${{ steps.read-size.outputs.WEBGPU_NODES_TREESHAKEN_BASE_GZIP }} run: | WEBGL_FILESIZE_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGL_FILESIZE") WEBGL_FILESIZE_GZIP_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGL_FILESIZE_GZIP") WEBGL_FILESIZE_BASE_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGL_FILESIZE_BASE") WEBGL_FILESIZE_BASE_GZIP_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGL_FILESIZE_BASE_GZIP") WEBGL_FILESIZE_DIFF=$(node ./test/treeshake/utils/format-diff.js "$WEBGL_FILESIZE" "$WEBGL_FILESIZE_BASE") WEBGL_FILESIZE_DIFF_GZIP=$(node ./test/treeshake/utils/format-diff.js "$WEBGL_FILESIZE_GZIP" "$WEBGL_FILESIZE_BASE_GZIP") WEBGL_TREESHAKEN_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGL_TREESHAKEN") WEBGL_TREESHAKEN_GZIP_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGL_TREESHAKEN_GZIP") WEBGL_TREESHAKEN_BASE_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGL_TREESHAKEN_BASE") WEBGL_TREESHAKEN_BASE_GZIP_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGL_TREESHAKEN_BASE_GZIP") WEBGL_TREESHAKEN_DIFF=$(node ./test/treeshake/utils/format-diff.js "$WEBGL_TREESHAKEN" "$WEBGL_TREESHAKEN_BASE") WEBGL_TREESHAKEN_DIFF_GZIP=$(node ./test/treeshake/utils/format-diff.js "$WEBGL_TREESHAKEN_GZIP" "$WEBGL_TREESHAKEN_BASE_GZIP") WEBGPU_FILESIZE_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGPU_FILESIZE") WEBGPU_FILESIZE_GZIP_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGPU_FILESIZE_GZIP") WEBGPU_FILESIZE_BASE_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGPU_FILESIZE_BASE") WEBGPU_FILESIZE_BASE_GZIP_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGPU_FILESIZE_BASE_GZIP") WEBGPU_FILESIZE_DIFF=$(node ./test/treeshake/utils/format-diff.js "$WEBGPU_FILESIZE" "$WEBGPU_FILESIZE_BASE") WEBGPU_FILESIZE_DIFF_GZIP=$(node ./test/treeshake/utils/format-diff.js "$WEBGPU_FILESIZE_GZIP" "$WEBGPU_FILESIZE_BASE_GZIP") WEBGPU_TREESHAKEN_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGPU_TREESHAKEN") WEBGPU_TREESHAKEN_GZIP_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGPU_TREESHAKEN_GZIP") WEBGPU_TREESHAKEN_BASE_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGPU_TREESHAKEN_BASE") WEBGPU_TREESHAKEN_BASE_GZIP_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGPU_TREESHAKEN_BASE_GZIP") WEBGPU_TREESHAKEN_DIFF=$(node ./test/treeshake/utils/format-diff.js "$WEBGPU_TREESHAKEN" "$WEBGPU_TREESHAKEN_BASE") WEBGPU_TREESHAKEN_DIFF_GZIP=$(node ./test/treeshake/utils/format-diff.js "$WEBGPU_TREESHAKEN_GZIP" "$WEBGPU_TREESHAKEN_BASE_GZIP") WEBGPU_NODES_FILESIZE_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGPU_NODES_FILESIZE") WEBGPU_NODES_FILESIZE_GZIP_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGPU_NODES_FILESIZE_GZIP") WEBGPU_NODES_FILESIZE_BASE_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGPU_NODES_FILESIZE_BASE") WEBGPU_NODES_FILESIZE_BASE_GZIP_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGPU_NODES_FILESIZE_BASE_GZIP") WEBGPU_NODES_FILESIZE_DIFF=$(node ./test/treeshake/utils/format-diff.js "$WEBGPU_NODES_FILESIZE" "$WEBGPU_NODES_FILESIZE_BASE") WEBGPU_NODES_FILESIZE_DIFF_GZIP=$(node ./test/treeshake/utils/format-diff.js "$WEBGPU_NODES_FILESIZE_GZIP" "$WEBGPU_NODES_FILESIZE_BASE_GZIP") WEBGPU_NODES_TREESHAKEN_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGPU_NODES_TREESHAKEN") WEBGPU_NODES_TREESHAKEN_GZIP_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGPU_NODES_TREESHAKEN_GZIP") WEBGPU_NODES_TREESHAKEN_BASE_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGPU_NODES_TREESHAKEN_BASE") WEBGPU_NODES_TREESHAKEN_BASE_GZIP_FORM=$(node ./test/treeshake/utils/format-size.js "$WEBGPU_NODES_TREESHAKEN_BASE_GZIP") WEBGPU_NODES_TREESHAKEN_DIFF=$(node ./test/treeshake/utils/format-diff.js "$WEBGPU_NODES_TREESHAKEN" "$WEBGPU_NODES_TREESHAKEN_BASE") WEBGPU_NODES_TREESHAKEN_DIFF_GZIP=$(node ./test/treeshake/utils/format-diff.js "$WEBGPU_NODES_TREESHAKEN_GZIP" "$WEBGPU_NODES_TREESHAKEN_BASE_GZIP") echo "WEBGL_FILESIZE=$WEBGL_FILESIZE_FORM" >> $GITHUB_OUTPUT echo "WEBGL_FILESIZE_GZIP=$WEBGL_FILESIZE_GZIP_FORM" >> $GITHUB_OUTPUT echo "WEBGL_FILESIZE_BASE=$WEBGL_FILESIZE_BASE_FORM" >> $GITHUB_OUTPUT echo "WEBGL_FILESIZE_BASE_GZIP=$WEBGL_FILESIZE_BASE_GZIP_FORM" >> $GITHUB_OUTPUT echo "WEBGL_FILESIZE_DIFF=$WEBGL_FILESIZE_DIFF" >> $GITHUB_OUTPUT echo "WEBGL_FILESIZE_DIFF_GZIP=$WEBGL_FILESIZE_DIFF_GZIP" >> $GITHUB_OUTPUT echo "WEBGL_TREESHAKEN=$WEBGL_TREESHAKEN_FORM" >> $GITHUB_OUTPUT echo "WEBGL_TREESHAKEN_GZIP=$WEBGL_TREESHAKEN_GZIP_FORM" >> $GITHUB_OUTPUT echo "WEBGL_TREESHAKEN_BASE=$WEBGL_TREESHAKEN_BASE_FORM" >> $GITHUB_OUTPUT echo "WEBGL_TREESHAKEN_BASE_GZIP=$WEBGL_TREESHAKEN_BASE_GZIP_FORM" >> $GITHUB_OUTPUT echo "WEBGL_TREESHAKEN_DIFF=$WEBGL_TREESHAKEN_DIFF" >> $GITHUB_OUTPUT echo "WEBGL_TREESHAKEN_DIFF_GZIP=$WEBGL_TREESHAKEN_DIFF_GZIP" >> $GITHUB_OUTPUT echo "WEBGPU_FILESIZE=$WEBGPU_FILESIZE_FORM" >> $GITHUB_OUTPUT echo "WEBGPU_FILESIZE_GZIP=$WEBGPU_FILESIZE_GZIP_FORM" >> $GITHUB_OUTPUT echo "WEBGPU_FILESIZE_BASE=$WEBGPU_FILESIZE_BASE_FORM" >> $GITHUB_OUTPUT echo "WEBGPU_FILESIZE_BASE_GZIP=$WEBGPU_FILESIZE_BASE_GZIP_FORM" >> $GITHUB_OUTPUT echo "WEBGPU_FILESIZE_DIFF=$WEBGPU_FILESIZE_DIFF" >> $GITHUB_OUTPUT echo "WEBGPU_FILESIZE_DIFF_GZIP=$WEBGPU_FILESIZE_DIFF_GZIP" >> $GITHUB_OUTPUT echo "WEBGPU_TREESHAKEN=$WEBGPU_TREESHAKEN_FORM" >> $GITHUB_OUTPUT echo "WEBGPU_TREESHAKEN_GZIP=$WEBGPU_TREESHAKEN_GZIP_FORM" >> $GITHUB_OUTPUT echo "WEBGPU_TREESHAKEN_BASE=$WEBGPU_TREESHAKEN_BASE_FORM" >> $GITHUB_OUTPUT echo "WEBGPU_TREESHAKEN_BASE_GZIP=$WEBGPU_TREESHAKEN_BASE_GZIP_FORM" >> $GITHUB_OUTPUT echo "WEBGPU_TREESHAKEN_DIFF=$WEBGPU_TREESHAKEN_DIFF" >> $GITHUB_OUTPUT echo "WEBGPU_TREESHAKEN_DIFF_GZIP=$WEBGPU_TREESHAKEN_DIFF_GZIP" >> $GITHUB_OUTPUT echo "WEBGPU_NODES_FILESIZE=$WEBGPU_NODES_FILESIZE_FORM" >> $GITHUB_OUTPUT echo "WEBGPU_NODES_FILESIZE_GZIP=$WEBGPU_NODES_FILESIZE_GZIP_FORM" >> $GITHUB_OUTPUT echo "WEBGPU_NODES_FILESIZE_BASE=$WEBGPU_NODES_FILESIZE_BASE_FORM" >> $GITHUB_OUTPUT echo "WEBGPU_NODES_FILESIZE_BASE_GZIP=$WEBGPU_NODES_FILESIZE_BASE_GZIP_FORM" >> $GITHUB_OUTPUT echo "WEBGPU_NODES_FILESIZE_DIFF=$WEBGPU_NODES_FILESIZE_DIFF" >> $GITHUB_OUTPUT echo "WEBGPU_NODES_FILESIZE_DIFF_GZIP=$WEBGPU_NODES_FILESIZE_DIFF_GZIP" >> $GITHUB_OUTPUT echo "WEBGPU_NODES_TREESHAKEN=$WEBGPU_NODES_TREESHAKEN_FORM" >> $GITHUB_OUTPUT echo "WEBGPU_NODES_TREESHAKEN_GZIP=$WEBGPU_NODES_TREESHAKEN_GZIP_FORM" >> $GITHUB_OUTPUT echo "WEBGPU_NODES_TREESHAKEN_BASE=$WEBGPU_NODES_TREESHAKEN_BASE_FORM" >> $GITHUB_OUTPUT echo "WEBGPU_NODES_TREESHAKEN_BASE_GZIP=$WEBGPU_NODES_TREESHAKEN_BASE_GZIP_FORM" >> $GITHUB_OUTPUT echo "WEBGPU_NODES_TREESHAKEN_DIFF=$WEBGPU_NODES_TREESHAKEN_DIFF" >> $GITHUB_OUTPUT echo "WEBGPU_NODES_TREESHAKEN_DIFF_GZIP=$WEBGPU_NODES_TREESHAKEN_DIFF_GZIP" >> $GITHUB_OUTPUT - name: Find existing comment uses: peter-evans/find-comment@3eae4d37986fb5a8592848f6a574fdf654e61f9e # v3 id: find-comment with: issue-number: ${{ fromJSON(steps.download-artifact.outputs.result).pr }} comment-author: 'github-actions[bot]' body-includes: Bundle size - name: Comment on PR uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4 with: issue-number: ${{ fromJSON(steps.download-artifact.outputs.result).pr }} comment-id: ${{ steps.find-comment.outputs.comment-id }} edit-mode: replace body: | ### 📦 Bundle size _Full ESM build, minified and gzipped._ || Before | After | Diff | |:-:|:-:|:-:|:-:| | WebGL | ${{ steps.format.outputs.WEBGL_FILESIZE_BASE }}
**${{ steps.format.outputs.WEBGL_FILESIZE_BASE_GZIP }}** | ${{ steps.format.outputs.WEBGL_FILESIZE }}
**${{ steps.format.outputs.WEBGL_FILESIZE_GZIP }}** | ${{ steps.format.outputs.WEBGL_FILESIZE_DIFF }}
**${{ steps.format.outputs.WEBGL_FILESIZE_DIFF_GZIP }}** | | WebGPU | ${{ steps.format.outputs.WEBGPU_FILESIZE_BASE }}
**${{ steps.format.outputs.WEBGPU_FILESIZE_BASE_GZIP }}** | ${{ steps.format.outputs.WEBGPU_FILESIZE }}
**${{ steps.format.outputs.WEBGPU_FILESIZE_GZIP }}** | ${{ steps.format.outputs.WEBGPU_FILESIZE_DIFF }}
**${{ steps.format.outputs.WEBGPU_FILESIZE_DIFF_GZIP }}** | | WebGPU Nodes | ${{ steps.format.outputs.WEBGPU_NODES_FILESIZE_BASE }}
**${{ steps.format.outputs.WEBGPU_NODES_FILESIZE_BASE_GZIP }}** | ${{ steps.format.outputs.WEBGPU_NODES_FILESIZE }}
**${{ steps.format.outputs.WEBGPU_NODES_FILESIZE_GZIP }}** | ${{ steps.format.outputs.WEBGPU_NODES_FILESIZE_DIFF }}
**${{ steps.format.outputs.WEBGPU_NODES_FILESIZE_DIFF_GZIP }}** | ### 🌳 Bundle size after tree-shaking _Minimal build including a renderer, camera, empty scene, and dependencies._ || Before | After | Diff | |:-:|:-:|:-:|:-:| | WebGL | ${{ steps.format.outputs.WEBGL_TREESHAKEN_BASE }}
**${{ steps.format.outputs.WEBGL_TREESHAKEN_BASE_GZIP }}** | ${{ steps.format.outputs.WEBGL_TREESHAKEN }}
**${{ steps.format.outputs.WEBGL_TREESHAKEN_GZIP }}** | ${{ steps.format.outputs.WEBGL_TREESHAKEN_DIFF }}
**${{ steps.format.outputs.WEBGL_TREESHAKEN_DIFF_GZIP }}** | | WebGPU | ${{ steps.format.outputs.WEBGPU_TREESHAKEN_BASE }}
**${{ steps.format.outputs.WEBGPU_TREESHAKEN_BASE_GZIP }}** | ${{ steps.format.outputs.WEBGPU_TREESHAKEN }}
**${{ steps.format.outputs.WEBGPU_TREESHAKEN_GZIP }}** | ${{ steps.format.outputs.WEBGPU_TREESHAKEN_DIFF }}
**${{ steps.format.outputs.WEBGPU_TREESHAKEN_DIFF_GZIP }}** | | WebGPU Nodes | ${{ steps.format.outputs.WEBGPU_NODES_TREESHAKEN_BASE }}
**${{ steps.format.outputs.WEBGPU_NODES_TREESHAKEN_BASE_GZIP }}** | ${{ steps.format.outputs.WEBGPU_NODES_TREESHAKEN }}
**${{ steps.format.outputs.WEBGPU_NODES_TREESHAKEN_GZIP }}** | ${{ steps.format.outputs.WEBGPU_NODES_TREESHAKEN_DIFF }}
**${{ steps.format.outputs.WEBGPU_NODES_TREESHAKEN_DIFF_GZIP }}** |