Merge pull request #5285 from material-components:size

PiperOrigin-RevId: 591037361
This commit is contained in:
Copybara-Service 2023-12-14 13:34:16 -08:00
commit 6eb9fe670f
10 changed files with 752 additions and 93 deletions

View File

@ -0,0 +1,43 @@
name: Update size
on:
push:
branches: main
workflow_dispatch:
# allows triggering from the github UI
jobs:
check-for-doc-changes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: 20
cache: npm
- uses: google/wireit@setup-github-actions-caching/v1
- name: Install Dependencies
run: npm ci
- name: Update Size
run: npm run update-size
- name: Check if update-size produces git diff
id: ifChange
run: git diff --exit-code || echo "::set-output name=changed::yes"
- name: Create or update PR
if: steps.ifChange.outputs.changed == 'yes'
uses: peter-evans/create-pull-request@v5
with:
token: ${{ secrets.LIT_ROBOT_ACCESS_TOKEN }}
commit-message: 'chore: update sizes'
author: lit-robot <lit-robot@google.com>
committer: lit-robot <lit-robot@google.com>
title: 'chore: update sizes'
body: This PR was auto generated by the update-size-on-main GitHub action.
reviewers: e111077,asyncliz
branch: auto-update-size
# Don't automatically add Ready for Google label until we're ready
# since this will be noisy.

View File

@ -16,5 +16,6 @@ Google's open-source design system.
- [Introduction](docs/intro.md)
- [Roadmap](docs/roadmap.md)
- [Quick start](docs/quick-start.md)
- [Bundle sizes](docs/size.md)
- [Component docs](docs/components/)
- [Browser support and FAQ](docs/support.md)

96
docs/size.md Normal file
View File

@ -0,0 +1,96 @@
# Sizes
<!-- go/mwc-size -->
<!--*
# Document freshness: For more information, see go/fresh-source.
freshness: { owner: 'lizmitchell' reviewed: '2023-12-13' }
*-->
<!-- [TOC] -->
This doc tracks important size metrics for Material Web Components.
Sizes are tracked in bundles. A bundle is a single `.js` file for one or more
components that includes all of the JavaScript and CSS needed, minus external
dependencies. We track three metrics:
- **gzip** - minified and compressed. This impacts download size, which can
take longer over slow networks.
- **minified** - minified and unpacked. This impacts the time it takes a page
to be interactive, which can take longer on some devices.
- **% CSS** - the amount of CSS compared to JavaScript. The bundle includes
both JS and CSS, so this helps track changes to JS logic and CSS styles
separately.
<!-- Autogenerated below, do not update! -->
<!-- MWC_UPDATE_TRACKING_START -->
<sub>Last updated 2023-12-13.</sub>
<!-- mdformat off(autogenerated might break rendering in catalog) -->
| Component | gzip | minified | *% CSS* | Import |
| --- | --- | --- | --- | --- |
| **All** | **70.1kb** | 451.9kb | *66% CSS* | `@material/web/all.js` |
| **Common** | **51.5kb** | 282.2kb | *54% CSS* | `@material/web/common.js` |
| **Button** | **8.0kb** | 46.3kb | *66% CSS* | |
| | 6.7kb | 27.4kb | *49% CSS* | `@material/web/button/elevated-button.js` |
| | 6.6kb | 27.3kb | *49% CSS* | `@material/web/button/filled-button.js` |
| | 6.7kb | 27.7kb | *49% CSS* | `@material/web/button/filled-tonal-button.js` |
| | 6.4kb | 25.7kb | *48% CSS* | `@material/web/button/outlined-button.js` |
| | 6.2kb | 24.2kb | *45% CSS* | `@material/web/button/text-button.js` |
| **Checkbox** | **7.0kb** | 28.5kb | *43% CSS* | `@material/web/checkbox/checkbox.js` |
| **Chips** | **10.0kb** | 60.4kb | *64% CSS* | |
| | 4.8kb | 16.4kb | *22% CSS* | `@material/web/chips/chip-set.js` |
| | 6.3kb | 26.8kb | *51% CSS* | `@material/web/chips/assist-chip.js` |
| | 7.9kb | 37.0kb | *55% CSS* | `@material/web/chips/filter-chip.js` |
| | 7.3kb | 33.7kb | *54% CSS* | `@material/web/chips/input-chip.js` |
| | 6.4kb | 27.2kb | *51% CSS* | `@material/web/chips/suggestion-chip.js` |
| **Dialog** | **4.2kb** | 15.2kb | *36% CSS* | `@material/web/dialog/dialog.js` |
| **Divider** | **0.7kb** | 1.4kb | *39% CSS* | `@material/web/divider/divider.js` |
| **Elevation** | **0.7kb** | 1.7kb | *62% CSS* | `@material/web/elevation/elevation.js` |
| **Fab** | **6.9kb** | 37.1kb | *67% CSS* | |
| | 6.6kb | 32.8kb | *64% CSS* | `@material/web/fab/fab.js` |
| | 5.8kb | 24.6kb | *51% CSS* | `@material/web/fab/branded-fab.js` |
| **Field** | **6.0kb** | 40.5kb | *83% CSS* | |
| | 4.6kb | 24.8kb | *75% CSS* | `@material/web/field/filled-field.js` |
| | 5.0kb | 27.1kb | *76% CSS* | `@material/web/field/outlined-field.js` |
| **Focus** | **1.6kb** | 5.2kb | *46% CSS* | `@material/web/focus/md-focus-ring.js` |
| **Icon** | **0.7kb** | 1.3kb | *46% CSS* | `@material/web/icon/icon.js` |
| **Icon button** | **7.3kb** | 42.0kb | *65% CSS* | |
| | 5.8kb | 23.1kb | *42% CSS* | `@material/web/iconbutton/icon-button.js` |
| | 6.0kb | 25.0kb | *45% CSS* | `@material/web/iconbutton/filled-icon-button.js` |
| | 6.0kb | 25.5kb | *46% CSS* | `@material/web/iconbutton/filled-tonal-icon-button.js` |
| | 6.0kb | 24.6kb | *45% CSS* | `@material/web/iconbutton/outlined-icon-button.js` |
| **List** | **6.9kb** | 27.2kb | *35% CSS* | |
| | 1.6kb | 4.5kb | *5% CSS* | `@material/web/list/list.js` |
| | 5.8kb | 23.0kb | *40% CSS* | `@material/web/list/list-item.js` |
| **Menu** | **13.5kb** | 53.9kb | *23% CSS* | |
| | 7.9kb | 28.8kb | *17% CSS* | `@material/web/menu/menu.js` |
| | 6.5kb | 25.6kb | *37% CSS* | `@material/web/menu/menu-item.js` |
| | 8.4kb | 31.9kb | *11% CSS* | `@material/web/menu/sub-menu.js` |
| **Progress** | **3.5kb** | 13.9kb | *70% CSS* | |
| | 2.6kb | 8.6kb | *64% CSS* | `@material/web/progress/linear-progress.js` |
| | 2.2kb | 7.4kb | *57% CSS* | `@material/web/progress/circular-progress.js` |
| **Radio** | **6.9kb** | 26.0kb | *31% CSS* | `@material/web/radio/radio.js` |
| **Ripple** | **2.8kb** | 7.9kb | *14% CSS* | `@material/web/ripple/ripple.js` |
| **Select** | **25.6kb** | 142.5kb | *57% CSS* | |
| | 17.8kb | 89.3kb | *48% CSS* | `@material/web/select/filled-select.js` |
| | 18.1kb | 89.9kb | *48% CSS* | `@material/web/select/outlined-select.js` |
| | 6.6kb | 26.6kb | *36% CSS* | `@material/web/select/select-option.js` |
| **Slider** | **9.7kb** | 45.0kb | *49% CSS* | `@material/web/slider/slider.js` |
| **Switch** | **7.8kb** | 34.8kb | *53% CSS* | `@material/web/switch/switch.js` |
| **Tabs** | **7.9kb** | 35.1kb | *50% CSS* | |
| | 6.2kb | 21.9kb | *25% CSS* | `@material/web/tabs/tabs.js` |
| | 6.3kb | 25.6kb | *48% CSS* | `@material/web/tabs/primary-tab.js` |
| | 6.2kb | 25.2kb | *48% CSS* | `@material/web/tabs/secondary-tab.js` |
| **Text field** | **13.7kb** | 93.0kb | *74% CSS* | |
| | 10.7kb | 60.8kb | *62% CSS* | `@material/web/textfield/filled-text-field.js` |
| | 10.9kb | 61.3kb | *62% CSS* | `@material/web/textfield/outlined-text-field.js` |
<!-- mdformat on(autogenerated might break rendering in catalog) -->
<!-- MWC_UPDATE_TRACKING_END -->

323
package-lock.json generated
View File

@ -17,10 +17,14 @@
},
"devDependencies": {
"@lit-labs/analyzer": "^0.9.2",
"@rollup/plugin-multi-entry": "^6.0.1",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-terser": "^0.4.4",
"@types/jasmine": "^4.0.3",
"@web/test-runner": "^0.15.0",
"@web/test-runner-playwright": "^0.9.0",
"jasmine": "^4.5.0",
"rollup": "^2.79.1",
"sass": "^1.52.3",
"sass-true": "^6.1.0",
"typescript": "5.1.6",
@ -746,6 +750,20 @@
"integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==",
"dev": true
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
"integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
"dev": true,
"dependencies": {
"@jridgewell/set-array": "^1.0.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
"@jridgewell/trace-mapping": "^0.3.9"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
@ -755,6 +773,25 @@
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/set-array": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
"integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
"dev": true,
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/source-map": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
"integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
"dev": true,
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.0",
"@jridgewell/trace-mapping": "^0.3.9"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.14",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
@ -1448,41 +1485,111 @@
}
}
},
"node_modules/@rollup/plugin-node-resolve": {
"version": "13.3.0",
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.3.0.tgz",
"integrity": "sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw==",
"node_modules/@rollup/plugin-multi-entry": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-multi-entry/-/plugin-multi-entry-6.0.1.tgz",
"integrity": "sha512-AXm6toPyTSfbYZWghQGbom1Uh7dHXlrGa+HoiYNhQtDUE3Q7LqoUYdVQx9E1579QWS1uOiu+cZRSE4okO7ySgw==",
"dev": true,
"dependencies": {
"@rollup/pluginutils": "^3.1.0",
"@types/resolve": "1.17.1",
"deepmerge": "^4.2.2",
"is-builtin-module": "^3.1.0",
"is-module": "^1.0.0",
"resolve": "^1.19.0"
"@rollup/plugin-virtual": "^3.0.0",
"matched": "^5.0.1"
},
"engines": {
"node": ">= 10.0.0"
"node": ">=14.0.0"
},
"peerDependencies": {
"rollup": "^2.42.0"
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
}
},
"node_modules/@rollup/plugin-node-resolve": {
"version": "15.2.3",
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz",
"integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==",
"dev": true,
"dependencies": {
"@rollup/pluginutils": "^5.0.1",
"@types/resolve": "1.20.2",
"deepmerge": "^4.2.2",
"is-builtin-module": "^3.2.1",
"is-module": "^1.0.0",
"resolve": "^1.22.1"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"rollup": "^2.78.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
}
},
"node_modules/@rollup/plugin-terser": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz",
"integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==",
"dev": true,
"dependencies": {
"serialize-javascript": "^6.0.1",
"smob": "^1.0.0",
"terser": "^5.17.4"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"rollup": "^2.0.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
}
},
"node_modules/@rollup/plugin-virtual": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-3.0.2.tgz",
"integrity": "sha512-10monEYsBp3scM4/ND4LNH5Rxvh3e/cVeL3jWTgZ2SrQ+BmUoQcopVQvnaMcOnykb1VkxUFuDAN+0FnpTFRy2A==",
"dev": true,
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
}
},
"node_modules/@rollup/pluginutils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
"integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz",
"integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==",
"dev": true,
"dependencies": {
"@types/estree": "0.0.39",
"estree-walker": "^1.0.1",
"picomatch": "^2.2.2"
"@types/estree": "^1.0.0",
"estree-walker": "^2.0.2",
"picomatch": "^2.3.1"
},
"engines": {
"node": ">= 8.0.0"
"node": ">=14.0.0"
},
"peerDependencies": {
"rollup": "^1.20.0||^2.0.0"
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
}
},
"node_modules/@sindresorhus/slugify": {
@ -1640,9 +1747,9 @@
"dev": true
},
"node_modules/@types/estree": {
"version": "0.0.39",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw=="
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
},
"node_modules/@types/express": {
"version": "4.17.17",
@ -1826,13 +1933,10 @@
"dev": true
},
"node_modules/@types/resolve": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
"integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
"version": "1.20.2",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
"integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
"dev": true
},
"node_modules/@types/send": {
"version": "0.17.1",
@ -2030,6 +2134,64 @@
"node": ">=10.0.0"
}
},
"node_modules/@web/dev-server-rollup/node_modules/@rollup/plugin-node-resolve": {
"version": "13.3.0",
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.3.0.tgz",
"integrity": "sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw==",
"dev": true,
"dependencies": {
"@rollup/pluginutils": "^3.1.0",
"@types/resolve": "1.17.1",
"deepmerge": "^4.2.2",
"is-builtin-module": "^3.1.0",
"is-module": "^1.0.0",
"resolve": "^1.19.0"
},
"engines": {
"node": ">= 10.0.0"
},
"peerDependencies": {
"rollup": "^2.42.0"
}
},
"node_modules/@web/dev-server-rollup/node_modules/@rollup/pluginutils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
"integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==",
"dev": true,
"dependencies": {
"@types/estree": "0.0.39",
"estree-walker": "^1.0.1",
"picomatch": "^2.2.2"
},
"engines": {
"node": ">= 8.0.0"
},
"peerDependencies": {
"rollup": "^1.20.0||^2.0.0"
}
},
"node_modules/@web/dev-server-rollup/node_modules/@types/estree": {
"version": "0.0.39",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
"dev": true
},
"node_modules/@web/dev-server-rollup/node_modules/@types/resolve": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
"integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@web/dev-server-rollup/node_modules/estree-walker": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
"integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
"dev": true
},
"node_modules/@web/dev-server-rollup/node_modules/parse5": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
@ -2553,6 +2715,12 @@
"node": "*"
}
},
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"dev": true
},
"node_modules/builtin-modules": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
@ -3612,9 +3780,9 @@
}
},
"node_modules/estree-walker": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
"integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"dev": true
},
"node_modules/etag": {
@ -5258,6 +5426,22 @@
"integrity": "sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==",
"dev": true
},
"node_modules/matched": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/matched/-/matched-5.0.1.tgz",
"integrity": "sha512-E1fhSTPRyhAlNaNvGXAgZQlq1hL0bgYMTk/6bktVlIhzUnX/SZs7296ACdVeNJE8xFNGSuvd9IpI7vSnmcqLvw==",
"dev": true,
"dependencies": {
"glob": "^7.1.6",
"picomatch": "^2.2.1"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/material-web-catalog": {
"resolved": "catalog",
"link": true
@ -6416,6 +6600,15 @@
}
]
},
"node_modules/randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
"dev": true,
"dependencies": {
"safe-buffer": "^5.1.0"
}
},
"node_modules/raw-body": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
@ -6784,6 +6977,15 @@
"integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
"dev": true
},
"node_modules/serialize-javascript": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz",
"integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==",
"dev": true,
"dependencies": {
"randombytes": "^2.1.0"
}
},
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
@ -6899,6 +7101,12 @@
"node": ">=8.0.0"
}
},
"node_modules/smob": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/smob/-/smob-1.4.1.tgz",
"integrity": "sha512-9LK+E7Hv5R9u4g4C3p+jjLstaLe11MDsL21UpYaCNmapvMkYhqCV4A/f/3gyH8QjMyh6l68q9xC85vihY9ahMQ==",
"dev": true
},
"node_modules/source-map": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
@ -6928,6 +7136,25 @@
"decode-uri-component": "^0.2.0"
}
},
"node_modules/source-map-support": {
"version": "0.5.21",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"dev": true,
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
"node_modules/source-map-support/node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/sourcemap-codec": {
"version": "1.4.8",
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
@ -7115,6 +7342,36 @@
"node": ">=6"
}
},
"node_modules/terser": {
"version": "5.26.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz",
"integrity": "sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==",
"dev": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.8.2",
"commander": "^2.20.0",
"source-map-support": "~0.5.20"
},
"bin": {
"terser": "bin/terser"
},
"engines": {
"node": ">=10"
}
},
"node_modules/terser/node_modules/acorn": {
"version": "8.11.2",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz",
"integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",

View File

@ -29,8 +29,9 @@
"build:sass": "wireit",
"test": "wireit",
"build:catalog": "wireit",
"build:analyzer": "wireit",
"update-docs": "wireit"
"build:scripts": "wireit",
"update-docs": "wireit",
"update-size": "wireit"
},
"type": "module",
"files": [
@ -56,10 +57,14 @@
},
"devDependencies": {
"@lit-labs/analyzer": "^0.9.2",
"@rollup/plugin-multi-entry": "^6.0.1",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-terser": "^0.4.4",
"@types/jasmine": "^4.0.3",
"@web/test-runner": "^0.15.0",
"@web/test-runner-playwright": "^0.9.0",
"jasmine": "^4.5.0",
"rollup": "^2.79.1",
"sass": "^1.52.3",
"sass-true": "^6.1.0",
"typescript": "5.1.6",
@ -145,19 +150,19 @@
"./catalog:build:prod"
]
},
"build:analyzer": {
"build:scripts": {
"command": "tsc -b scripts/tsconfig.json --pretty",
"files": [
"scripts/tsconfig.json",
"scripts/analyzer/**/*.ts",
"scripts/**/*.ts",
"!**/*.d.ts",
"!**/*.css.ts"
],
"output": [
"scripts/.tsbuildinfo",
"scripts/analyzer/**/*.js",
"scripts/analyzer/**/*.js.map",
"scripts/analyzer/**/*.d.ts"
"scripts/**/*.js",
"scripts/**/*.js.map",
"scripts/**/*.d.ts"
],
"clean": "if-file-deleted"
},
@ -175,7 +180,14 @@
],
"output": [],
"dependencies": [
"build:analyzer"
"build:scripts"
]
},
"update-size": {
"command": "node scripts/size/update-size.js",
"dependencies": [
"build:scripts",
"build"
]
}
}

View File

@ -4,56 +4,31 @@
* SPDX-License-Identifier: Apache-2.0
*/
import {COMPONENT_CUSTOM_ELEMENTS} from '../component-custom-elements.js';
/**
* A map of Markdown documentation file name to element entrypoints associated
* with that documentation.
*/
export const docsToElementMapping: {[key: string]: string[]} = {
'button.md': [
'button/elevated-button.ts',
'button/filled-button.ts',
'button/filled-tonal-button.ts',
'button/outlined-button.ts',
'button/text-button.ts',
],
'checkbox.md': ['checkbox/checkbox.ts'],
'chip.md': [
'chips/chip-set.ts',
'chips/assist-chip.ts',
'chips/filter-chip.ts',
'chips/input-chip.ts',
'chips/suggestion-chip.ts',
],
'dialog.md': ['dialog/dialog.ts'],
'divider.md': ['divider/divider.ts'],
'elevation.md': ['elevation/elevation.ts'],
'fab.md': ['fab/fab.ts', 'fab/branded-fab.ts'],
'focus-ring.md': ['focus/md-focus-ring.ts'],
'icon-button.md': [
'iconbutton/icon-button.ts',
'iconbutton/filled-icon-button.ts',
'iconbutton/filled-tonal-icon-button.ts',
'iconbutton/outlined-icon-button.ts',
],
'icon.md': ['icon/icon.ts'],
'list.md': ['list/list.ts', 'list/list-item.ts'],
'menu.md': ['menu/menu.ts', 'menu/menu-item.ts', 'menu/sub-menu.ts'],
'progress.md': [
'progress/linear-progress.ts',
'progress/circular-progress.ts',
],
'radio.md': ['radio/radio.ts'],
'ripple.md': ['ripple/ripple.ts'],
'slider.md': ['slider/slider.ts'],
'switch.md': ['switch/switch.ts'],
'tabs.md': ['tabs/tabs.ts', 'tabs/primary-tab.ts', 'tabs/secondary-tab.ts'],
'text-field.md': [
'textfield/filled-text-field.ts',
'textfield/outlined-text-field.ts',
],
'select.md': [
'select/filled-select.ts',
'select/outlined-select.ts',
'select/select-option.ts',
],
export const docsToElementMapping: {[key: string]: readonly string[]} = {
'button.md': COMPONENT_CUSTOM_ELEMENTS.button,
'checkbox.md': COMPONENT_CUSTOM_ELEMENTS.checkbox,
'chip.md': COMPONENT_CUSTOM_ELEMENTS.chips,
'dialog.md': COMPONENT_CUSTOM_ELEMENTS.dialog,
'divider.md': COMPONENT_CUSTOM_ELEMENTS.divider,
'elevation.md': COMPONENT_CUSTOM_ELEMENTS.elevation,
'fab.md': COMPONENT_CUSTOM_ELEMENTS.fab,
'focus-ring.md': COMPONENT_CUSTOM_ELEMENTS.focus,
'icon-button.md': COMPONENT_CUSTOM_ELEMENTS.iconButton,
'icon.md': COMPONENT_CUSTOM_ELEMENTS.icon,
'list.md': COMPONENT_CUSTOM_ELEMENTS.list,
'menu.md': COMPONENT_CUSTOM_ELEMENTS.menu,
'progress.md': COMPONENT_CUSTOM_ELEMENTS.progress,
'radio.md': COMPONENT_CUSTOM_ELEMENTS.radio,
'ripple.md': COMPONENT_CUSTOM_ELEMENTS.ripple,
'slider.md': COMPONENT_CUSTOM_ELEMENTS.slider,
'switch.md': COMPONENT_CUSTOM_ELEMENTS.switch,
'tabs.md': COMPONENT_CUSTOM_ELEMENTS.tabs,
'text-field.md': COMPONENT_CUSTOM_ELEMENTS.textField,
'select.md': COMPONENT_CUSTOM_ELEMENTS.select,
};

View File

@ -40,7 +40,7 @@ export class MarkdownTable {
addRow(row: string[]) {
if (row.length !== this.columnsInternal.length) {
throw new Error(
`Row length (${row.length}) must match column length (${this.columnsInternal.length})`,
`Row length (${row.length}) must match column length (${this.columnsInternal.length})`
);
}
@ -53,10 +53,12 @@ export class MarkdownTable {
* @returns A markdown-compatible table.
*/
toString() {
const headerRow = this.columnsInternal.join(' | ');
const dividerRow = this.columnsInternal.map(() => '---').join(' | ');
const headerRow = `| ${this.columnsInternal.join(' | ')} |`;
const dividerRow = `| ${this.columnsInternal
.map(() => '---')
.join(' | ')} |`;
const rows = this.rowsInternal
.map((row) => `${row.join(' | ')}`)
.map((row) => `| ${row.join(' | ')} |`)
.join('\n');
return `<!-- mdformat off(autogenerated might break rendering in catalog) -->

View File

@ -0,0 +1,56 @@
/**
* @license
* Copyright 2023 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* A map of components and their custom element TypeScript entrypoints.
*/
export const COMPONENT_CUSTOM_ELEMENTS = {
button: [
'button/elevated-button.ts',
'button/filled-button.ts',
'button/filled-tonal-button.ts',
'button/outlined-button.ts',
'button/text-button.ts',
],
checkbox: ['checkbox/checkbox.ts'],
chips: [
'chips/chip-set.ts',
'chips/assist-chip.ts',
'chips/filter-chip.ts',
'chips/input-chip.ts',
'chips/suggestion-chip.ts',
],
dialog: ['dialog/dialog.ts'],
divider: ['divider/divider.ts'],
elevation: ['elevation/elevation.ts'],
fab: ['fab/fab.ts', 'fab/branded-fab.ts'],
field: ['field/filled-field.ts', 'field/outlined-field.ts'],
focus: ['focus/md-focus-ring.ts'],
icon: ['icon/icon.ts'],
iconButton: [
'iconbutton/icon-button.ts',
'iconbutton/filled-icon-button.ts',
'iconbutton/filled-tonal-icon-button.ts',
'iconbutton/outlined-icon-button.ts',
],
list: ['list/list.ts', 'list/list-item.ts'],
menu: ['menu/menu.ts', 'menu/menu-item.ts', 'menu/sub-menu.ts'],
progress: ['progress/linear-progress.ts', 'progress/circular-progress.ts'],
radio: ['radio/radio.ts'],
ripple: ['ripple/ripple.ts'],
select: [
'select/filled-select.ts',
'select/outlined-select.ts',
'select/select-option.ts',
],
slider: ['slider/slider.ts'],
switch: ['switch/switch.ts'],
tabs: ['tabs/tabs.ts', 'tabs/primary-tab.ts', 'tabs/secondary-tab.ts'],
textField: [
'textfield/filled-text-field.ts',
'textfield/outlined-text-field.ts',
],
} as const;

View File

@ -0,0 +1,99 @@
/**
* @license
* Copyright 2023 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import multiEntry from '@rollup/plugin-multi-entry';
import nodeResolve from '@rollup/plugin-node-resolve';
import terser from '@rollup/plugin-terser';
import {rollup} from 'rollup';
import {promisify} from 'util';
import {gzip} from 'zlib';
const gzipPromise = promisify(gzip);
export interface Bundle {
name: string;
inputs: string[];
}
export interface BundleSize {
name: string;
size: Size;
inputs: InputSize[];
}
export interface InputSize {
input: string;
size: Size;
}
export interface Size {
raw: number;
css: number;
gzip: number;
}
export async function getBundleSize(bundle: Bundle): Promise<BundleSize> {
const bundleSize = await computeBundleSize(bundle.inputs);
let inputSizes: InputSize[];
if (bundle.inputs.length === 1) {
// If there's only one input, we don't need to re-generate the bundle.
inputSizes = [{input: bundle.inputs[0], size: bundleSize}];
} else {
// Include computed bundle size for individual inputs.
inputSizes = await Promise.all(
bundle.inputs.map(async (input) => {
return {
input,
size: await computeBundleSize(input),
};
}),
);
}
return {
name: bundle.name,
size: bundleSize,
inputs: inputSizes,
};
}
async function computeBundleSize(input: string | string[]): Promise<Size> {
const rollupBundle = await rollup({
input,
external: [/node_modules/],
plugins: [multiEntry(), nodeResolve(), terser()],
});
let code = '';
try {
const {output} = await rollupBundle.generate({});
code = output[0].code;
} finally {
rollupBundle.close();
}
const litCssTagNameMatch = code.match(/css\s*as\s*(\w+)/);
if (!litCssTagNameMatch) {
throw new Error("Cannot find `import { css as X } from 'lit'`");
}
const litCssTagName = litCssTagNameMatch[1];
const codeWithoutCss = code.replaceAll(
new RegExp(`${litCssTagName}\`([^\`]*)\``, 'g'),
'',
);
const encoder = new TextEncoder();
const codeSize = encoder.encode(code).length;
const codeSizeWithoutCss = encoder.encode(codeWithoutCss).length;
const cssSize = codeSize - codeSizeWithoutCss;
const gzipSize = (await gzipPromise(code)).length;
return {
raw: codeSize,
css: cssSize,
gzip: gzipSize,
};
}

118
scripts/size/update-size.ts Normal file
View File

@ -0,0 +1,118 @@
/**
* @license
* Copyright 2023 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import * as fs from 'fs/promises';
import { MarkdownTable } from '../analyzer/markdown-tree-builder.js';
import { COMPONENT_CUSTOM_ELEMENTS } from '../component-custom-elements.js';
import { Bundle, Size, getBundleSize } from './bundle-size.js';
// The bundles to track sizes for.
const bundles: Bundle[] = [
{
name: 'all',
inputs: ['all.js'],
},
{
name: 'common',
inputs: ['common.js'],
},
...(
Object.keys(COMPONENT_CUSTOM_ELEMENTS) as Array<
keyof typeof COMPONENT_CUSTOM_ELEMENTS
>
).map((component) => {
const tsCustomElementPaths = COMPONENT_CUSTOM_ELEMENTS[component];
const jsCustomElementPaths = tsCustomElementPaths.map((tsPath) =>
tsPath.replace(/\.ts$/, '.js')
);
return {
name: component,
inputs: jsCustomElementPaths,
};
}),
];
// Compute bundle sizes.
const bundleSizes = await Promise.all(
bundles.map((bundle) => getBundleSize(bundle))
);
// Create a markdown table with size data.
const columns = ['Component', 'gzip', 'minified', '*% CSS*', 'Import'];
const rows: string[][] = [];
for (const { name, size, inputs } of bundleSizes) {
rows.push([
`**${camelToSentenceCase(name)}**`,
`**${bytesToString(size.gzip)}**`,
bytesToString(size.raw),
getCssPercent(size),
inputs.length === 1 ? getImport(inputs[0].input) : '',
]);
if (inputs.length > 1) {
rows.push(
...inputs.map((input) => {
return [
'',
bytesToString(input.size.gzip),
bytesToString(input.size.raw),
getCssPercent(input.size),
getImport(input.input),
];
})
);
}
}
const markdownTable = new MarkdownTable(columns);
for (const row of rows) {
markdownTable.addRow(row);
}
// Update markdown file.
const markdownContent = await fs.readFile('docs/size.md', { encoding: 'utf8' });
const updateTrackingStart = '<!-- MWC_UPDATE_TRACKING_START -->';
const updateTrackingEnd = '<!-- MWC_UPDATE_TRACKING_END -->';
const now = new Date();
const nowString = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()}`;
const newMarkdownContent = [
markdownContent.substring(0, markdownContent.indexOf(updateTrackingStart)),
updateTrackingStart,
'\n\n',
`<sub>Last updated ${nowString}.</sub>\n\n`,
markdownTable.toString(),
'\n\n',
markdownContent.substring(markdownContent.indexOf(updateTrackingEnd)),
].join('');
await fs.writeFile('docs/size.md', newMarkdownContent);
// Text formatting functions for markdown table.
function getImport(input: string) {
return `\`@material/web/${input}\``;
}
function getCssPercent(size: Size) {
return `*${Math.round((size.css / size.raw) * 100)}% CSS*`;
}
function bytesToString(bytes: number) {
return `${(Math.round(bytes / 100) / 10).toFixed(1)}kb`;
}
function camelToSentenceCase(value: string) {
const withSpaces = value.replaceAll(/([a-z])([A-Z])/g, '$1 $2');
return withSpaces[0].toUpperCase() + withSpaces.slice(1).toLowerCase();
}