Skip to content

Improve performance of hashRegExp lookup#16759

Merged
TheLarkInn merged 1 commit intowebpack:mainfrom
ryanwilsonperkin:real-content-hash-regex-perf
Mar 8, 2023
Merged

Improve performance of hashRegExp lookup#16759
TheLarkInn merged 1 commit intowebpack:mainfrom
ryanwilsonperkin:real-content-hash-regex-perf

Conversation

@ryanwilsonperkin
Copy link
Copy Markdown
Contributor

@ryanwilsonperkin ryanwilsonperkin commented Feb 24, 2023

Fixes #16758
For applications with a very large number of assets, the cost of invoking a single regular expression with many many values in a group becomes very high.

By changing to a list of regular expressions (with helper methods for maintaining the original design) we can get a large performance improvement.

A simple way to view the performance difference between these two approaches is with the following short scripts:

// benchmark-regex-group.js
const crypto = require('node:crypto');

function makeRandomString(length) {
  return crypto.randomBytes(length).toString('hex');
}

const name = makeRandomString(40);
const keys = Array.from(Array(3000), () => makeRandomString(20));
const regex = new RegExp(keys.join("|"), "g");

name.replace(regex, found => 'replaced');
const crypto = require('node:crypto');

function makeRandomString(length) {
  return crypto.randomBytes(length).toString('hex');
}

const name = makeRandomString(40);
const keys = Array.from(Array(3000), () => makeRandomString(20));
const regexes = keys.map(key => new RegExp(key, "g"));

let result = name;
for (const regex of regexes) {
  result = result.replace(regex, found => 'replaced');
}

Benchmarking these against each other I get the following results:

❯ hyperfine 'node benchmark-regex-many.js' 'node benchmark-regex-group.js'
Benchmark 1: node benchmark-regex-many.js
  Time (mean ± σ):      87.2 ms ± 143.6 ms    [User: 39.5 ms, System: 4.9 ms]
  Range (min … max):    39.3 ms … 495.8 ms    10 runs

Benchmark 2: node benchmark-regex-group.js
  Time (mean ± σ):     18.669 s ±  0.101 s    [User: 18.564 s, System: 0.054 s]
  Range (min … max):   18.556 s … 18.840 s    10 runs

Summary
  'node benchmark-regex-many.js' ran
  214.02 ± 352.29 times faster than 'node benchmark-regex-group.js'

What kind of change does this PR introduce?

Bugfix, performance

Did you add tests for your changes?

No, given that this is a performance improvement I'm not sure that the test suite is setup to test the difference.

Does this PR introduce a breaking change?

No, hashes remain the same

What needs to be documented once your changes are merged?
N/A

For applications with a very large number of assets, the cost of
invoking a single regular expression with many many values in a group
becomes very high.

By changing to a list of regular expressions (with helper methods for
maintaining the original design) we can get a large performance
improvement.
@webpack-bot
Copy link
Copy Markdown
Contributor

For maintainers only:

  • This needs to be documented (issue in webpack/webpack.js.org will be filed when merged)
  • This needs to be backported to webpack 4 (issue will be created when merged)

@ryanwilsonperkin
Copy link
Copy Markdown
Contributor Author

One thing that I was unsure of was whether or not a given asset could be expected to have multiple asset hashes in it's filename. To be defensive against that case, I've designed hashReplace and hashMatch to always iterate through the entire array of regular expressions, but if there's a known invariant that only one can match then we can speed this up even more by breaking on the first match/replacement.

Copy link
Copy Markdown

@devvsakib devvsakib left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@TheLarkInn
Copy link
Copy Markdown
Member

@alexander-akait when you are back and available will you look at this?

@TheLarkInn TheLarkInn enabled auto-merge March 8, 2023 15:44
@TheLarkInn
Copy link
Copy Markdown
Member

image Re-running failed jobs which look to be flakey and then auto-merge.

@ryanwilsonperkin
Copy link
Copy Markdown
Contributor Author

@TheLarkInn TheLarkInn disabled auto-merge March 8, 2023 17:16
@TheLarkInn TheLarkInn merged commit b84efe6 into webpack:main Mar 8, 2023
@ryanwilsonperkin ryanwilsonperkin deleted the real-content-hash-regex-perf branch March 8, 2023 17:22
kodiakhq bot referenced this pull request in weareinreach/InReach Mar 8, 2023
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@aws-sdk/client-cognito-identity-provider](https://togithub.com/aws/aws-sdk-js-v3/tree/main/clients/client-cognito-identity-provider) ([source](https://togithub.com/aws/aws-sdk-js-v3)) | [`3.282.0` -> `3.287.0`](https://renovatebot.com/diffs/npm/@aws-sdk%2fclient-cognito-identity-provider/3.282.0/3.287.0) | [![age](https://badges.renovateapi.com/packages/npm/@aws-sdk%2fclient-cognito-identity-provider/3.287.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/@aws-sdk%2fclient-cognito-identity-provider/3.287.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/@aws-sdk%2fclient-cognito-identity-provider/3.287.0/compatibility-slim/3.282.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/@aws-sdk%2fclient-cognito-identity-provider/3.287.0/confidence-slim/3.282.0)](https://docs.renovatebot.com/merge-confidence/) |
| [@aws-sdk/client-s3](https://togithub.com/aws/aws-sdk-js-v3/tree/main/clients/client-s3) ([source](https://togithub.com/aws/aws-sdk-js-v3)) | [`3.282.0` -> `3.287.0`](https://renovatebot.com/diffs/npm/@aws-sdk%2fclient-s3/3.282.0/3.287.0) | [![age](https://badges.renovateapi.com/packages/npm/@aws-sdk%2fclient-s3/3.287.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/@aws-sdk%2fclient-s3/3.287.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/@aws-sdk%2fclient-s3/3.287.0/compatibility-slim/3.282.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/@aws-sdk%2fclient-s3/3.287.0/confidence-slim/3.282.0)](https://docs.renovatebot.com/merge-confidence/) |
| [@storybook/addon-a11y](https://togithub.com/storybookjs/storybook/tree/main/addons/a11y) ([source](https://togithub.com/storybookjs/storybook)) | [`7.0.0-beta.62` -> `7.0.0-beta.63`](https://renovatebot.com/diffs/npm/@storybook%2faddon-a11y/7.0.0-beta.62/7.0.0-beta.63) | [![age](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-a11y/7.0.0-beta.63/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-a11y/7.0.0-beta.63/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-a11y/7.0.0-beta.63/compatibility-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-a11y/7.0.0-beta.63/confidence-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) |
| [@storybook/addon-actions](https://togithub.com/storybookjs/storybook/tree/main/addons/actions) ([source](https://togithub.com/storybookjs/storybook)) | [`7.0.0-beta.62` -> `7.0.0-beta.63`](https://renovatebot.com/diffs/npm/@storybook%2faddon-actions/7.0.0-beta.62/7.0.0-beta.63) | [![age](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-actions/7.0.0-beta.63/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-actions/7.0.0-beta.63/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-actions/7.0.0-beta.63/compatibility-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-actions/7.0.0-beta.63/confidence-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) |
| [@storybook/addon-docs](https://togithub.com/storybookjs/storybook/tree/main/addons/docs) ([source](https://togithub.com/storybookjs/storybook)) | [`7.0.0-beta.62` -> `7.0.0-beta.63`](https://renovatebot.com/diffs/npm/@storybook%2faddon-docs/7.0.0-beta.62/7.0.0-beta.63) | [![age](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-docs/7.0.0-beta.63/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-docs/7.0.0-beta.63/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-docs/7.0.0-beta.63/compatibility-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-docs/7.0.0-beta.63/confidence-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) |
| [@storybook/addon-essentials](https://togithub.com/storybookjs/storybook/tree/main/addons/essentials) ([source](https://togithub.com/storybookjs/storybook)) | [`7.0.0-beta.62` -> `7.0.0-beta.63`](https://renovatebot.com/diffs/npm/@storybook%2faddon-essentials/7.0.0-beta.62/7.0.0-beta.63) | [![age](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-essentials/7.0.0-beta.63/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-essentials/7.0.0-beta.63/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-essentials/7.0.0-beta.63/compatibility-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-essentials/7.0.0-beta.63/confidence-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) |
| [@storybook/addon-interactions](https://togithub.com/storybookjs/storybook/tree/main/addons/interactions) ([source](https://togithub.com/storybookjs/storybook)) | [`7.0.0-beta.62` -> `7.0.0-beta.63`](https://renovatebot.com/diffs/npm/@storybook%2faddon-interactions/7.0.0-beta.62/7.0.0-beta.63) | [![age](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-interactions/7.0.0-beta.63/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-interactions/7.0.0-beta.63/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-interactions/7.0.0-beta.63/compatibility-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-interactions/7.0.0-beta.63/confidence-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) |
| [@storybook/addon-links](https://togithub.com/storybookjs/storybook/tree/main/addons/links) ([source](https://togithub.com/storybookjs/storybook)) | [`7.0.0-beta.62` -> `7.0.0-beta.63`](https://renovatebot.com/diffs/npm/@storybook%2faddon-links/7.0.0-beta.62/7.0.0-beta.63) | [![age](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-links/7.0.0-beta.63/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-links/7.0.0-beta.63/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-links/7.0.0-beta.63/compatibility-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-links/7.0.0-beta.63/confidence-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) |
| [@storybook/addon-viewport](https://togithub.com/storybookjs/storybook/tree/main/addons/viewport) ([source](https://togithub.com/storybookjs/storybook)) | [`7.0.0-beta.62` -> `7.0.0-beta.63`](https://renovatebot.com/diffs/npm/@storybook%2faddon-viewport/7.0.0-beta.62/7.0.0-beta.63) | [![age](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-viewport/7.0.0-beta.63/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-viewport/7.0.0-beta.63/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-viewport/7.0.0-beta.63/compatibility-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/@storybook%2faddon-viewport/7.0.0-beta.63/confidence-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) |
| [@storybook/nextjs](https://togithub.com/storybookjs/storybook/tree/next/code/frameworks/nextjs) ([source](https://togithub.com/storybookjs/storybook)) | [`7.0.0-beta.62` -> `7.0.0-beta.63`](https://renovatebot.com/diffs/npm/@storybook%2fnextjs/7.0.0-beta.62/7.0.0-beta.63) | [![age](https://badges.renovateapi.com/packages/npm/@storybook%2fnextjs/7.0.0-beta.63/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/@storybook%2fnextjs/7.0.0-beta.63/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/@storybook%2fnextjs/7.0.0-beta.63/compatibility-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/@storybook%2fnextjs/7.0.0-beta.63/confidence-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) |
| [@storybook/react](https://togithub.com/storybookjs/storybook/tree/main/app/react) ([source](https://togithub.com/storybookjs/storybook)) | [`7.0.0-beta.62` -> `7.0.0-beta.63`](https://renovatebot.com/diffs/npm/@storybook%2freact/7.0.0-beta.62/7.0.0-beta.63) | [![age](https://badges.renovateapi.com/packages/npm/@storybook%2freact/7.0.0-beta.63/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/@storybook%2freact/7.0.0-beta.63/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/@storybook%2freact/7.0.0-beta.63/compatibility-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/@storybook%2freact/7.0.0-beta.63/confidence-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) |
| [@storybook/theming](https://togithub.com/storybookjs/storybook/tree/main/lib/theming) ([source](https://togithub.com/storybookjs/storybook)) | [`7.0.0-beta.62` -> `7.0.0-beta.63`](https://renovatebot.com/diffs/npm/@storybook%2ftheming/7.0.0-beta.62/7.0.0-beta.63) | [![age](https://badges.renovateapi.com/packages/npm/@storybook%2ftheming/7.0.0-beta.63/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/@storybook%2ftheming/7.0.0-beta.63/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/@storybook%2ftheming/7.0.0-beta.63/compatibility-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/@storybook%2ftheming/7.0.0-beta.63/confidence-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) |
| [@storybook/types](https://togithub.com/storybookjs/storybook/tree/main/code/lib/types) ([source](https://togithub.com/storybookjs/storybook)) | [`7.0.0-beta.62` -> `7.0.0-beta.63`](https://renovatebot.com/diffs/npm/@storybook%2ftypes/7.0.0-beta.62/7.0.0-beta.63) | [![age](https://badges.renovateapi.com/packages/npm/@storybook%2ftypes/7.0.0-beta.63/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/@storybook%2ftypes/7.0.0-beta.63/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/@storybook%2ftypes/7.0.0-beta.63/compatibility-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/@storybook%2ftypes/7.0.0-beta.63/confidence-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) |
| [@total-typescript/ts-reset](https://togithub.com/total-typescript/ts-reset) | [`0.3.7` -> `0.4.2`](https://renovatebot.com/diffs/npm/@total-typescript%2fts-reset/0.3.7/0.4.2) | [![age](https://badges.renovateapi.com/packages/npm/@total-typescript%2fts-reset/0.4.2/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/@total-typescript%2fts-reset/0.4.2/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/@total-typescript%2fts-reset/0.4.2/compatibility-slim/0.3.7)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/@total-typescript%2fts-reset/0.4.2/confidence-slim/0.3.7)](https://docs.renovatebot.com/merge-confidence/) |
| [embla-carousel-react](https://www.embla-carousel.com) ([source](https://togithub.com/davidjerleke/embla-carousel)) | [`7.0.9` -> `7.1.0`](https://renovatebot.com/diffs/npm/embla-carousel-react/7.0.9/7.1.0) | [![age](https://badges.renovateapi.com/packages/npm/embla-carousel-react/7.1.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/embla-carousel-react/7.1.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/embla-carousel-react/7.1.0/compatibility-slim/7.0.9)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/embla-carousel-react/7.1.0/confidence-slim/7.0.9)](https://docs.renovatebot.com/merge-confidence/) |
| [msw-storybook-addon](https://msw-sb.vercel.app/) ([source](https://togithub.com/mswjs/msw-storybook-addon)) | [`1.7.0` -> `1.8.0`](https://renovatebot.com/diffs/npm/msw-storybook-addon/1.7.0/1.8.0) | [![age](https://badges.renovateapi.com/packages/npm/msw-storybook-addon/1.8.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/msw-storybook-addon/1.8.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/msw-storybook-addon/1.8.0/compatibility-slim/1.7.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/msw-storybook-addon/1.8.0/confidence-slim/1.7.0)](https://docs.renovatebot.com/merge-confidence/) |
| [next-i18next](https://togithub.com/i18next/next-i18next) | [`13.2.1` -> `13.2.2`](https://renovatebot.com/diffs/npm/next-i18next/13.2.1/13.2.2) | [![age](https://badges.renovateapi.com/packages/npm/next-i18next/13.2.2/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/next-i18next/13.2.2/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/next-i18next/13.2.2/compatibility-slim/13.2.1)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/next-i18next/13.2.2/confidence-slim/13.2.1)](https://docs.renovatebot.com/merge-confidence/) |
| [storybook](https://togithub.com/storybookjs/storybook/tree/main/lib/cli) ([source](https://togithub.com/storybookjs/storybook)) | [`7.0.0-beta.62` -> `7.0.0-beta.63`](https://renovatebot.com/diffs/npm/storybook/7.0.0-beta.62/7.0.0-beta.63) | [![age](https://badges.renovateapi.com/packages/npm/storybook/7.0.0-beta.63/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/storybook/7.0.0-beta.63/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/storybook/7.0.0-beta.63/compatibility-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/storybook/7.0.0-beta.63/confidence-slim/7.0.0-beta.62)](https://docs.renovatebot.com/merge-confidence/) |
| [webpack](https://togithub.com/webpack/webpack) | [`5.75.0` -> `5.76.0`](https://renovatebot.com/diffs/npm/webpack/5.75.0/5.76.0) | [![age](https://badges.renovateapi.com/packages/npm/webpack/5.76.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/webpack/5.76.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/webpack/5.76.0/compatibility-slim/5.75.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/webpack/5.76.0/confidence-slim/5.75.0)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>aws/aws-sdk-js-v3 (@&#8203;aws-sdk/client-cognito-identity-provider)</summary>

### [`v3.287.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-cognito-identity-provider/CHANGELOG.md#&#8203;32870-httpsgithubcomawsaws-sdk-js-v3comparev32860v32870-2023-03-08)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.282.0...v3.287.0)

##### Bug Fixes

-   **clients:** remove aggregated client from paginators ([#&#8203;4496](https://togithub.com/aws/aws-sdk-js-v3/issues/4496)) ([aea457a](https://togithub.com/aws/aws-sdk-js-v3/commit/aea457ab5d4e72939f2f608140d82b60526eb716))

</details>

<details>
<summary>aws/aws-sdk-js-v3 (@&#8203;aws-sdk/client-s3)</summary>

### [`v3.287.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#&#8203;32870-httpsgithubcomawsaws-sdk-js-v3comparev32860v32870-2023-03-08)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.282.0...v3.287.0)

##### Bug Fixes

-   **clients:** remove aggregated client from paginators ([#&#8203;4496](https://togithub.com/aws/aws-sdk-js-v3/issues/4496)) ([aea457a](https://togithub.com/aws/aws-sdk-js-v3/commit/aea457ab5d4e72939f2f608140d82b60526eb716))

</details>

<details>
<summary>storybookjs/storybook</summary>

### [`v7.0.0-beta.63`](https://togithub.com/storybookjs/storybook/blob/HEAD/CHANGELOG.md#&#8203;700-beta63-March-9-2023)

[Compare Source](https://togithub.com/storybookjs/storybook/compare/v7.0.0-beta.62...v7.0.0-beta.63)

##### Bug Fixes

-   Story Index: Fix storySort parsing for parameters variable [#&#8203;21481](https://togithub.com/storybooks/storybook/pull/21481)
-   React/Vite: Add some missing types [#&#8203;21449](https://togithub.com/storybooks/storybook/pull/21449)
-   Docs: Cleanup with Promise instead of setTimeout [#&#8203;21476](https://togithub.com/storybooks/storybook/pull/21476)
-   Docs: Re-render MDX files when you fix a thrown error [#&#8203;21454](https://togithub.com/storybooks/storybook/pull/21454)
-   CLI: Fix mdx-to-csf codemod blocks imports [#&#8203;21448](https://togithub.com/storybooks/storybook/pull/21448)

##### Maintenance

-   CLI: Copy tweaks for automigrations [#&#8203;21475](https://togithub.com/storybooks/storybook/pull/21475)
-   CLI: Warn the user when stories glob does not match any file [#&#8203;21392](https://togithub.com/storybooks/storybook/pull/21392)
-   Docs: Use `Of` type in `useOf` argument [#&#8203;21442](https://togithub.com/storybooks/storybook/pull/21442)
-   Telemetry: Is interactive shell [#&#8203;21436](https://togithub.com/storybooks/storybook/pull/21436)

</details>

<details>
<summary>total-typescript/ts-reset</summary>

### [`v0.4.2`](https://togithub.com/total-typescript/ts-reset/releases/tag/v0.4.2)

#### 0.4.2

##### Minor Changes

-   [`ce9db42`](https://togithub.com/total-typescript/ts-reset/commit/ce9db42): Added support for widening in `Array.lastIndexOf`, `Array.indexOf`, `ReadonlyArray.lastIndexOf` and `ReadonlyArray.indexOf`.

-   [`107dfc2`](https://togithub.com/total-typescript/ts-reset/commit/107dfc2): Changed the array.includes on readonly arrays to NOT be a type predicate. Before this change, this perfectly valid code would not behave correctly.

    ```ts
    type Code = 0 | 1 | 2;
    type SpecificCode = 0 | 1;

    const currentCode: Code = 0;

    // Create an empty list of subset type
    const specificCodeList: ReadonlyArray<SpecificCode> = [];

    // This will be false, since 0 is not in []
    if (specificCodeList.includes(currentCode)) {
      currentCode; // -> SpecificCode
    } else {
      // This branch will be entered, and ts will think z is 2, when it is actually 0
      currentCode; // -> 2
    }
    ```

    Removing the type predicate brings ts-reset closer towards correctness.

-   [`4765413`](https://togithub.com/total-typescript/ts-reset/commit/4765413): author: [@&#8203;mefechoel](https://togithub.com/mefechoel)

    Added the `Map.has` rule.

    Similar to `.includes` or `Set.has()`, `Map.has()` doesn't let you pass members that don't exist in the map's keys:

    ```ts
    // BEFORE
    const userMap = new Map([
      ["matt", 0],
      ["sofia", 1],
      [2, "waqas"],
    ] as const);

    // Argument of type '"bryan"' is not assignable to
    // parameter of type '"matt" | "sofia" | "waqas"'.
    userMap.has("bryan");
    ```

    With the rule enabled, `Map` follows the same semantics as `Set`.

    ```ts
    // AFTER
    import "@&#8203;total-typescript/ts-reset/map-has";

    const userMap = new Map([
      ["matt", 0],
      ["sofia", 1],
      [2, "waqas"],
    ] as const);

    // .has now takes a string as the argument!
    userMap.has("bryan");
    ```

##### Patch Changes

-   [`b15aaa4`](https://togithub.com/total-typescript/ts-reset/commit/b15aaa4): Fixed an oversight with the initial `set-has` implementation by adding support to `ReadonlySet`.

### [`v0.4.1`](https://togithub.com/total-typescript/ts-reset/blob/HEAD/CHANGELOG.md#&#8203;041)

##### Patch Changes

-   No changes, just pushing to fix the previous slightly borked release.

### [`v0.4.0`](https://togithub.com/total-typescript/ts-reset/blob/HEAD/CHANGELOG.md#&#8203;040)

##### Minor Changes

-   [`ce9db42`](https://togithub.com/total-typescript/ts-reset/commit/ce9db42): Added support for widening in `Array.lastIndexOf`, `Array.indexOf`, `ReadonlyArray.lastIndexOf` and `ReadonlyArray.indexOf`.

-   [`107dfc2`](https://togithub.com/total-typescript/ts-reset/commit/107dfc2): Changed the array.includes on readonly arrays to NOT be a type predicate. Before this change, this perfectly valid code would not behave correctly.

    ```ts
    type Code = 0 | 1 | 2;
    type SpecificCode = 0 | 1;

    const currentCode: Code = 0;

    // Create an empty list of subset type
    const specificCodeList: ReadonlyArray<SpecificCode> = [];

    // This will be false, since 0 is not in []
    if (specificCodeList.includes(currentCode)) {
      currentCode; // -> SpecificCode
    } else {
      // This branch will be entered, and ts will think z is 2, when it is actually 0
      currentCode; // -> 2
    }
    ```

    Removing the type predicate brings ts-reset closer towards correctness.

-   [`4765413`](https://togithub.com/total-typescript/ts-reset/commit/4765413): author: [@&#8203;mefechoel](https://togithub.com/mefechoel)

    Added the `Map.has` rule.

    Similar to `.includes` or `Set.has()`, `Map.has()` doesn't let you pass members that don't exist in the map's keys:

    ```ts
    // BEFORE
    const userMap = new Map([
      ["matt", 0],
      ["sofia", 1],
      [2, "waqas"],
    ] as const);

    // Argument of type '"bryan"' is not assignable to
    // parameter of type '"matt" | "sofia" | "waqas"'.
    userMap.has("bryan");
    ```

    With the rule enabled, `Map` follows the same semantics as `Set`.

    ```ts
    // AFTER
    import "@&#8203;total-typescript/ts-reset/map-has";

    const userMap = new Map([
      ["matt", 0],
      ["sofia", 1],
      [2, "waqas"],
    ] as const);

    // .has now takes a string as the argument!
    userMap.has("bryan");
    ```

##### Patch Changes

-   [`b15aaa4`](https://togithub.com/total-typescript/ts-reset/commit/b15aaa4): Fixed an oversight with the initial `set-has` implementation by adding support to `ReadonlySet`.

</details>

<details>
<summary>davidjerleke/embla-carousel</summary>

### [`v7.1.0`](https://togithub.com/davidjerleke/embla-carousel/releases/tag/v7.1.0)

[Compare Source](https://togithub.com/davidjerleke/embla-carousel/compare/v7.0.9...v7.1.0)

### 🌟 New features:

-   \[x] [#&#8203;440](https://togithub.com/davidjerleke/embla-carousel/issues/440) - Add [`slides`](https://www.embla-carousel.com/api/options/#slides) & [`container`](https://www.embla-carousel.com/api/options/#container) options.

##### Donations

Embla Carousel is an open source MIT licensed project. If you are interested in supporting this project, please consider:

-   [One-off donation via PayPal](https://www.paypal.com/paypalme/davidjerleke)
-   [One-off/monthly donations via Ko-fi](https://ko-fi.com/davidjerleke)

***

#### What's Changed

-   Migrate to the latest Gatsby version by [@&#8203;davidjerleke](https://togithub.com/davidjerleke) in [https://github.com/davidjerleke/embla-carousel/pull/428](https://togithub.com/davidjerleke/embla-carousel/pull/428)
-   Docs improvements by [@&#8203;davidjerleke](https://togithub.com/davidjerleke) in [https://github.com/davidjerleke/embla-carousel/pull/439](https://togithub.com/davidjerleke/embla-carousel/pull/439)
-   Add `slides` & `container` options by [@&#8203;davidjerleke](https://togithub.com/davidjerleke) in [https://github.com/davidjerleke/embla-carousel/pull/441](https://togithub.com/davidjerleke/embla-carousel/pull/441)

**Full Changelog**: davidjerleke/embla-carousel@v7.0.9...v7.1.0

</details>

<details>
<summary>mswjs/msw-storybook-addon</summary>

### [`v1.8.0`](https://togithub.com/mswjs/msw-storybook-addon/blob/HEAD/packages/msw-addon/CHANGELOG.md#v180-Wed-Mar-08-2023)

[Compare Source](https://togithub.com/mswjs/msw-storybook-addon/compare/v1.7.0...v1.8.0)

##### 🚀 Enhancement

-   support Storybook 7 [#&#8203;102](https://togithub.com/mswjs/msw-storybook-addon/pull/102) ([@&#8203;yannbf](https://togithub.com/yannbf))

##### 🐛 Bug Fix

-   Fetch git tags on release workflow [#&#8203;103](https://togithub.com/mswjs/msw-storybook-addon/pull/103) ([@&#8203;yannbf](https://togithub.com/yannbf))
-   Use auto for release management [#&#8203;100](https://togithub.com/mswjs/msw-storybook-addon/pull/100) ([@&#8203;yannbf](https://togithub.com/yannbf))
-   fix: update peer dependency range [#&#8203;94](https://togithub.com/mswjs/msw-storybook-addon/pull/94) ([@&#8203;rajtslegr](https://togithub.com/rajtslegr))

##### Authors: 2

-   Petr Rajtslegr ([@&#8203;rajtslegr](https://togithub.com/rajtslegr))
-   Yann Braga ([@&#8203;yannbf](https://togithub.com/yannbf))

</details>

<details>
<summary>i18next/next-i18next</summary>

### [`v13.2.2`](https://togithub.com/i18next/next-i18next/blob/HEAD/CHANGELOG.md#&#8203;1322)

[Compare Source](https://togithub.com/i18next/next-i18next/compare/v13.2.1...v13.2.2)

-   pageProps may be undefined on strange setups [#&#8203;2109](https://togithub.com/i18next/next-i18next/issues/2109)"

</details>

<details>
<summary>webpack/webpack</summary>

### [`v5.76.0`](https://togithub.com/webpack/webpack/releases/tag/v5.76.0)

[Compare Source](https://togithub.com/webpack/webpack/compare/v5.75.0...v5.76.0)

#### Bugfixes

-   Avoid cross-realm object access by [@&#8203;Jack-Works](https://togithub.com/Jack-Works) in [https://github.com/webpack/webpack/pull/16500](https://togithub.com/webpack/webpack/pull/16500)
-   Improve hash performance via conditional initialization by [@&#8203;lvivski](https://togithub.com/lvivski) in [https://github.com/webpack/webpack/pull/16491](https://togithub.com/webpack/webpack/pull/16491)
-   Serialize `generatedCode` info to fix bug in asset module cache restoration by [@&#8203;ryanwilsonperkin](https://togithub.com/ryanwilsonperkin) in [https://github.com/webpack/webpack/pull/16703](https://togithub.com/webpack/webpack/pull/16703)
-   Improve performance of `hashRegExp` lookup by [@&#8203;ryanwilsonperkin](https://togithub.com/ryanwilsonperkin) in [https://github.com/webpack/webpack/pull/16759](https://togithub.com/webpack/webpack/pull/16759)

#### Features

-   add `target` to `LoaderContext` type by [@&#8203;askoufis](https://togithub.com/askoufis) in [https://github.com/webpack/webpack/pull/16781](https://togithub.com/webpack/webpack/pull/16781)

#### Security

-   [CVE-2022-37603](https://togithub.com/advisories/GHSA-3rfm-jhwj-7488) fixed by [@&#8203;akhilgkrishnan](https://togithub.com/akhilgkrishnan) in [https://github.com/webpack/webpack/pull/16446](https://togithub.com/webpack/webpack/pull/16446)

#### Repo Changes

-   Fix HTML5 logo in README by [@&#8203;jakebailey](https://togithub.com/jakebailey) in [https://github.com/webpack/webpack/pull/16614](https://togithub.com/webpack/webpack/pull/16614)
-   Replace TypeScript logo in README by [@&#8203;jakebailey](https://togithub.com/jakebailey) in [https://github.com/webpack/webpack/pull/16613](https://togithub.com/webpack/webpack/pull/16613)
-   Update actions/cache dependencies by [@&#8203;piwysocki](https://togithub.com/piwysocki) in [https://github.com/webpack/webpack/pull/16493](https://togithub.com/webpack/webpack/pull/16493)

#### New Contributors

-   [@&#8203;Jack-Works](https://togithub.com/Jack-Works) made their first contribution in [https://github.com/webpack/webpack/pull/16500](https://togithub.com/webpack/webpack/pull/16500)
-   [@&#8203;lvivski](https://togithub.com/lvivski) made their first contribution in [https://github.com/webpack/webpack/pull/16491](https://togithub.com/webpack/webpack/pull/16491)
-   [@&#8203;jakebailey](https://togithub.com/jakebailey) made their first contribution in [https://github.com/webpack/webpack/pull/16614](https://togithub.com/webpack/webpack/pull/16614)
-   [@&#8203;akhilgkrishnan](https://togithub.com/akhilgkrishnan) made their first contribution in [https://github.com/webpack/webpack/pull/16446](https://togithub.com/webpack/webpack/pull/16446)
-   [@&#8203;ryanwilsonperkin](https://togithub.com/ryanwilsonperkin) made their first contribution in [https://github.com/webpack/webpack/pull/16703](https://togithub.com/webpack/webpack/pull/16703)
-   [@&#8203;piwysocki](https://togithub.com/piwysocki) made their first contribution in [https://github.com/webpack/webpack/pull/16493](https://togithub.com/webpack/webpack/pull/16493)
-   [@&#8203;askoufis](https://togithub.com/askoufis) made their first contribution in [https://github.com/webpack/webpack/pull/16781](https://togithub.com/webpack/webpack/pull/16781)

**Full Changelog**: webpack/webpack@v5.75.0...v5.76.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://togithub.com/renovatebot/renovate/discussions) if that's undesired.

---

 - [ ] If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://app.renovatebot.com/dashboard#github/weareinreach/InReach).



PR-URL: #278
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
@lvivski
Copy link
Copy Markdown
Contributor

lvivski commented Mar 10, 2023

@ryanwilsonperkin thanks for this PR! I was thinking of a similar change, while working on #16491, and was very excited to see you making it :)
Unfortunately, at least for our scenario (~2M LOC, 10k hashes to replace per runtime, 5+ runtimes, 5000 output js files) this change has degraded performance quite a bit. Previously our builds would spend around 600 seconds in RealContentHash, and 90s after #16491, now they timeout.

Even generating multiple RegExp's is slower than having a single huge one for us. Do you see the same improvements, you've mentioned in PR, after upgrading to the latest version? I'm trying to understand why it would be faster for your scenario, which sounds relatively similar to ours in terms of size and complexity, but much slower for us.

@ryanwilsonperkin
Copy link
Copy Markdown
Contributor Author

Hey @lvivski thanks for bringing it to my attention. Could you include some information about the format of the hashes that you're replacing and the number and size of assets that you're replacing them in? And are you able to isolate the timeout to this part of the code?

@lvivski
Copy link
Copy Markdown
Contributor

lvivski commented Mar 10, 2023

@ryanwilsonperkin

Could you include some information about the format of the hashes

we're using xxxhash64 8 chars.

the number and size of assets that you're replacing them in

~5 runtime assets
~10k hashes to replace. 5k from content hash and 5k through the hook with webpack-subresource-integrity. I've also tried disabling SRI and it didn't help.

And are you able to isolate the timeout to this part of the code?

Yes, after creating a custom webpack build with this change reverted, it works fine.

I have just ran your stress-test build from https://github.com/ryanwilsonperkin/webpack-16758

CPU: 2.4 GHz 8-Core Intel Core i9
RAM: 64 GB 2667 MHz DDR4
OS: Mac OS 13.2.1
NodeJS: v19.7.0

v5.76.0

Run 1: 50487 ms asset processing > RealContentHashPlugin
Run 2: 51002 ms asset processing > RealContentHashPlugin
Run 3: 51650 ms asset processing > RealContentHashPlugin

v5.76.0 w/ changes from this PR reverted

Run 1: 9812 ms asset processing > RealContentHashPlugin
Run 2: 10482 ms asset processing > RealContentHashPlugin
Run 3: 10761 ms asset processing > RealContentHashPlugin

Around 5x decrease in processing time if I revert this change.

@renovate renovate bot mentioned this pull request Jun 6, 2023
1 task
This was referenced Jun 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

No open projects
Status: Shipped

Development

Successfully merging this pull request may close these issues.

Performance issue in RealContentHashPlugin on large builds with many assets

8 participants