چطور Baseline کمک میکند JavaScript کمتری بفرستیم؟
فاصلهٔ «کتابخانه» و «خود مرورگر» کوتاهتر شده
خیلی از وابستگیهای package.json وقتی نصب شدند کار میکردند، تستها سبز ماندند، و دیگر کسی سراغشان نرفت. در همین مدت پلتفرم وب جلو رفت: فرمت تاریخ و عدد، درخواست HTTP، مودال، تولتیپ، deep clone و گروهبندی آرایه دیگر لزوماً به کتابخانه نیاز ندارند.
در یک اپ متوسط جاوااسکریپت، معمولاً حدود ۶۰ تا ۹۰ کیلوبایت (minified و gzipped) وابستگی هست که خود مرورگر الان میتواند پوشش بدهد. مشکل تنبلی نیست؛ تیمها معمولاً روی cadence مربوط به Baseline دوباره audit نمیکنند.

Baseline چیست؟
Baseline از WebDX Community Group میگوید یک قابلیت وب چقدر در Chrome، Edge، Firefox و Safari امن است:
- Limited availability — هنوز در همهٔ موتورهای اصلی نیست؛ بدون fallback تکیه نکنید.
- Baseline Newly available — تازه در همهٔ موتورها آمده؛ برای کاربران بهروز خوب است، روی دستگاههای قدیمیتر ممکن است نباشد.
- Baseline Widely available — حدود ۳۰ ماه در همهٔ موتورها بوده؛ معمولاً بدون نگرانی میشود سراغش رفت.
فاصلهٔ Newly تا Widely مهم است: Widely را معمولاً همین امروز میتوان جایگزین کتابخانه کرد؛ Newly را فقط بعد از چک مخاطب یا با feature check.
وضعیت هر قابلیت را در webstatus.dev، روی MDN، یا با پکیج web-features ببینید.
قبل از حذف: سه سؤال
- جایگزین برای مخاطب من Baseline-safe است؟ Widely معمولاً بله. Newly را با analytics یا
browserslistچک کنید. - هزینهٔ واقعی جابهجایی چقدر است؟ اگر polyfill از خود کتابخانه سنگینتر شود، باندل بزرگتر میشود (مگر conditional load).
- قابلیت پلتفرم همان use case واقعی من را پوشش میدهد؟ مثلاً
axiosفقطfetchنیست؛ interceptor و retry هم دارد.
هر کلاستر پایین همان سه سؤال است روی یک گوشه از وابستگیها.
کلاستر ۱: بینالمللیسازی (معمولاً بزرگترین برد امروز)
خانوادهٔ Intl خیلی از کتابخانههای کوچک فرمت را بینیاز کرده است. مجموع تقریبی مجموعهٔ کامل: ~۱۴KB gzip.
| کتابخانه | جایگزین پلتفرم | کاربرد | کاهش تقریبی (gz) | وضعیت Baseline |
|---|---|---|---|---|
timeago.js |
Intl.RelativeTimeFormat |
«۳ ساعت پیش» و نسبیسازی زمان | ~۱KB | Widely |
pluralize |
Intl.PluralRules |
قواعد جمع/مفرد بر اساس locale | ~۲.۳KB | Widely |
numeral |
Intl.NumberFormat |
جداکننده هزارگان، ارز، درصد، compact | ~۳.۹KB | Widely |
humanize-duration |
Intl.DurationFormat |
تبدیل مدت به متن خوانا | ~۶.۶KB | Newly (مارس ۲۰۲۵) |
| کمکهای join لیست | Intl.ListFormat |
«Alice, Bob, and Carol» | چند KB | Widely |
نکته: RelativeTimeFormat واحد را خودش انتخاب نمیکند؛ اختلاف را حساب کنید و بزرگترین واحد مناسب را بدهید. برای DurationFormat روی سایت عمومی با دستگاههای قدیمی، یک سال دیگر صبر کنید یا feature check بگذارید.
کلاستر ۲: کلاینتهای HTTP
| کتابخانه | جایگزین پلتفرم | کاربرد | کاهش تقریبی (gz) | وضعیت Baseline |
|---|---|---|---|---|
axios |
fetch + AbortController / AbortSignal.timeout |
GET/POST و timeout | ~۱۷KB | Widely |
superagent |
همان | درخواست HTTP عمومی | ~۱۹KB | Widely |
fetch کمتر «خودکار» است. قبل از تعویض کورکورانه این شکافها را ببینید:
- روی ۴۰۴/۵۰۰ reject نمیکند؛ باید
res.okرا خودتان چک کنید. - interceptor ندارد (توکن auth، مدیریت ۴۰۱).
- retry خودکار و upload progress درجهٔ اول ندارد.
اگر فقط GET/POST ساده دارید، یک wrapper نازک روی fetch معمولاً همان ~۱۷KB را پس میگیرد.
const res = await fetch("/api/users", {
signal: AbortSignal.timeout(5000),
});
کلاستر ۳: UI primitives
اینجا جایگزینیها اغلب حتی accessibleتر از پیادهسازی دستی هستند. مجموع تقریبی: ~۲۴KB gzip.
| کتابخانه | جایگزین پلتفرم | کاربرد | کاهش تقریبی (gz) | وضعیت Baseline |
|---|---|---|---|---|
a11y-dialog (و مشابه) |
<dialog> + showModal() |
مودال، focus، Escape، top layer | ~۱.۸KB | Widely |
focus-trap |
همان <dialog> |
قفل فوکوس داخل مودال | ~۶.۶KB | Widely |
body-scroll-lock |
CSS با :has(dialog:modal) |
قفل اسکرول پسزمینه | ~۱.۳KB | Widely |
tippy.js (+ Popper) |
Popover API + CSS anchor positioning | منو، تولتیپ، پنل شناور | ~۱۴KB | Newly (Popover از ژانویه ۲۰۲۵؛ anchor از ژانویه ۲۰۲۶) |
body:has(dialog:modal) {
overflow: hidden;
}
از dialog[open] برای قفل اسکرول استفاده نکنید؛ :modal فقط وقتی واقعاً مودال است true میشود (showModal()).
Anchor positioning هنوز خیلی تازه است: برای مخاطب مدرن عالی است، برای مخاطب گسترده fallback نگه دارید.
کلاستر ۴: ابزارهای Lodash
هدف «حذف کل Lodash» نیست؛ بخشهایی که مرورگر دارد را دیگر نفرستید. فقط clonedeep + groupby حدود ~۸KB gzip است.
| کتابخانه / تابع | جایگزین پلتفرم | کاربرد | کاهش تقریبی (gz) | وضعیت Baseline |
|---|---|---|---|---|
lodash.groupby |
Object.groupBy / Map.groupBy |
گروهبندی آرایه بر اساس کلید | بخشی از ~۸KB+ | Newly (مارس ۲۰۲۴ → Widely حدود اواخر ۲۰۲۶) |
lodash.clonedeep |
structuredClone |
کپی عمیق دادهٔ ساده | بخشی از ~۸KB+ | Widely |
| union / intersection / difference | متدهای Set |
عملیات مجموعه | چند KB | Newly (ژوئن ۲۰۲۴) |
lodash.debounce / throttle |
— (هنوز native نیست) | محدود کردن نرخ اجرا | نگه دارید | — |
structuredClone توابع، DOM node و prototype کلاس را مثل دادهٔ ساده کلون نمیکند؛ برای data plain معمولاً جایگزین تمیزی است.
کلاستر ۵: Temporal — الان حذف نکنید
این کلاستر نشان میدهد چارچوب گاهی میگوید صبر کنید.
| کتابخانه فعلی | جایگزین پیشنهادی | کاربرد | هزینهٔ تقریبی | وضعیت |
|---|---|---|---|---|
dayjs (~۳KB gz) یا date-fns |
Temporal + polyfill |
تاریخ/زمان بهتر از Date |
polyfill رسمی ~۴۴KB gz؛ نسخهٔ سبکتر ~۱۹KB gz | هنوز Baseline نیست (Safari stable ندارد) |
سؤال ۱ و ۲ اینجا رد میشوند: مخاطب گسترده پوشش ندارد و polyfill باندل را بزرگتر میکند. وقتی Safari stable بیاید و به Baseline برسد، دوباره سراغش بروید — ترجیحاً با بارگذاری شرطی polyfill.
چطور روی package.json خودتان audit کنید؟

- وابستگیهای production را لیست کنید:
npm ls --omit=dev --depth=0 - هزینه را اندازه بگیرید: Bundlephobia برای عدد سریع؛ برای تصویر واقعی بعد از tree-shaking از analyzer باندل (
source-map-explorerیاvite-bundle-visualizer) - برای هر کاندیدا، جایگزین پلتفرم و وضعیت Baseline را در webstatus.dev یا MDN چک کنید
- همان سه سؤال را اجرا کنید
- برای Newly، در صورت نیاز progressive enhancement:
if (typeof Intl.DurationFormat === "function") {
// پلتفرم
} else {
// کتابخانه یا فرمت سادهتر
}
جمعبندی
| کلاستر | کاهش تقریبی (gzip) |
|---|---|
| بینالمللیسازی | ~۱۴KB |
| HTTP | ~۱۷KB |
| UI primitives | ~۲۴KB |
| Lodash (بخشهای رایج) | ~۸KB یا بیشتر |
| جمع معمول | ~۶۰–۹۰KB |
اعداد uncompressed در analyzer معمولاً دو تا سه برابر بزرگترند. بعضی پکیجهای dialog بهتنهایی میتوانند تا ~۵۰KB gz باشند.
این کار یکباره تمام نمیشود. هر فصل یک audit کوچک: لیست وابستگیها، چک Baseline، و برگرداندن آنچه پلتفرم دیگر خودش دارد.
این پست نسخهٔ فشرده و جدولمحور ایدههای مقالهٔ How Baseline Can Help You Ship Less JavaScript نوشتهٔ Jad Joubran در Smashing Magazine است؛ برای جزئیات و مثالهای بیشتر همان منبع را ببینید. تصاویر از همان مقاله گرفته شدهاند.