From 4016d0d66393fe3cf17440877464806afe96ffc4 Mon Sep 17 00:00:00 2001 From: Marco Fugaro Date: Fri, 3 Mar 2023 11:39:55 +0100 Subject: [PATCH 1/6] Add report-size.yml action --- .github/workflows/read-size.yml | 47 +++++++++++++ .github/workflows/report-size.yml | 101 ++++++++++++++++++++++++++++ package-lock.json | 19 ++++++ package.json | 1 + test/treeshake/utils/format-diff.js | 10 +++ test/treeshake/utils/format-size.js | 7 ++ 6 files changed, 185 insertions(+) create mode 100644 .github/workflows/read-size.yml create mode 100644 .github/workflows/report-size.yml create mode 100644 test/treeshake/utils/format-diff.js create mode 100644 test/treeshake/utils/format-size.js diff --git a/.github/workflows/read-size.yml b/.github/workflows/read-size.yml new file mode 100644 index 00000000000000..dcfbf79c0f14a7 --- /dev/null +++ b/.github/workflows/read-size.yml @@ -0,0 +1,47 @@ +name: Read size + +on: + pull_request: + paths: + - 'src/**' + - 'package.json' + +# This workflow runs in a read-only environment. We can safely checkout +# the PR code here. +# Reference: +# https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ +permissions: + contents: read + +jobs: + treeshaking: + name: Tree-shaking + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@v3 + - name: Install Node + uses: actions/setup-node@v3 + with: + node-version: 18 + cache: 'npm' + - name: Install dependencies + run: npm ci + - name: Build + run: npm run build-module + - name: === Test tree-shaking === + run: npm run test-treeshake + - name: Read tree-shaken size + id: read-size + run: | + FILESIZE=$(stat --format=%s test/treeshake/index.bundle.min.js) + gzip -k test/treeshake/index.bundle.min.js + FILESIZE_GZIP=$(stat --format=%s test/treeshake/index.bundle.min.js.gz) + + # write the output in a json file to upload it as artifact + node -pe "JSON.stringify({ filesize: $FILESIZE, gzip: $FILESIZE_GZIP })" > sizes.json + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: sizes + path: sizes.json diff --git a/.github/workflows/report-size.yml b/.github/workflows/report-size.yml new file mode 100644 index 00000000000000..6507924aeac7de --- /dev/null +++ b/.github/workflows/report-size.yml @@ -0,0 +1,101 @@ +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: + treeshaking: + name: Tree-shaking + runs-on: ubuntu-latest + if: github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'success' + steps: + # Using actions/download-artifact doesn't work here + # https://github.com/actions/download-artifact/issues/60 + - name: Download artifact + uses: actions/github-script@v6 + 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 = fs.readFile('sizes.json', 'utf8'); + return json; + + # This runs on the base branch of the PR, meaning "dev" + - name: Git checkout + uses: actions/checkout@v3 + - name: Install Node + uses: actions/setup-node@v3 + with: + node-version: 18 + cache: 'npm' + - name: Install dependencies + run: npm ci + - name: Build + run: npm run build-module + - name: === Test tree-shaking === + run: npm run test-treeshake + - name: Read tree-shaken size + id: read-size + run: | + FILESIZE_BASE=$(stat --format=%s test/treeshake/index.bundle.min.js) + echo "FILESIZE_BASE=$FILESIZE_BASE" >> $GITHUB_OUTPUT + + - name: Format sizes + id: format + env: + FILESIZE: ${{ fromJSON(steps.download-artifact.outputs.result).filesize }} + FILESIZE_GZIP: ${{ fromJSON(steps.download-artifact.outputs.result).gzip }} + FILESIZE_BASE: ${{ steps.read-size.outputs.FILESIZE_BASE }} + run: | + FILESIZE_FORM=$(node ./test/treeshake/utils/format-size.js "$FILESIZE") + FILESIZE_GZIP_FORM=$(node ./test/treeshake/utils/format-size.js "$FILESIZE_GZIP") + FILESIZE_DIFF=$(node ./test/treeshake/utils/format-diff.js "$FILESIZE" "$FILESIZE_BASE") + echo "FILESIZE=$FILESIZE_FORM" >> $GITHUB_OUTPUT + echo "FILESIZE_GZIP=$FILESIZE_GZIP_FORM" >> $GITHUB_OUTPUT + echo "FILESIZE_DIFF=$FILESIZE_DIFF" >> $GITHUB_OUTPUT + + - name: Find existing comment + uses: peter-evans/find-comment@v2 + id: find-comment + with: + issue-number: ${{ github.event.workflow_run.pull_requests[0].number }} + comment-author: 'github-actions[bot]' + body-includes: Bundle size + - name: Comment on PR + uses: peter-evans/create-or-update-comment@v2 + with: + issue-number: ${{ github.event.workflow_run.pull_requests[0].number }} + comment-id: ${{ steps.find-comment.outputs.comment-id }} + edit-mode: replace + body: | + ### 📦 Bundle size after tree-shaking + | Filesize | Gzipped | Diff from `${{ github.ref_name }}` | + |----------|---------|------| + | ${{ steps.format.outputs.FILESIZE }} | ${{ steps.format.outputs.FILESIZE_GZIP }} | ${{ steps.format.outputs.FILESIZE_DIFF }} | diff --git a/package-lock.json b/package-lock.json index 6a2623a220dd7b..a21e70eade3ce1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "failonlyreporter": "^1.0.0", "jimp": "^0.22.5", "pixelmatch": "^5.3.0", + "pretty-bytes": "^6.1.0", "puppeteer-core": "^19.7.2", "qunit": "^2.19.4", "rollup": "^3.17.2", @@ -5100,6 +5101,18 @@ "node": ">= 0.8.0" } }, + "node_modules/pretty-bytes": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.0.tgz", + "integrity": "sha512-Rk753HI8f4uivXi4ZCIYdhmG1V+WKzvRMg/X+M42a6t7D07RcmopXJMDNk6N++7Bl75URRGsb40ruvg7Hcp2wQ==", + "dev": true, + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -10747,6 +10760,12 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, + "pretty-bytes": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.0.tgz", + "integrity": "sha512-Rk753HI8f4uivXi4ZCIYdhmG1V+WKzvRMg/X+M42a6t7D07RcmopXJMDNk6N++7Bl75URRGsb40ruvg7Hcp2wQ==", + "dev": true + }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", diff --git a/package.json b/package.json index bf8e916f55a559..b7559695069806 100644 --- a/package.json +++ b/package.json @@ -98,6 +98,7 @@ "failonlyreporter": "^1.0.0", "jimp": "^0.22.5", "pixelmatch": "^5.3.0", + "pretty-bytes": "^6.1.0", "puppeteer-core": "^19.7.2", "qunit": "^2.19.4", "rollup": "^3.17.2", diff --git a/test/treeshake/utils/format-diff.js b/test/treeshake/utils/format-diff.js new file mode 100644 index 00000000000000..0864f3e5ce658f --- /dev/null +++ b/test/treeshake/utils/format-diff.js @@ -0,0 +1,10 @@ +// used in report-size.yml + +const filesize = Number( process.argv[ 2 ] ); +const filesizeBase = Number( process.argv[ 3 ] ); + +const diff = ( filesize - filesizeBase ) * 100 / filesizeBase; +const diffString = diff.toFixed( 2 ).slice( - 1 ) === '0' ? diff.toFixed( 1 ) : diff.toFixed( 2 ); +const formatted = `${diff >= 0 ? '+' : ''}${diffString}%`; + +console.log( formatted ); diff --git a/test/treeshake/utils/format-size.js b/test/treeshake/utils/format-size.js new file mode 100644 index 00000000000000..3fa74509a2ea7c --- /dev/null +++ b/test/treeshake/utils/format-size.js @@ -0,0 +1,7 @@ +// used in report-size.yml +import prettyBytes from 'pretty-bytes'; + +const n = Number( process.argv[ 2 ] ); +const formatted = prettyBytes( n, { minimumFractionDigits: 0, maximumFractionDigits: 1 } ); + +console.log( formatted ); From 60e51c627b86a07b0db11648e17579561caf5abf Mon Sep 17 00:00:00 2001 From: Marco Fugaro Date: Fri, 3 Mar 2023 11:47:01 +0100 Subject: [PATCH 2/6] Format --- .github/workflows/report-size.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/report-size.yml b/.github/workflows/report-size.yml index 6507924aeac7de..07c9b9ded9be85 100644 --- a/.github/workflows/report-size.yml +++ b/.github/workflows/report-size.yml @@ -30,6 +30,7 @@ jobs: result-encoding: string script: | const fs = require('fs/promises'); + const artifacts = await github.rest.actions.listWorkflowRunArtifacts({ owner: context.repo.owner, repo: context.repo.repo, @@ -42,9 +43,10 @@ jobs: artifact_id: matchArtifact.id, archive_format: 'zip', }); + await fs.writeFile('sizes.zip', Buffer.from(download.data)); await exec.exec('unzip sizes.zip'); - const json = fs.readFile('sizes.json', 'utf8'); + const json = await fs.readFile('sizes.json', 'utf8'); return json; # This runs on the base branch of the PR, meaning "dev" From 5a8bf6c5a0cc258b771c0d966673dcd658db4cf4 Mon Sep 17 00:00:00 2001 From: Marco Fugaro Date: Fri, 3 Mar 2023 15:45:22 +0100 Subject: [PATCH 3/6] Report normal bundle size as well --- .github/workflows/read-size.yml | 11 +++++++---- .github/workflows/report-size.yml | 27 +++++++++++++++++++++++---- .gitignore | 1 + test/rollup.treeshake.config.js | 13 +++++++++++++ 4 files changed, 44 insertions(+), 8 deletions(-) diff --git a/.github/workflows/read-size.yml b/.github/workflows/read-size.yml index dcfbf79c0f14a7..2cc0f8b5de25d3 100644 --- a/.github/workflows/read-size.yml +++ b/.github/workflows/read-size.yml @@ -14,7 +14,7 @@ permissions: contents: read jobs: - treeshaking: + read-size: name: Tree-shaking runs-on: ubuntu-latest steps: @@ -34,12 +34,15 @@ jobs: - name: Read tree-shaken size id: read-size run: | - FILESIZE=$(stat --format=%s test/treeshake/index.bundle.min.js) + FILESIZE=$(stat --format=%s test/treeshake/three.module.min.js) + gzip -k test/treeshake/three.module.min.js + FILESIZE_GZIP=$(stat --format=%s test/treeshake/three.module.min.js.gz) + TREESHAKEN=$(stat --format=%s test/treeshake/index.bundle.min.js) gzip -k test/treeshake/index.bundle.min.js - FILESIZE_GZIP=$(stat --format=%s test/treeshake/index.bundle.min.js.gz) + TREESHAKEN_GZIP=$(stat --format=%s test/treeshake/index.bundle.min.js.gz) # write the output in a json file to upload it as artifact - node -pe "JSON.stringify({ filesize: $FILESIZE, gzip: $FILESIZE_GZIP })" > sizes.json + node -pe "JSON.stringify({ filesize: $FILESIZE, gzip: $FILESIZE_GZIP, treeshaken: $TREESHAKEN, treeshakenGzip: $TREESHAKEN_GZIP })" > sizes.json - name: Upload artifact uses: actions/upload-artifact@v3 with: diff --git a/.github/workflows/report-size.yml b/.github/workflows/report-size.yml index 07c9b9ded9be85..35cb3d333598bd 100644 --- a/.github/workflows/report-size.yml +++ b/.github/workflows/report-size.yml @@ -15,8 +15,8 @@ permissions: pull-requests: write jobs: - treeshaking: - name: Tree-shaking + report-size: + name: Comment on PR runs-on: ubuntu-latest if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' @@ -66,22 +66,36 @@ jobs: - name: Read tree-shaken size id: read-size run: | - FILESIZE_BASE=$(stat --format=%s test/treeshake/index.bundle.min.js) + FILESIZE_BASE=$(stat --format=%s test/treeshake/three.module.min.js) + TREESHAKEN_BASE=$(stat --format=%s test/treeshake/index.bundle.min.js) echo "FILESIZE_BASE=$FILESIZE_BASE" >> $GITHUB_OUTPUT + echo "TREESHAKEN_BASE=$TREESHAKEN_BASE" >> $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: FILESIZE: ${{ fromJSON(steps.download-artifact.outputs.result).filesize }} FILESIZE_GZIP: ${{ fromJSON(steps.download-artifact.outputs.result).gzip }} FILESIZE_BASE: ${{ steps.read-size.outputs.FILESIZE_BASE }} + TREESHAKEN: ${{ fromJSON(steps.download-artifact.outputs.result).treeshaken }} + TREESHAKEN_GZIP: ${{ fromJSON(steps.download-artifact.outputs.result).treeshakenGzip }} + TREESHAKEN_BASE: ${{ steps.read-size.outputs.TREESHAKEN_BASE }} run: | FILESIZE_FORM=$(node ./test/treeshake/utils/format-size.js "$FILESIZE") FILESIZE_GZIP_FORM=$(node ./test/treeshake/utils/format-size.js "$FILESIZE_GZIP") FILESIZE_DIFF=$(node ./test/treeshake/utils/format-diff.js "$FILESIZE" "$FILESIZE_BASE") + TREESHAKEN_FORM=$(node ./test/treeshake/utils/format-size.js "$TREESHAKEN") + TREESHAKEN_GZIP_FORM=$(node ./test/treeshake/utils/format-size.js "$TREESHAKEN_GZIP") + TREESHAKEN_DIFF=$(node ./test/treeshake/utils/format-diff.js "$TREESHAKEN" "$TREESHAKEN_BASE") + echo "FILESIZE=$FILESIZE_FORM" >> $GITHUB_OUTPUT echo "FILESIZE_GZIP=$FILESIZE_GZIP_FORM" >> $GITHUB_OUTPUT echo "FILESIZE_DIFF=$FILESIZE_DIFF" >> $GITHUB_OUTPUT + echo "TREESHAKEN=$TREESHAKEN_FORM" >> $GITHUB_OUTPUT + echo "TREESHAKEN_GZIP=$TREESHAKEN_GZIP_FORM" >> $GITHUB_OUTPUT + echo "TREESHAKEN_DIFF=$TREESHAKEN_DIFF" >> $GITHUB_OUTPUT - name: Find existing comment uses: peter-evans/find-comment@v2 @@ -97,7 +111,12 @@ jobs: comment-id: ${{ steps.find-comment.outputs.comment-id }} edit-mode: replace body: | - ### 📦 Bundle size after tree-shaking + ### 📦 Bundle size | Filesize | Gzipped | Diff from `${{ github.ref_name }}` | |----------|---------|------| | ${{ steps.format.outputs.FILESIZE }} | ${{ steps.format.outputs.FILESIZE_GZIP }} | ${{ steps.format.outputs.FILESIZE_DIFF }} | + + ### 🌳 Bundle size after tree-shaking + | Filesize | Gzipped | Diff from `${{ github.ref_name }}` | + |----------|---------|------| + | ${{ steps.format.outputs.TREESHAKEN }} | ${{ steps.format.outputs.TREESHAKEN_GZIP }} | ${{ steps.format.outputs.TREESHAKEN_DIFF }} | diff --git a/.gitignore b/.gitignore index 50df59a8212b6c..f3a967d1af95e1 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ test/unit/build test/treeshake/index.bundle.js test/treeshake/index.bundle.min.js test/treeshake/index-src.bundle.min.js +test/treeshake/three.module.min.js test/treeshake/stats.html test/e2e/chromium test/e2e/output-screenshots diff --git a/test/rollup.treeshake.config.js b/test/rollup.treeshake.config.js index 6adcb33eae0ed2..b68165fdba1e8e 100644 --- a/test/rollup.treeshake.config.js +++ b/test/rollup.treeshake.config.js @@ -70,4 +70,17 @@ export default [ } ] }, + // esm bundle size minified, used in read-size.yml + { + input: 'build/three.module.js', + plugins: [ + terser(), + ], + output: [ + { + format: 'esm', + file: 'test/treeshake/three.module.min.js' + } + ] + }, ]; From 8a60d36734204d9242d91d028e848790cde56682 Mon Sep 17 00:00:00 2001 From: Marco Fugaro Date: Fri, 3 Mar 2023 15:53:34 +0100 Subject: [PATCH 4/6] Wording --- .github/workflows/read-size.yml | 2 +- .github/workflows/report-size.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/read-size.yml b/.github/workflows/read-size.yml index 2cc0f8b5de25d3..9d8a8cc10778d5 100644 --- a/.github/workflows/read-size.yml +++ b/.github/workflows/read-size.yml @@ -31,7 +31,7 @@ jobs: run: npm run build-module - name: === Test tree-shaking === run: npm run test-treeshake - - name: Read tree-shaken size + - name: Read bundle sizes id: read-size run: | FILESIZE=$(stat --format=%s test/treeshake/three.module.min.js) diff --git a/.github/workflows/report-size.yml b/.github/workflows/report-size.yml index 35cb3d333598bd..ed6b74d431954f 100644 --- a/.github/workflows/report-size.yml +++ b/.github/workflows/report-size.yml @@ -63,7 +63,7 @@ jobs: run: npm run build-module - name: === Test tree-shaking === run: npm run test-treeshake - - name: Read tree-shaken size + - name: Read sizes id: read-size run: | FILESIZE_BASE=$(stat --format=%s test/treeshake/three.module.min.js) From 48401b2cabb8ceae3860a802388aa93a3d1ee419 Mon Sep 17 00:00:00 2001 From: Marco Fugaro Date: Mon, 6 Mar 2023 10:46:36 +0100 Subject: [PATCH 5/6] Remove pretty-bytes dependency --- package-lock.json | 19 ------------------- package.json | 1 - test/treeshake/utils/format-size.js | 17 +++++++++++++++-- 3 files changed, 15 insertions(+), 22 deletions(-) diff --git a/package-lock.json b/package-lock.json index a21e70eade3ce1..6a2623a220dd7b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,6 @@ "failonlyreporter": "^1.0.0", "jimp": "^0.22.5", "pixelmatch": "^5.3.0", - "pretty-bytes": "^6.1.0", "puppeteer-core": "^19.7.2", "qunit": "^2.19.4", "rollup": "^3.17.2", @@ -5101,18 +5100,6 @@ "node": ">= 0.8.0" } }, - "node_modules/pretty-bytes": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.0.tgz", - "integrity": "sha512-Rk753HI8f4uivXi4ZCIYdhmG1V+WKzvRMg/X+M42a6t7D07RcmopXJMDNk6N++7Bl75URRGsb40ruvg7Hcp2wQ==", - "dev": true, - "engines": { - "node": "^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -10760,12 +10747,6 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, - "pretty-bytes": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.0.tgz", - "integrity": "sha512-Rk753HI8f4uivXi4ZCIYdhmG1V+WKzvRMg/X+M42a6t7D07RcmopXJMDNk6N++7Bl75URRGsb40ruvg7Hcp2wQ==", - "dev": true - }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", diff --git a/package.json b/package.json index b7559695069806..bf8e916f55a559 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,6 @@ "failonlyreporter": "^1.0.0", "jimp": "^0.22.5", "pixelmatch": "^5.3.0", - "pretty-bytes": "^6.1.0", "puppeteer-core": "^19.7.2", "qunit": "^2.19.4", "rollup": "^3.17.2", diff --git a/test/treeshake/utils/format-size.js b/test/treeshake/utils/format-size.js index 3fa74509a2ea7c..1ae96b73044ed2 100644 --- a/test/treeshake/utils/format-size.js +++ b/test/treeshake/utils/format-size.js @@ -1,7 +1,20 @@ // used in report-size.yml -import prettyBytes from 'pretty-bytes'; + +export function formatBytes( bytes, decimals = 1 ) { + + if ( bytes === 0 ) return '0 B'; + + const k = 1000; + const dm = decimals < 0 ? 0 : decimals; + const sizes = [ 'B', 'kB', 'MB', 'GB' ]; + + const i = Math.floor( Math.log( bytes ) / Math.log( k ) ); + + return parseFloat( ( bytes / Math.pow( k, i ) ).toFixed( dm ) ) + ' ' + sizes[ i ]; + +} const n = Number( process.argv[ 2 ] ); -const formatted = prettyBytes( n, { minimumFractionDigits: 0, maximumFractionDigits: 1 } ); +const formatted = formatBytes( n ); console.log( formatted ); From 21505c2e7d0750670f6d34cb1ec1276153d65153 Mon Sep 17 00:00:00 2001 From: Marco Fugaro Date: Mon, 6 Mar 2023 10:52:57 +0100 Subject: [PATCH 6/6] Add clarification about tree-shaking in message --- .github/workflows/report-size.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/report-size.yml b/.github/workflows/report-size.yml index ed6b74d431954f..a563453bc0bf51 100644 --- a/.github/workflows/report-size.yml +++ b/.github/workflows/report-size.yml @@ -117,6 +117,9 @@ jobs: | ${{ steps.format.outputs.FILESIZE }} | ${{ steps.format.outputs.FILESIZE_GZIP }} | ${{ steps.format.outputs.FILESIZE_DIFF }} | ### 🌳 Bundle size after tree-shaking + + _Includes a renderer, camera, and empty scene._ + | Filesize | Gzipped | Diff from `${{ github.ref_name }}` | |----------|---------|------| | ${{ steps.format.outputs.TREESHAKEN }} | ${{ steps.format.outputs.TREESHAKEN_GZIP }} | ${{ steps.format.outputs.TREESHAKEN_DIFF }} |