]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
ci: add continuous reactivity benchmark (#9638)
author三咲智子 Kevin Deng <sxzz@sxzz.moe>
Fri, 8 Dec 2023 13:26:48 +0000 (21:26 +0800)
committerGitHub <noreply@github.com>
Fri, 8 Dec 2023 13:26:48 +0000 (21:26 +0800)
.github/workflows/ci.yml
package.json
packages/reactivity/__tests__/computed.bench.ts [new file with mode: 0644]
packages/reactivity/__tests__/reactiveArray.bench.ts [new file with mode: 0644]
packages/reactivity/__tests__/reactiveMap.bench.ts [new file with mode: 0644]
packages/reactivity/__tests__/reactiveObject.bench.ts [new file with mode: 0644]
packages/reactivity/__tests__/ref.bench.ts [new file with mode: 0644]
packages/runtime-core/__tests__/apiWatch.bench.ts [new file with mode: 0644]
pnpm-lock.yaml
vitest.config.ts

index 493ab295000c6d12fb916149008e7fec46514331..f70f98a3821e8aabd81455467efd1ee393817357 100644 (file)
@@ -58,6 +58,31 @@ jobs:
       - name: Run ssr unit tests
         run: pnpm run test-unit server-renderer
 
+  benchmarks:
+    runs-on: ubuntu-latest
+    if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
+    env:
+      PUPPETEER_SKIP_DOWNLOAD: 'true'
+    steps:
+      - uses: actions/checkout@v4
+
+      - name: Install pnpm
+        uses: pnpm/action-setup@v2
+
+      - name: Install Node.js
+        uses: actions/setup-node@v4
+        with:
+          node-version-file: '.node-version'
+          cache: 'pnpm'
+
+      - run: pnpm install
+
+      - name: Run benchmarks
+        uses: CodSpeedHQ/action@v1
+        with:
+          run: pnpm vitest bench --run
+          token: ${{ secrets.CODSPEED_TOKEN }}
+
   e2e-test:
     runs-on: ubuntu-latest
     if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
index 926f6e00b245d64443e75cc8abe4df67febbd5fa..ba2427c6916a6aeade4f1453024a17ea100a45b3 100644 (file)
@@ -22,6 +22,7 @@
     "test-dts": "run-s build-dts test-dts-only",
     "test-dts-only": "tsc -p ./packages/dts-test/tsconfig.test.json",
     "test-coverage": "vitest -c vitest.unit.config.ts --coverage",
+    "test-bench": "vitest bench",
     "release": "node scripts/release.js",
     "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
     "dev-esm": "node scripts/dev.js -if esm-bundler-runtime",
@@ -60,6 +61,7 @@
   "devDependencies": {
     "@babel/parser": "^7.23.5",
     "@babel/types": "^7.23.5",
+    "@codspeed/vitest-plugin": "^2.3.1",
     "@rollup/plugin-alias": "^5.0.1",
     "@rollup/plugin-commonjs": "^25.0.7",
     "@rollup/plugin-json": "^6.0.1",
@@ -69,7 +71,7 @@
     "@types/hash-sum": "^1.0.2",
     "@types/node": "^20.10.3",
     "@typescript-eslint/parser": "^6.13.0",
-    "@vitest/coverage-istanbul": "^0.34.6",
+    "@vitest/coverage-istanbul": "^1.0.2",
     "@vue/consolidate": "0.17.3",
     "conventional-changelog-cli": "^4.1.0",
     "enquirer": "^2.4.1",
diff --git a/packages/reactivity/__tests__/computed.bench.ts b/packages/reactivity/__tests__/computed.bench.ts
new file mode 100644 (file)
index 0000000..73c20ac
--- /dev/null
@@ -0,0 +1,126 @@
+import { describe, bench } from 'vitest'
+import { ComputedRef, Ref, computed, ref } from '../src/index'
+
+describe('computed', () => {
+  bench('create computed', () => {
+    computed(() => 100)
+  })
+
+  {
+    let i = 0
+    const o = ref(100)
+    bench('write independent ref dep', () => {
+      o.value = i++
+    })
+  }
+
+  {
+    const v = ref(100)
+    computed(() => v.value * 2)
+    let i = 0
+    bench("write ref, don't read computed (never invoked)", () => {
+      v.value = i++
+    })
+  }
+
+  {
+    const v = ref(100)
+    computed(() => {
+      return v.value * 2
+    })
+    let i = 0
+    bench("write ref, don't read computed (never invoked)", () => {
+      v.value = i++
+    })
+  }
+
+  {
+    const v = ref(100)
+    const c = computed(() => {
+      return v.value * 2
+    })
+    c.value
+    let i = 0
+    bench("write ref, don't read computed (invoked)", () => {
+      v.value = i++
+    })
+  }
+
+  {
+    const v = ref(100)
+    const c = computed(() => {
+      return v.value * 2
+    })
+    let i = 0
+    bench('write ref, read computed', () => {
+      v.value = i++
+      c.value
+    })
+  }
+
+  {
+    const v = ref(100)
+    const computeds = []
+    for (let i = 0, n = 1000; i < n; i++) {
+      const c = computed(() => {
+        return v.value * 2
+      })
+      computeds.push(c)
+    }
+    let i = 0
+    bench("write ref, don't read 1000 computeds (never invoked)", () => {
+      v.value = i++
+    })
+  }
+
+  {
+    const v = ref(100)
+    const computeds = []
+    for (let i = 0, n = 1000; i < n; i++) {
+      const c = computed(() => {
+        return v.value * 2
+      })
+      c.value
+      computeds.push(c)
+    }
+    let i = 0
+    bench("write ref, don't read 1000 computeds (invoked)", () => {
+      v.value = i++
+    })
+  }
+
+  {
+    const v = ref(100)
+    const computeds: ComputedRef<number>[] = []
+    for (let i = 0, n = 1000; i < n; i++) {
+      const c = computed(() => {
+        return v.value * 2
+      })
+      c.value
+      computeds.push(c)
+    }
+    let i = 0
+    bench('write ref, read 1000 computeds', () => {
+      v.value = i++
+      computeds.forEach(c => c.value)
+    })
+  }
+
+  {
+    const refs: Ref<number>[] = []
+    for (let i = 0, n = 1000; i < n; i++) {
+      refs.push(ref(i))
+    }
+    const c = computed(() => {
+      let total = 0
+      refs.forEach(ref => (total += ref.value))
+      return total
+    })
+    let i = 0
+    const n = refs.length
+    bench('1000 refs, 1 computed', () => {
+      refs[i++ % n].value++
+      c.value
+    })
+  }
+})
diff --git a/packages/reactivity/__tests__/reactiveArray.bench.ts b/packages/reactivity/__tests__/reactiveArray.bench.ts
new file mode 100644 (file)
index 0000000..596b9f1
--- /dev/null
@@ -0,0 +1,92 @@
+import { bench } from 'vitest'
+import { computed, reactive, readonly, shallowRef, triggerRef } from '../src'
+
+for (let amount = 1e1; amount < 1e4; amount *= 10) {
+  {
+    const rawArray = []
+    for (let i = 0, n = amount; i < n; i++) {
+      rawArray.push(i)
+    }
+    const r = reactive(rawArray)
+    const c = computed(() => {
+      return r.reduce((v, a) => a + v, 0)
+    })
+
+    bench(`reduce *reactive* array, ${amount} elements`, () => {
+      for (let i = 0, n = r.length; i < n; i++) {
+        r[i]++
+      }
+      c.value
+    })
+  }
+
+  {
+    const rawArray = []
+    for (let i = 0, n = amount; i < n; i++) {
+      rawArray.push(i)
+    }
+    const r = reactive(rawArray)
+    const c = computed(() => {
+      return r.reduce((v, a) => a + v, 0)
+    })
+
+    bench(
+      `reduce *reactive* array, ${amount} elements, only change first value`,
+      () => {
+        r[0]++
+        c.value
+      }
+    )
+  }
+
+  {
+    const rawArray = []
+    for (let i = 0, n = amount; i < n; i++) {
+      rawArray.push(i)
+    }
+    const r = reactive({ arr: readonly(rawArray) })
+    const c = computed(() => {
+      return r.arr.reduce((v, a) => a + v, 0)
+    })
+
+    bench(`reduce *readonly* array, ${amount} elements`, () => {
+      r.arr = r.arr.map(v => v + 1)
+      c.value
+    })
+  }
+
+  {
+    const rawArray = []
+    for (let i = 0, n = amount; i < n; i++) {
+      rawArray.push(i)
+    }
+    const r = shallowRef(rawArray)
+    const c = computed(() => {
+      return r.value.reduce((v, a) => a + v, 0)
+    })
+
+    bench(`reduce *raw* array, copied, ${amount} elements`, () => {
+      r.value = r.value.map(v => v + 1)
+      c.value
+    })
+  }
+
+  {
+    const rawArray: number[] = []
+    for (let i = 0, n = amount; i < n; i++) {
+      rawArray.push(i)
+    }
+    const r = shallowRef(rawArray)
+    const c = computed(() => {
+      return r.value.reduce((v, a) => a + v, 0)
+    })
+
+    bench(`reduce *raw* array, manually triggered, ${amount} elements`, () => {
+      for (let i = 0, n = rawArray.length; i < n; i++) {
+        rawArray[i]++
+      }
+      triggerRef(r)
+      c.value
+    })
+  }
+}
diff --git a/packages/reactivity/__tests__/reactiveMap.bench.ts b/packages/reactivity/__tests__/reactiveMap.bench.ts
new file mode 100644 (file)
index 0000000..579904b
--- /dev/null
@@ -0,0 +1,143 @@
+import { bench } from 'vitest'
+import { reactive, computed, ComputedRef } from '../src'
+
+function createMap(obj: Record<string, any>) {
+  const map = new Map()
+  for (const key in obj) {
+    if (obj.hasOwnProperty(key)) {
+      map.set(key, obj[key])
+    }
+  }
+  return map
+}
+
+bench('create reactive map', () => {
+  reactive(createMap({ a: 1 }))
+})
+
+{
+  let i = 0
+  const r = reactive(createMap({ a: 1 }))
+  bench('write reactive map property', () => {
+    r.set('a', i++)
+  })
+}
+
+{
+  const r = reactive(createMap({ a: 1 }))
+  computed(() => {
+    return r.get('a') * 2
+  })
+  let i = 0
+  bench("write reactive map, don't read computed (never invoked)", () => {
+    r.set('a', i++)
+  })
+}
+
+{
+  const r = reactive(createMap({ a: 1 }))
+  const c = computed(() => {
+    return r.get('a') * 2
+  })
+  c.value
+  let i = 0
+  bench("write reactive map, don't read computed (invoked)", () => {
+    r.set('a', i++)
+  })
+}
+
+{
+  const r = reactive(createMap({ a: 1 }))
+  const c = computed(() => {
+    return r.get('a') * 2
+  })
+  let i = 0
+  bench('write reactive map, read computed', () => {
+    r.set('a', i++)
+    c.value
+  })
+}
+
+{
+  const _m = new Map()
+  for (let i = 0; i < 10000; i++) {
+    _m.set(i, i)
+  }
+  const r = reactive(_m)
+  const c = computed(() => {
+    let total = 0
+    r.forEach((value, key) => {
+      total += value
+    })
+    return total
+  })
+  bench("write reactive map (10'000 items), read computed", () => {
+    r.set(5000, r.get(5000) + 1)
+    c.value
+  })
+}
+
+{
+  const r = reactive(createMap({ a: 1 }))
+  const computeds = []
+  for (let i = 0, n = 1000; i < n; i++) {
+    const c = computed(() => {
+      return r.get('a') * 2
+    })
+    computeds.push(c)
+  }
+  let i = 0
+  bench("write reactive map, don't read 1000 computeds (never invoked)", () => {
+    r.set('a', i++)
+  })
+}
+
+{
+  const r = reactive(createMap({ a: 1 }))
+  const computeds = []
+  for (let i = 0, n = 1000; i < n; i++) {
+    const c = computed(() => {
+      return r.get('a') * 2
+    })
+    c.value
+    computeds.push(c)
+  }
+  let i = 0
+  bench("write reactive map, don't read 1000 computeds (invoked)", () => {
+    r.set('a', i++)
+  })
+}
+
+{
+  const r = reactive(createMap({ a: 1 }))
+  const computeds: ComputedRef<number>[] = []
+  for (let i = 0, n = 1000; i < n; i++) {
+    const c = computed(() => {
+      return r.get('a') * 2
+    })
+    computeds.push(c)
+  }
+  let i = 0
+  bench('write reactive map, read 1000 computeds', () => {
+    r.set('a', i++)
+    computeds.forEach(c => c.value)
+  })
+}
+
+{
+  const reactives: Map<any, any>[] = []
+  for (let i = 0, n = 1000; i < n; i++) {
+    reactives.push(reactive(createMap({ a: i })))
+  }
+  const c = computed(() => {
+    let total = 0
+    reactives.forEach(r => (total += r.get('a')))
+    return total
+  })
+  let i = 0
+  const n = reactives.length
+  bench('1000 reactive maps, 1 computed', () => {
+    reactives[i++ % n].set('a', reactives[i++ % n].get('a') + 1)
+    c.value
+  })
+}
diff --git a/packages/reactivity/__tests__/reactiveObject.bench.ts b/packages/reactivity/__tests__/reactiveObject.bench.ts
new file mode 100644 (file)
index 0000000..43af8a9
--- /dev/null
@@ -0,0 +1,114 @@
+import { bench } from 'vitest'
+import { ComputedRef, computed, reactive } from '../src'
+
+bench('create reactive obj', () => {
+  reactive({ a: 1 })
+})
+
+{
+  let i = 0
+  const r = reactive({ a: 1 })
+  bench('write reactive obj property', () => {
+    r.a = i++
+  })
+}
+
+{
+  const r = reactive({ a: 1 })
+  computed(() => {
+    return r.a * 2
+  })
+  let i = 0
+  bench("write reactive obj, don't read computed (never invoked)", () => {
+    r.a = i++
+  })
+}
+
+{
+  const r = reactive({ a: 1 })
+  const c = computed(() => {
+    return r.a * 2
+  })
+  c.value
+  let i = 0
+  bench("write reactive obj, don't read computed (invoked)", () => {
+    r.a = i++
+  })
+}
+
+{
+  const r = reactive({ a: 1 })
+  const c = computed(() => {
+    return r.a * 2
+  })
+  let i = 0
+  bench('write reactive obj, read computed', () => {
+    r.a = i++
+    c.value
+  })
+}
+
+{
+  const r = reactive({ a: 1 })
+  const computeds = []
+  for (let i = 0, n = 1000; i < n; i++) {
+    const c = computed(() => {
+      return r.a * 2
+    })
+    computeds.push(c)
+  }
+  let i = 0
+  bench("write reactive obj, don't read 1000 computeds (never invoked)", () => {
+    r.a = i++
+  })
+}
+
+{
+  const r = reactive({ a: 1 })
+  const computeds = []
+  for (let i = 0, n = 1000; i < n; i++) {
+    const c = computed(() => {
+      return r.a * 2
+    })
+    c.value
+    computeds.push(c)
+  }
+  let i = 0
+  bench("write reactive obj, don't read 1000 computeds (invoked)", () => {
+    r.a = i++
+  })
+}
+
+{
+  const r = reactive({ a: 1 })
+  const computeds: ComputedRef<number>[] = []
+  for (let i = 0, n = 1000; i < n; i++) {
+    const c = computed(() => {
+      return r.a * 2
+    })
+    computeds.push(c)
+  }
+  let i = 0
+  bench('write reactive obj, read 1000 computeds', () => {
+    r.a = i++
+    computeds.forEach(c => c.value)
+  })
+}
+
+{
+  const reactives: Record<string, number>[] = []
+  for (let i = 0, n = 1000; i < n; i++) {
+    reactives.push(reactive({ a: i }))
+  }
+  const c = computed(() => {
+    let total = 0
+    reactives.forEach(r => (total += r.a))
+    return total
+  })
+  let i = 0
+  const n = reactives.length
+  bench('1000 reactive objs, 1 computed', () => {
+    reactives[i++ % n].a++
+    c.value
+  })
+}
diff --git a/packages/reactivity/__tests__/ref.bench.ts b/packages/reactivity/__tests__/ref.bench.ts
new file mode 100644 (file)
index 0000000..a1b625a
--- /dev/null
@@ -0,0 +1,33 @@
+import { describe, bench } from 'vitest'
+import { ref } from '../src/index'
+
+describe('ref', () => {
+  bench('create ref', () => {
+    ref(100)
+  })
+
+  {
+    let i = 0
+    const v = ref(100)
+    bench('write ref', () => {
+      v.value = i++
+    })
+  }
+
+  {
+    const v = ref(100)
+    bench('read ref', () => {
+      v.value
+    })
+  }
+
+  {
+    let i = 0
+    const v = ref(100)
+    bench('write/read ref', () => {
+      v.value = i++
+
+      v.value
+    })
+  }
+})
diff --git a/packages/runtime-core/__tests__/apiWatch.bench.ts b/packages/runtime-core/__tests__/apiWatch.bench.ts
new file mode 100644 (file)
index 0000000..89693a4
--- /dev/null
@@ -0,0 +1,58 @@
+import { nextTick, ref, watch, watchEffect } from '../src'
+import { bench } from 'vitest'
+
+bench('create watcher', () => {
+  const v = ref(100)
+  watch(v, v => {})
+})
+
+{
+  const v = ref(100)
+  watch(v, v => {})
+  let i = 0
+  bench('update ref to trigger watcher (scheduled but not executed)', () => {
+    v.value = i++
+  })
+}
+
+{
+  const v = ref(100)
+  watch(v, v => {})
+  let i = 0
+  bench('update ref to trigger watcher (executed)', async () => {
+    v.value = i++
+    return nextTick()
+  })
+}
+
+{
+  bench('create watchEffect', () => {
+    watchEffect(() => {})
+  })
+}
+
+{
+  const v = ref(100)
+  watchEffect(() => {
+    v.value
+  })
+  let i = 0
+  bench(
+    'update ref to trigger watchEffect (scheduled but not executed)',
+    () => {
+      v.value = i++
+    }
+  )
+}
+
+{
+  const v = ref(100)
+  watchEffect(() => {
+    v.value
+  })
+  let i = 0
+  bench('update ref to trigger watchEffect (executed)', async () => {
+    v.value = i++
+    await nextTick()
+  })
+}
index 01ecc5dee79e33f5c3b2156c50ddb5091d2a7582..bf0646779f5449c6d1a36f5749a1573dcc93e94b 100644 (file)
@@ -14,6 +14,9 @@ importers:
       '@babel/types':
         specifier: ^7.23.5
         version: 7.23.5
+      '@codspeed/vitest-plugin':
+        specifier: ^2.3.1
+        version: 2.3.1(vite@5.0.6)(vitest@1.0.1)
       '@rollup/plugin-alias':
         specifier: ^5.0.1
         version: 5.0.1(rollup@4.1.4)
@@ -42,8 +45,8 @@ importers:
         specifier: ^6.13.0
         version: 6.13.0(eslint@8.54.0)(typescript@5.2.2)
       '@vitest/coverage-istanbul':
-        specifier: ^0.34.6
-        version: 0.34.6(vitest@1.0.1)
+        specifier: ^1.0.2
+        version: 1.0.2(vitest@1.0.1)
       '@vue/consolidate':
         specifier: 0.17.3
         version: 0.17.3
@@ -151,7 +154,7 @@ importers:
         version: 5.2.2
       vite:
         specifier: ^5.0.5
-        version: 5.0.5(@types/node@20.10.3)(terser@5.22.0)
+        version: 5.0.6(@types/node@20.10.3)(terser@5.22.0)
       vitest:
         specifier: ^1.0.0
         version: 1.0.1(@types/node@20.10.3)(jsdom@22.1.0)(terser@5.22.0)
@@ -368,10 +371,10 @@ importers:
     devDependencies:
       '@vitejs/plugin-vue':
         specifier: ^4.4.0
-        version: 4.4.0(vite@5.0.5)(vue@packages+vue)
+        version: 4.4.0(vite@5.0.6)(vue@packages+vue)
       vite:
         specifier: ^5.0.5
-        version: 5.0.5(@types/node@20.10.3)(terser@5.22.0)
+        version: 5.0.6(@types/node@20.10.3)(terser@5.22.0)
 
   packages/shared: {}
 
@@ -642,6 +645,24 @@ packages:
       '@babel/helper-validator-identifier': 7.22.20
       to-fast-properties: 2.0.0
 
+  /@codspeed/core@2.3.1:
+    resolution: {integrity: sha512-7KRwBX4iXK33gEQwh8jPWBF9srGIjewm3oc+A/66caiG/aOyHmxJCapjAZxT2f2vIVYqR7CghzqlxY2ik0DNBg==}
+    dependencies:
+      find-up: 6.3.0
+      node-gyp-build: 4.7.1
+    dev: true
+
+  /@codspeed/vitest-plugin@2.3.1(vite@5.0.6)(vitest@1.0.1):
+    resolution: {integrity: sha512-/e4G2B/onX/hG/EjUU/NpDxnIryeTDamVRTBeWfgQDoex3g7GDzTwoQktaU5l/Asw3ZjEErQg+oQVToQ6jYZlA==}
+    peerDependencies:
+      vite: ^4.2.0 || ^5.0.0
+      vitest: '>=1.0.0-beta.4 || >=1'
+    dependencies:
+      '@codspeed/core': 2.3.1
+      vite: 5.0.6(@types/node@20.10.3)(terser@5.22.0)
+      vitest: 1.0.1(@types/node@20.10.3)(jsdom@22.1.0)(terser@5.22.0)
+    dev: true
+
   /@esbuild/android-arm64@0.18.20:
     resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==}
     engines: {node: '>=12'}
@@ -1560,8 +1581,8 @@ packages:
     resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
     dev: true
 
-  /@types/semver@7.5.4:
-    resolution: {integrity: sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==}
+  /@types/semver@7.5.5:
+    resolution: {integrity: sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg==}
     dev: true
 
   /@types/yauzl@2.10.2:
@@ -1669,7 +1690,7 @@ packages:
     dependencies:
       '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0)
       '@types/json-schema': 7.0.14
-      '@types/semver': 7.5.4
+      '@types/semver': 7.5.5
       '@typescript-eslint/scope-manager': 5.62.0
       '@typescript-eslint/types': 5.62.0
       '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.2.2)
@@ -1701,27 +1722,29 @@ packages:
     resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
     dev: true
 
-  /@vitejs/plugin-vue@4.4.0(vite@5.0.5)(vue@packages+vue):
+  /@vitejs/plugin-vue@4.4.0(vite@5.0.6)(vue@packages+vue):
     resolution: {integrity: sha512-xdguqb+VUwiRpSg+nsc2HtbAUSGak25DXYvpQQi4RVU1Xq1uworyoH/md9Rfd8zMmPR/pSghr309QNcftUVseg==}
     engines: {node: ^14.18.0 || >=16.0.0}
     peerDependencies:
       vite: ^4.0.0
       vue: ^3.2.25
     dependencies:
-      vite: 5.0.5(@types/node@20.10.3)(terser@5.22.0)
+      vite: 5.0.6(@types/node@20.10.3)(terser@5.22.0)
       vue: link:packages/vue
     dev: true
 
-  /@vitest/coverage-istanbul@0.34.6(vitest@1.0.1):
-    resolution: {integrity: sha512-5KaBNZPDSk2ybavC3rZ1pWGniw7sJ5usuwVGRUYzJwiBfWvnLpuUer7bjw7qUCRGdKJXrBgb/Dsgif9rkwMX/A==}
+  /@vitest/coverage-istanbul@1.0.2(vitest@1.0.1):
+    resolution: {integrity: sha512-HZk0VYYvLrUX/TExxxVT7DwowqjJXmm4LbKGYBLN9HwYZe50nGYU3K/KisnOY7lgt0+Po4MLVa2fXe2ediyr9g==}
     peerDependencies:
-      vitest: '>=0.32.0 <1'
+      vitest: ^1.0.0
     dependencies:
-      istanbul-lib-coverage: 3.2.0
+      debug: 4.3.4
+      istanbul-lib-coverage: 3.2.2
       istanbul-lib-instrument: 6.0.1
       istanbul-lib-report: 3.0.1
       istanbul-lib-source-maps: 4.0.1
       istanbul-reports: 3.1.6
+      magicast: 0.3.2
       picocolors: 1.0.0
       test-exclude: 6.0.0
       vitest: 1.0.1(@types/node@20.10.3)(jsdom@22.1.0)(terser@5.22.0)
@@ -3833,8 +3856,8 @@ packages:
     resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
     dev: true
 
-  /istanbul-lib-coverage@3.2.0:
-    resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==}
+  /istanbul-lib-coverage@3.2.2:
+    resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==}
     engines: {node: '>=8'}
     dev: true
 
@@ -3845,7 +3868,7 @@ packages:
       '@babel/core': 7.23.5
       '@babel/parser': 7.23.5
       '@istanbuljs/schema': 0.1.3
-      istanbul-lib-coverage: 3.2.0
+      istanbul-lib-coverage: 3.2.2
       semver: 7.5.4
     transitivePeerDependencies:
       - supports-color
@@ -3855,7 +3878,7 @@ packages:
     resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==}
     engines: {node: '>=10'}
     dependencies:
-      istanbul-lib-coverage: 3.2.0
+      istanbul-lib-coverage: 3.2.2
       make-dir: 4.0.0
       supports-color: 7.2.0
     dev: true
@@ -3865,7 +3888,7 @@ packages:
     engines: {node: '>=10'}
     dependencies:
       debug: 4.3.4
-      istanbul-lib-coverage: 3.2.0
+      istanbul-lib-coverage: 3.2.2
       source-map: 0.6.1
     transitivePeerDependencies:
       - supports-color
@@ -4178,6 +4201,14 @@ packages:
     dependencies:
       '@jridgewell/sourcemap-codec': 1.4.15
 
+  /magicast@0.3.2:
+    resolution: {integrity: sha512-Fjwkl6a0syt9TFN0JSYpOybxiMCkYNEeOTnOTNRbjphirLakznZXAqrXgj/7GG3D1dvETONNwrBfinvAbpunDg==}
+    dependencies:
+      '@babel/parser': 7.23.5
+      '@babel/types': 7.23.5
+      source-map-js: 1.0.2
+    dev: true
+
   /make-dir@4.0.0:
     resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
     engines: {node: '>=10'}
@@ -4359,6 +4390,11 @@ packages:
       whatwg-url: 5.0.0
     dev: true
 
+  /node-gyp-build@4.7.1:
+    resolution: {integrity: sha512-wTSrZ+8lsRRa3I3H8Xr65dLWSgCvY2l4AOnaeKdPA9TB/WYMPaTcrzf3rXvFoVvjKNVnu0CcWSx54qq9GKRUYg==}
+    hasBin: true
+    dev: true
+
   /node-releases@2.0.13:
     resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==}
     dev: true
@@ -5992,7 +6028,7 @@ packages:
       debug: 4.3.4
       pathe: 1.1.1
       picocolors: 1.0.0
-      vite: 5.0.5(@types/node@20.10.3)(terser@5.22.0)
+      vite: 5.0.6(@types/node@20.10.3)(terser@5.22.0)
     transitivePeerDependencies:
       - '@types/node'
       - less
@@ -6004,8 +6040,8 @@ packages:
       - terser
     dev: true
 
-  /vite@5.0.5(@types/node@20.10.3)(terser@5.22.0):
-    resolution: {integrity: sha512-OekeWqR9Ls56f3zd4CaxzbbS11gqYkEiBtnWFFgYR2WV8oPJRRKq0mpskYy/XaoCL3L7VINDhqqOMNDiYdGvGg==}
+  /vite@5.0.6(@types/node@20.10.3)(terser@5.22.0):
+    resolution: {integrity: sha512-MD3joyAEBtV7QZPl2JVVUai6zHms3YOmLR+BpMzLlX2Yzjfcc4gTgNi09d/Rua3F4EtC8zdwPU8eQYyib4vVMQ==}
     engines: {node: ^18.0.0 || >=20.0.0}
     hasBin: true
     peerDependencies:
@@ -6086,7 +6122,7 @@ packages:
       strip-literal: 1.3.0
       tinybench: 2.5.1
       tinypool: 0.8.1
-      vite: 5.0.5(@types/node@20.10.3)(terser@5.22.0)
+      vite: 5.0.6(@types/node@20.10.3)(terser@5.22.0)
       vite-node: 1.0.1(@types/node@20.10.3)(terser@5.22.0)
       why-is-node-running: 2.2.2
     transitivePeerDependencies:
index e5d5f59345f71ac06ca9705b8f81e23dc0df4c95..3b1d4354ef0a94c7a0c47e5a484f7cca11cb8215 100644 (file)
@@ -1,5 +1,6 @@
-import { configDefaults, defineConfig, UserConfig } from 'vitest/config'
+import { configDefaults, defineConfig } from 'vitest/config'
 import { entries } from './scripts/aliases.js'
+import codspeedPlugin from '@codspeed/vitest-plugin'
 
 export default defineConfig({
   define: {
@@ -20,10 +21,10 @@ export default defineConfig({
   resolve: {
     alias: entries
   },
+  plugins: [codspeedPlugin()],
   test: {
     globals: true,
     // disable threads on GH actions to speed it up
-    threads: !process.env.GITHUB_ACTIONS,
     setupFiles: 'scripts/setupVitest.ts',
     environmentMatchGlobs: [
       ['packages/{vue,vue-compat,runtime-dom}/**', 'jsdom']
@@ -43,4 +44,4 @@ export default defineConfig({
       ]
     }
   }
-}) as UserConfig
+})