Профилирование производительности тестов
При запуске Vitest отображаются различные метрики времени выполнения ваших тестов:
bashRUN v2.1.1 /x/vitest/examples/profiling ✓ test/prime-number.test.ts (1) 4517ms ✓ generate prime number 4517ms Test Files 1 passed (1) Tests 1 passed (1) Start at 09:32:53 Duration 4.80s (transform 44ms, setup 0ms, collect 35ms, tests 4.52s, environment 0ms, prepare 81ms) # Time metrics ^^
- Transform: Время, затраченное на преобразование файлов. См. Преобразование файлов.
- Setup: Время, затраченное на выполнение
setupFiles
. - Collect: Время, затраченное на сбор всех тестов в тестовых файлах. Это включает время, необходимое для импорта всех файловых зависимостей.
- Tests: Время, затраченное на выполнение тестов.
- Environment: Время, затраченное на настройку тестовой среды
environment
, например JSDOM. - Prepare: Время, затрачиваемое Vitest на подготовку тестового раннера.
Тестовый раннер
Если выполнение ваших тестов занимает много времени, вы можете сгенерировать профиль тестового раннера. См. документацию NodeJS по следующим опциям:
WARNING
Опция --prof
не работает с pool: 'threads'
из-за ограничений node:worker_threads
.
Чтобы передать эти опции тестовому раннеру Vitest, определите poolOptions.<pool>.execArgv
в вашей конфигурации Vitest:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
pool: 'forks',
poolOptions: {
forks: {
execArgv: [
'--cpu-prof',
'--cpu-prof-dir=test-runner-profile',
'--heap-prof',
'--heap-prof-dir=test-runner-profile',
],
// Для генерации одного профиля
singleFork: true,
},
},
},
});
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
pool: 'threads',
poolOptions: {
threads: {
execArgv: [
'--cpu-prof',
'--cpu-prof-dir=test-runner-profile',
'--heap-prof',
'--heap-prof-dir=test-runner-profile',
],
// Для генерации одного профиля
singleThread: true,
},
},
},
});
После выполнения тестов будут сгенерированы файлы test-runner-profile/*.cpuprofile
и test-runner-profile/*.heapprofile
. См. Просмотр записей профилирования для инструкций по их анализу.
Пример см. в Profiling | Examples.
Основной поток
Профилирование основного потока полезно для отладки использования Vite в Vitest и файлов globalSetup
. Здесь же выполняются ваши плагины Vite.
TIP
См. Performance | Vite для получения дополнительных советов по профилированию, характерному для Vite.
Мы рекомендуем vite-plugin-inspect
для профилирования производительности ваших плагинов Vite.
Для этого необходимо передать аргументы процессу Node, который запускает Vitest.
$ node --cpu-prof --cpu-prof-dir=main-profile ./node_modules/vitest/vitest.mjs --run
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^
# NodeJS arguments Vitest arguments
После выполнения тестов должен быть сгенерирован файл main-profile/*.cpuprofile
. См. Просмотр записей профилирования для инструкций по их анализу.
Преобразование файлов
Если время преобразования и сбора тестов велико, вы можете использовать переменную окружения DEBUG=vite-node:*
, чтобы увидеть, какие файлы преобразуются и выполняются vite-node
.
$ DEBUG=vite-node:* vitest --run
RUN v2.1.1 /x/vitest/examples/profiling
vite-node:server:request /x/vitest/examples/profiling/global-setup.ts +0ms
vite-node:client:execute /x/vitest/examples/profiling/global-setup.ts +0ms
vite-node:server:request /x/vitest/examples/profiling/test/prime-number.test.ts +45ms
vite-node:client:execute /x/vitest/examples/profiling/test/prime-number.test.ts +26ms
vite-node:server:request /src/prime-number.ts +9ms
vite-node:client:execute /x/vitest/examples/profiling/src/prime-number.ts +9ms
vite-node:server:request /src/unnecessary-file.ts +6ms
vite-node:client:execute /x/vitest/examples/profiling/src/unnecessary-file.ts +4ms
...
Эта стратегия профилирования помогает выявить ненужные преобразования, вызванные barrel files. Если в этих логах присутствуют файлы, которые не должны загружаться при запуске вашего теста, возможно, у вас есть barrel files, которые импортируют файлы без необходимости.
Вы также можете использовать Vitest UI для отладки медлительности, вызванной barrel files. Пример ниже показывает, как импорт файлов без barrel file сокращает количество преобразованных файлов приблизительно на 85%.
├── src
│ └── utils
│ ├── currency.ts
│ ├── formatters.ts
│ ├── index.ts
│ ├── location.ts
│ ├── math.ts
│ ├── time.ts
│ └── users.ts
├── test
│ └── formatters.test.ts
└── vitest.config.ts
import { expect, test } from 'vitest';
import { formatter } from '../src/utils';
import { formatter } from '../src/utils/formatters';
test('formatter works', () => {
expect(formatter).not.toThrow();
});

Чтобы увидеть, как преобразуются файлы, вы можете использовать переменную окружения VITE_NODE_DEBUG_DUMP
для записи преобразованных файлов в файловую систему:
$ VITE_NODE_DEBUG_DUMP=true vitest --run
[vite-node] [debug] dump modules to /x/examples/profiling/.vite-node/dump
RUN v2.1.1 /x/vitest/examples/profiling
...
$ ls .vite-node/dump/
_x_examples_profiling_global-setup_ts-1292904907.js
_x_examples_profiling_test_prime-number_test_ts-1413378098.js
_src_prime-number_ts-525172412.js
Покрытие кода
Если формирование отчёта о покрытии кода происходит медленно в вашем проекте, вы можете использовать переменную окружения DEBUG=vitest:coverage
для включения логирования производительности.
$ DEBUG=vitest:coverage vitest --run --coverage
RUN v3.1.1 /x/vitest-example
vitest:coverage Reading coverage results 2/2
vitest:coverage Converting 1/2
vitest:coverage 4 ms /x/src/multiply.ts
vitest:coverage Converting 2/2
vitest:coverage 552 ms /x/src/add.ts
vitest:coverage Uncovered files 1/2
vitest:coverage File "/x/src/large-file.ts" is taking longer than 3s
vitest:coverage 3027 ms /x/src/large-file.ts
vitest:coverage Uncovered files 2/2
vitest:coverage 4 ms /x/src/untested-file.ts
vitest:coverage Generate coverage total time 3521 ms
Этот подход к профилированию отлично подходит для обнаружения больших файлов, которые случайно включаются провайдерами покрытия. Например, если ваша конфигурация случайно включает большие минифицированные файлы Javascript в покрытие кода, они будут отображаться в логах. В этих случаях рекомендуется настроить опции coverage.include
и coverage.exclude
.
Просмотр записей профилирования
Вы можете просматривать содержимое файлов *.cpuprofile
и *.heapprofile
с помощью различных инструментов. Примеры см. в списке ниже.