چطور کندی Vite را در پروژههای بزرگ پیدا کنیم؟
وقتی پروژه کوچک است، Vite معمولاً بسیار سریع است. اما با رشد codebase، افزایش تعداد pluginها، dependencyهای سنگین، monorepo و هزاران module، ممکن است startup، HMR یا production build بهمرور کند شود.
اشتباه رایج این است که بدون اندازهگیری config را تغییر دهیم. مسیر بهتر:
Measure → Isolate → Profile → Change → Remeasure
اول مشخص کنید چه چیزی کند است
«Vite کند است» مسئله دقیقی نیست. حداقل این موارد را جدا کنید:
- cold start dev server؛
- first page load؛
- HMR؛
- production build.
هرکدام ممکن است root cause متفاوتی داشته باشند.
baseline ثبت کنید
قبل از تغییر config، وضعیت فعلی را ثبت کنید. cold run را با warm run قاطی نکنید و environment را ثابت نگه دارید.
اگر مسئله در dev page load است، browser extensionها و تنظیم Disable Cache در DevTools را هم بررسی کنید؛ چون میتوانند نتیجه را منحرف کنند.
pluginها را بررسی کنید
Vite ابزار debug برای transform pluginها دارد:
vite --debug plugin-transform
بهخصوص pluginهایی را بررسی کنید که روی فایلهای بسیار زیادی اجرا میشوند یا filter محدودی ندارند.
Hookهای حساس معمولاً شامل اینها هستند:
config
configResolved
buildStart
resolveId
load
transform
یک هزینه کوچک در transform اگر روی هزاران فایل تکرار شود، میتواند قابلتوجه شود.
transform timing و import waterfall
vite --debug transform
این خروجی کمک میکند فایلهای پرهزینه و dependency chainهای عمیق را پیدا کنید.
نمونه:
main.tsx
↓
Dashboard.tsx
↓
charts/index.ts
↓
heavy-chart-library
در dev، transformهای on-demand میتوانند waterfall ایجاد کنند.
Barrel fileها را بدون تعصب بررسی کنید
Barrelها همیشه بد نیستند، اما یک index.ts بزرگ ممکن است graph را بیش از حد باز کند.
به جای:
import { formatMoney } from "@/utils"
گاهی import مستقیم بهتر است:
import { formatMoney } from "@/utils/format-money"
این تغییر فقط وقتی ارزش دارد که measurement آن را تأیید کند.
CPU profile بگیرید
Vite profiling داخلی دارد:
vite --profile --open
برای build:
vite build --profile
فایل .cpuprofile کمک میکند ببینید CPU واقعاً زمان را کجا مصرف میکند.
server.warmup هدفمند
اگر چند فایل مشخص تقریباً همیشه در اولین route استفاده میشوند و transform آنها سنگین است، warmup میتواند مفید باشد:
export default defineConfig({
server: {
warmup: {
clientFiles: [
"./src/pages/dashboard.tsx",
"./src/lib/heavy-utils.ts",
],
},
},
})
کل codebase را warm نکنید؛ این فقط هزینه را به startup منتقل میکند.
--force راهحل دائمی نیست
Dependency optimization خودکار است. اگر پروژه دائماً به vite --force نیاز دارد، باید علت cache invalidation یا linked dependency بررسی شود.
Vite 8 چه تغییری داده؟
Vite 8 در مارس ۲۰۲۶ با Rolldown بهعنوان bundler یکپارچه منتشر شد. این تغییر معماری build را سادهتر کرده و طبق اعلام رسمی Vite میتواند buildهای بسیار سریعتری ایجاد کند.
اما upgrade جای profiling را نمیگیرد. اگر plugin سفارشی یا import graph مشکل داشته باشد، نسخه جدید الزاماً root cause را حذف نمیکند.
Vite 8.1 نیز bundled dev mode آزمایشی را برای applicationهای بسیار بزرگ معرفی کرده است. این گزینه برای همه پروژهها نیست و زمانی ارزش بررسی دارد که تعداد بسیار زیاد moduleها واقعاً bottleneck باشد.
یک workflow عملی
1. Scope
cold start:
first load:
HMR:
build:
2. Environment
- Node version
- Vite version
- package manager
- plugin list
- monorepo/linking
3. Plugin timing
vite --debug plugin-transform
4. Transform timing
vite --debug transform
5. CPU profile
vite --profile --open
vite build --profile
6. یک تغییر هدفمند
مثلاً:
- محدود کردن filter یک plugin؛
- حذف کار سنگین از startup hook؛
- import مستقیم برای barrel مشکلساز؛
- warmup چند فایل؛
- upgrade Vite.
7. دوباره اندازه بگیرید
اگر قبل/بعد قابل اندازهگیری نیست، بهینهسازی را قطعی اعلام نکنید.
جمعبندی
Vite performance بیشتر از اینکه مجموعهای از magic configها باشد، یک مسئله profiling است:
Slow Vite
↓
Classify
↓
Measure plugins/transforms
↓
CPU profile
↓
Find bottleneck
↓
Targeted change
↓
Remeasure
این روند از tweakهای تصادفی جلوگیری میکند و نتیجهای قابل دفاع برای code review یا case study میدهد.