diff --git a/.github/workflows/size-limit.yml b/.github/workflows/size-limit.yml new file mode 100644 index 0000000000..c0ec536857 --- /dev/null +++ b/.github/workflows/size-limit.yml @@ -0,0 +1,37 @@ +name: Performance + +on: + pull_request: + paths: ['dist/**'] + + workflow_dispatch: + +jobs: + install: + name: Install + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Install dependencies + uses: ./.github/workflows/actions/install-node + + size: + name: Size Limit + runs-on: ubuntu-latest + needs: [install] + + strategy: + fail-fast: false + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Restore dependencies + uses: ./.github/workflows/actions/install-node + + - name: Run size-limit + run: npm run size diff --git a/package-lock.json b/package-lock.json index 64f07e68d5..3d77c67b46 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,6 +55,7 @@ "@percy/cli": "^1.16.0", "@percy/puppeteer": "^2.0.2", "@percy/sdk-utils": "^1.16.0", + "@size-limit/preset-big-lib": "^8.1.0", "babel-jest": "^29.3.1", "cheerio": "^1.0.0-rc.12", "eslint": "^8.29.0", @@ -76,6 +77,7 @@ "outdent": "^0.8.0", "puppeteer": "^19.3.0", "sass-color-helpers": "^2.1.1", + "size-limit": "^8.1.0", "standard": "^17.0.0", "stylelint": "^14.16.0", "stylelint-config-gds": "^0.2.0", @@ -3188,6 +3190,107 @@ "@sinonjs/commons": "^1.7.0" } }, + "node_modules/@sitespeed.io/tracium": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@sitespeed.io/tracium/-/tracium-0.3.3.tgz", + "integrity": "sha512-dNZafjM93Y+F+sfwTO5gTpsGXlnc/0Q+c2+62ViqP3gkMWvHEMSKkaEHgVJLcLg3i/g19GSIPziiKpgyne07Bw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@size-limit/file": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@size-limit/file/-/file-8.1.0.tgz", + "integrity": "sha512-Ur+NgJSRHBnbQBrD8X2doxXYdBcVJsMxe2KfWrUmnZ6wYz09YKhQ1iYLqNztjf2yf/JEp00zp1vyhmimUQfUHQ==", + "dev": true, + "dependencies": { + "semver": "7.3.7" + }, + "engines": { + "node": "^14.0.0 || ^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "size-limit": "8.1.0" + } + }, + "node_modules/@size-limit/file/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@size-limit/preset-big-lib": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@size-limit/preset-big-lib/-/preset-big-lib-8.1.0.tgz", + "integrity": "sha512-onkwmJt+gXzoRXOkcmvAX2mGyAoS6vXltqZsQHKpqYENJDghi5o4XuIZhYoEdsAYeP/vrM7u9jGGB7a0PGXR+Q==", + "dev": true, + "dependencies": { + "@size-limit/file": "8.1.0", + "@size-limit/time": "8.1.0", + "@size-limit/webpack": "8.1.0" + }, + "peerDependencies": { + "size-limit": "8.1.0" + } + }, + "node_modules/@size-limit/time": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@size-limit/time/-/time-8.1.0.tgz", + "integrity": "sha512-rOfIqpq8RSjKUnByJcWr2qw8XBTo3DAL16lmzjILvzQBkKi1kgDHU4QVa9K/BehYqH+Lx3rA3pVFMrQ5aJsOkg==", + "dev": true, + "dependencies": { + "estimo": "^2.3.6", + "react": "^17.0.2" + }, + "engines": { + "node": "^14.0.0 || ^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "size-limit": "8.1.0" + } + }, + "node_modules/@size-limit/webpack": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@size-limit/webpack/-/webpack-8.1.0.tgz", + "integrity": "sha512-TLego57hQbR0dmYZzIa9KZecebGMJoxZaqJTx9v3NDllxt6kJTljVXWghEvsGLpdKQfZTqraZ6nRm38+lG3sNw==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^4.0.0", + "nanoid": "^3.3.4", + "webpack": "^5.74.0" + }, + "engines": { + "node": "^14.0.0 || ^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "size-limit": "8.1.0" + } + }, + "node_modules/@size-limit/webpack/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@szmarczak/http-timer": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", @@ -5280,6 +5383,15 @@ "node": ">= 0.8" } }, + "node_modules/bytes-iec": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bytes-iec/-/bytes-iec-3.1.1.tgz", + "integrity": "sha512-fey6+4jDK7TFtFg/klGSvNKJctyU7n2aQdnM+CO0ruLPbqqMOM8Tio0Pc+deqUeVKX1tL5DQep1zQ7+37aTAsA==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/cacache": { "version": "15.3.0", "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", @@ -5727,6 +5839,12 @@ "integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==", "dev": true }, + "node_modules/ci-job-number": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ci-job-number/-/ci-job-number-1.2.2.tgz", + "integrity": "sha512-CLOGsVDrVamzv8sXJGaILUVI6dsuAkouJP/n6t+OxLPeeA4DDby7zn9SB6EUpa1H7oIKoE+rMmkW80zYsFfUjA==", + "dev": true + }, "node_modules/cjs-module-lexer": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", @@ -8829,6 +8947,84 @@ "node": ">=4.0" } }, + "node_modules/estimo": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/estimo/-/estimo-2.3.6.tgz", + "integrity": "sha512-aPd3VTQAL1TyDyhFfn6fqBTJ9WvbRZVN4Z29Buk6+P6xsI0DuF5Mh3dGv6kYCUxWnZkB4Jt3aYglUxOtuwtxoA==", + "dev": true, + "dependencies": { + "@sitespeed.io/tracium": "^0.3.3", + "commander": "^9.1.0", + "find-chrome-bin": "0.1.0", + "nanoid": "^3.3.2", + "puppeteer-core": "^13.5.1" + }, + "bin": { + "estimo": "scripts/cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/estimo/node_modules/commander": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", + "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", + "dev": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/estimo/node_modules/devtools-protocol": { + "version": "0.0.981744", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.981744.tgz", + "integrity": "sha512-0cuGS8+jhR67Fy7qG3i3Pc7Aw494sb9yG9QgpG97SFVWwolgYjlhJg7n+UaHxOQT30d1TYu/EYe9k01ivLErIg==", + "dev": true + }, + "node_modules/estimo/node_modules/puppeteer-core": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-13.7.0.tgz", + "integrity": "sha512-rXja4vcnAzFAP1OVLq/5dWNfwBGuzcOARJ6qGV7oAZhnLmVRU8G5MsdeQEAOy332ZhkIOnn9jp15R89LKHyp2Q==", + "dev": true, + "dependencies": { + "cross-fetch": "3.1.5", + "debug": "4.3.4", + "devtools-protocol": "0.0.981744", + "extract-zip": "2.0.1", + "https-proxy-agent": "5.0.1", + "pkg-dir": "4.2.0", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "rimraf": "3.0.2", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "ws": "8.5.0" + }, + "engines": { + "node": ">=10.18.1" + } + }, + "node_modules/estimo/node_modules/ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", @@ -9445,6 +9641,15 @@ "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, + "node_modules/find-chrome-bin": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/find-chrome-bin/-/find-chrome-bin-0.1.0.tgz", + "integrity": "sha512-XoFZwaEn1R3pE6zNG8kH64l2e093hgB9+78eEKPmJK0o1EXEou+25cEWdtu2qq4DBQPDSe90VJAWVI2Sz9pX6Q==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/find-file-up": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/find-file-up/-/find-file-up-0.1.3.tgz", @@ -17175,6 +17380,21 @@ "node": ">=0.10.0" } }, + "node_modules/nanospinner": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/nanospinner/-/nanospinner-1.1.0.tgz", + "integrity": "sha512-yFvNYMig4AthKYfHFl1sLj7B2nkHL4lzdig4osvl9/LdGbXwrdFRoqBS98gsEsOakr0yH+r5NZ/1Y9gdVB8trA==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0" + } + }, + "node_modules/nanospinner/node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -20582,6 +20802,19 @@ "node": ">=0.10.0" } }, + "node_modules/react": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", @@ -22156,6 +22389,34 @@ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "dev": true }, + "node_modules/size-limit": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/size-limit/-/size-limit-8.1.0.tgz", + "integrity": "sha512-bUL+Uyyt/G+a1XzKlI2WKHVDepmXtqMDhF65pdtjccheiQTNjExWW4nFefgbRL2QgNTzRfK6ayFKjO3o4ER4gg==", + "dev": true, + "dependencies": { + "bytes-iec": "^3.1.1", + "chokidar": "^3.5.3", + "ci-job-number": "^1.2.2", + "globby": "^11.1.0", + "lilconfig": "^2.0.6", + "mkdirp": "^1.0.4", + "nanospinner": "^1.1.0", + "picocolors": "^1.0.0" + }, + "bin": { + "size-limit": "bin.js" + }, + "engines": { + "node": "^14.0.0 || ^16.0.0 || >=18.0.0" + } + }, + "node_modules/size-limit/node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "node_modules/slash": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-5.0.0.tgz", diff --git a/package.json b/package.json index d17a2d5d5f..2a0c4ddf88 100644 --- a/package.json +++ b/package.json @@ -28,14 +28,15 @@ "postbuild:package": "jest --color --selectProjects \"Gulp tasks\" --testMatch \"**/*build-package*\"", "postbuild:dist": "jest --color --selectProjects \"Gulp tasks\" --testMatch \"**/*build-dist*\"", "pretest": "npm run build:compile", - "test": "jest --color --ignoreProjects \"Gulp tasks\" --maxWorkers=50%", + "test": "jest --color --ignoreProjects \"Gulp tasks\" --maxWorkers=50% && size-limit", "test:screenshots": "node ./tasks/screenshot-components.mjs", "lint": "npm run lint:js && npm run lint:scss", "lint:js": "npm run lint:js:cli -- \"**/*.{cjs,js,mjs}\"", "lint:js:cli": "eslint --cache --cache-location .cache/eslint --cache-strategy content --color --ignore-path .gitignore --max-warnings 0", "lint:scss": "npm run lint:scss:cli -- \"{app,src}/**/*.scss\"", "lint:scss:cli": "stylelint --cache --cache-location .cache/stylelint --cache-strategy content --color --ignore-path .gitignore --max-warnings 0", - "prepare": "node -e \"try { require('husky').install() } catch (e) {if (e.code !== 'MODULE_NOT_FOUND') throw e}\"" + "prepare": "node -e \"try { require('husky').install() } catch (e) {if (e.code !== 'MODULE_NOT_FOUND') throw e}\"", + "size": "npm run build:dist && size-limit" }, "dependencies": { "@babel/core": "^7.20.5", @@ -80,6 +81,7 @@ "@percy/cli": "^1.16.0", "@percy/puppeteer": "^2.0.2", "@percy/sdk-utils": "^1.16.0", + "@size-limit/preset-big-lib": "^8.1.0", "babel-jest": "^29.3.1", "cheerio": "^1.0.0-rc.12", "eslint": "^8.29.0", @@ -101,11 +103,18 @@ "outdent": "^0.8.0", "puppeteer": "^19.3.0", "sass-color-helpers": "^2.1.1", + "size-limit": "^8.1.0", "standard": "^17.0.0", "stylelint": "^14.16.0", "stylelint-config-gds": "^0.2.0", "stylelint-order": "^5.0.0", "vinyl": "^3.0.0", "wait-on": "^6.0.1" - } + }, + "size-limit": [ + { + "limit": "500ms", + "path": "dist/govuk-frontend-4.4.0.min.js" + } + ] }