مقالات

چگونه Baseline می تواند به شما کمک کند جاوا اسکریپت کمتری ارسال کنید — مجله Smashing


بسیاری از ما یک وابستگی را یک بار نصب می کنیم و دیگر هرگز به آن نگاه نمی کنیم. کار خودش را می‌کند، آزمون‌ها قبول می‌شوند و ما ادامه می‌دهیم. اما پلتفرم وب نیز به حرکت خود ادامه می دهد و تعداد شگفت انگیزی از کتابخانه ها در کتابخانه شما قرار دارند package.json امروز آنها قبلاً در مرورگر ساخته شده اند.

در یک برنامه معمولی جاوا اسکریپت با اندازه متوسط، اغلب می توانید بین 60 کیلوبایت تا 90 کیلوبایت (کوچک شده و gzip شده) وابستگی هایی را بیابید که پلتفرم از قبل می تواند به تنهایی آنها را مدیریت کند. قالب‌بندی تاریخ و اعداد، درخواست‌های HTTP، مدال‌ها، راهنمای ابزار، شبیه‌سازی عمیق، آرایه‌های گروه‌بندی: اینها همه حذفیات واقعی چند سال پیش بودند. بسیاری از آنها دیگر شکاف نیستند.

دلیل ماندن این کتابخانه ها تنبلی نیست. این است که اکثر تیم‌ها وابستگی‌های باند پایه خود را دوباره بررسی نمی‌کنند، یا فقط متوجه سرعت مرورگرهای این روزها نمی‌شوند. شما بررسی کنید npm audit مطمئن باشید، اما آیا این کتابخانه هنوز هم کاری را انجام می دهد که مرورگر قادر به انجام آن نیست؟ سوالی است که به ندرت پرسیده می شود. بنابراین کتابخانه ها باقی می مانند.

در این مقاله با هم این ممیزی را انجام خواهیم داد. به‌جای اینکه وابستگی‌ها را یکی یکی پشت سر بگذاریم، به‌صورت خوشه‌ای کار می‌کنیم، زیرا بردها معمولاً به صورت گروهی به دست می‌آیند. ما محاسبات بسته را انجام می‌دهیم، یک چارچوب تصمیم‌گیری کوچک می‌سازیم که می‌توانید دوباره از آن استفاده کنید، و در مورد جایی که پلتفرم هنوز ضعیف است صادق خواهیم بود. در پایان، یک فرآیند تکرارپذیر خواهید داشت که می توانید خودتان آن را اجرا کنید package.json.

(نمای بزرگ)

در واقع “خط پایه” به چه معناست؟

قبل از اینکه شروع به حذف موارد کنیم، بیایید سریعاً خلاصه کنیم که Baseline چیست. اگر از قبل آشنایی دارید، از این بخش صرفنظر کنید.

Baseline پروژه ای از گروه جامعه WebDX است که به زبان ساده به شما می گوید که استفاده از یک ویژگی وب در مرورگرهای اصلی (Chrome، Edge، Firefox و Safari) چقدر ایمن است. یک تابع می تواند در یکی از سه حالت باشد:

  • در دسترس بودن محدود
    این ویژگی هنوز در همه موتورهای اصلی ارائه نشده است. تکیه بر آن بدون گزینه پشتیبان امن نیست.
  • خط اصلی تازه موجود است
    این ویژگی به تازگی در همه موتورهای اصلی رونمایی شده است. این برای کاربران با مرورگرهای به روز کار می کند، اما دستگاه های قدیمی تر ممکن است هنوز آن را نداشته باشند.
  • سطح پایه به طور گسترده در دسترس است
    این ویژگی در تمام موتورهای اصلی از 30 ماهگی وجود دارد. در این مرحله می توانید بدون فکر زیاد به آن دست پیدا کنید.

این فاصله 30 ماهه بین «جدید» و «واید» برای این حسابرسی اهمیت زیادی دارد. ویژگی‌ای که به‌طور گسترده در دسترس است، چیزی است که معمولاً امروز می‌توانید با آن کتابخانه را ترک کنید. ویژگی‌ای که اخیراً در دسترس است، چیزی است که می‌توانید برای آن کتابخانه را ترک کنید اگر ابتدا مخاطبان خود را بررسی می کنید یا اگر دوست دارید ویژگی های کوچکی را بررسی کنید. ما با این دو مورد متفاوت برخورد خواهیم کرد.

شما می توانید برای هر تابع در webstatus.dev، در MDN (هر صفحه مرجع یک نشان پایه را در بالا نشان می دهد) یا به صورت برنامه ریزی شده با web-features بسته npm بعداً وقتی یک پروژه واقعی را ممیزی می کنیم از هر سه استفاده خواهیم کرد.

چارچوبی برای تصمیم گیری قبل از حذف چیزی

خواندنش وسوسه انگیز است “مرورگر اکنون این کار را انجام می دهد” و شروع به استخراج کتابخانه ها کنید. این کار را نکنیم. صرافی که روی کاغذ رایگان به نظر می رسد می تواند بی سر و صدا همه چیز را برای برخی از کاربران شما خراب کند یا برای شما هزینه خاصی را داشته باشد که بدون اینکه متوجه شوید به آن اعتماد کرده اید.

بنابراین قبل از اینکه هر کتابخانه ای را رها کنید، سه سوال بپرسید. ما از آنها در هر خوشه زیر استفاده مجدد خواهیم کرد.

1. آیا جایگزینی Baseline برای آن بی خطر است؟ مال من مخاطب؟

نه “آیا اساسی است” انتزاعی اما “آیا برای افرادی که واقعاً از برنامه من استفاده می کنند بی خطر است.” اگر تابع بومی به طور گسترده در دسترس باشد، این معمولاً بله است. اگر اخیراً در دسترس است، تجزیه و تحلیل خود یا خودتان را بررسی کنید browserslist پیکربندی کنید و ببینید چه سهمی از کاربران شما را از دست خواهند داد. یک داشبورد B2B که همه در آن از آخرین مرورگر استفاده می کنند، وضعیت بسیار متفاوتی با یک سایت عمومی با صف طولانی دستگاه های اندرویدی قدیمی است.

2. هزینه سوآپ واقعا چقدر است؟

حذف کتابخانه همیشه رایگان نیست. گاهی اوقات ویژگی بومی هنوز به اندازه کافی پشتیبانی نمی شود، بنابراین شما به دنبال یک polyfill خواهید بود. اگر این پلی پر از کتابخانه ای که در حال حذف آن هستید سنگین تر است، بسته خود را ساخته اید بزرگتر، مگر اینکه به صورت مشروط آن را بارگیری کنید. بعداً فقط آن را با Temporal خواهیم دید.

3. آیا ویژگی پلت فرم مورد استفاده واقعی من را پوشش می دهد؟

کتابخانه ها اغلب بیشتر از عملکرد پلتفرمی که شبیه آن هستند انجام می دهند. axios ساده نیست fetch با تجزیه خودکار JSON. رهگیرها، درخواست سقط و تلاش مجدد وجود دارد. اگر از آنها استفاده می کنید، فقط آنها را جایگزین کنید fetch باعث می شود دوباره آنها را اجرا کنید. قبل از اینکه فرض کنید یک جایگزین ضروری است، بررسی کنید که واقعاً از چه چیزی استفاده می کنید.

این سه مورد را در نظر داشته باشید. هر خوشه زیر در واقع فقط همان سوالاتی است که در زاویه متفاوتی از اعتیاد شما اعمال می شود.

خوشه 1: بین المللی شدن (بزرگترین کاهش دهنده امروز برنده است)

این خوشه‌ای است که معمولاً بیشترین KB را روی ویژگی‌هایی می‌بینید که در حال حاضر به طور گسترده در دسترس هستند. مرورگر یک خانواده کامل از ابزارهای قالب بندی را در زیر ارائه می کند Intl فضای نام و بسیاری از کتابخانه های محبوب کوچک غیر ضروری شدند.

در اینجا مظنونین معمولی و مواردی که جایگزین آنها می شود آورده شده است:

  • timeago.js (1 کیلوبایت gz) → Intl.RelativeTimeFormat
  • pluralize (2.3 کیلوبایت gz) → Intl.PluralRules
  • numeral (3.9 کیلوبایت gz) → Intl.NumberFormat
  • humanize-duration (6.6 کیلوبایت gz) → Intl.DurationFormat
  • فهرست پیوستن به یاران → Intl.ListFormat

اجازه دهید برخی از آنها را مرور کنیم.

زمان نسبی

timeago.js برای تبدیل مهر زمان وجود دارد “3 ساعت پیش”. Intl.RelativeTimeFormat همین کار را انجام می دهد و Baseline به طور گسترده در دسترس است.

const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });

rtf.format(-1, "day"); // "yesterday"
rtf.format(3, "hour"); // "in 3 hours"
rtf.format(-2, "week"); // "2 weeks ago"

را numeric: "auto" گزینه چیز خوبی در اینجا است: به جای “1 روز پیش” که در آن زبان کلمه ای برای آن وجود دارد، “دیروز” را به شما می دهد. شما یک عدد و یک واحد را پاس می کنید و یک رشته محلی شده را برمی گردانید.

ممکن است در مورد یک چیز تعجب کنید timeago.js کاری را انجام می دهد که این قطعه انجام نمی دهد: واحد را برای شما انتخاب می کند. تاریخ داده شده timeago.js تصمیم می گیرد که بگوید “ثانیه” یا “روز”. Intl.RelativeTimeFormat از شما انتظار دارد این قسمت را انجام دهید این چند خط حسابی است (تفاوت را محاسبه کنید، بزرگترین واحدی که مناسب است را پیدا کنید)، و هنگامی که این راهنما را نوشتید، دیگر به کتابخانه نیاز ندارید.

اعداد، ارز و لیست ها

Intl.NumberFormat بیشتر کارهایی که کتابخانه‌های قالب‌بندی اعداد انجام می‌دهند را پوشش می‌دهد: هزاران جداکننده، واحد پول، درصدها و نمادهای فشرده.

new Intl.NumberFormat("en-US").format(1234567.89);
// "1,234,567.89"

new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(
  1234.5,
);
// "$1,234.50"

new Intl.NumberFormat("en", { notation: "compact" }).format(1200000);
// "1.2M"

و Intl.ListFormat، که به طور گسترده در دسترس است، با مشکل “الحاق یک آرایه به جمله”، از جمله کاما آکسفورد، که نوعی از چیزهایی است که مردم توابع کمکی ناخوشایند را برای آن می نویسند، مقابله می کند:

const lf = new Intl.ListFormat("en", { style: "long", type: "conjunction" });

lf.format(["Alice", "Bob", "Carol"]);
// "Alice, Bob, and Carol"

تنها هشدار: مدت زمان

humanize-duration چند میلی ثانیه تبدیل می شود “1 ساعت 30 دقیقه”. معادل پلت فرم است Intl.DurationFormat:

const df = new Intl.DurationFormat("en", { style: "long" });

df.format({ hours: 1, minutes: 30 });
// "1 hour, 30 minutes"

یک چیزی که باید در نظر داشت این است که Intl.DurationFormat سطح پایه است جدید موجود در زمان نگارش به طور گسترده در دسترس نیست. در مارس 2025 روی همه موتورهای اصلی عرضه شد و در مسیری قرار دارد که در سال 2027 به طور گسترده در دسترس قرار گیرد. بنابراین این پاسخ سوال 1 را برای برنامه‌های مخاطب عمومی نمی‌دهد، مگر اینکه ابتدا ترافیک خود را بررسی کنید یا یک راه‌حل بازگشتی اضافه کنید. برای یک ابزار داخلی در مرورگرهای مدرن امروز خوب است. برای یک سایت عمومی با دستگاه های قدیمی، یک سال دیگر به آن فرصت دهید یا آن را با بررسی ویژگی نگه دارید.

ریاضیات این خوشه

اگر برنامه شما از مجموعه کامل (humanize-duration، timeago.js، pluralize، numeral)، این تقریباً است 14 کیلوبایت گیزیپ شده از وابستگی ها، که در حال حاضر اکثر آنها را می توان با API های به طور گسترده در دسترس جایگزین کرد. خوشه بین المللی سازی معمولاً ساده ترین برد در کل حسابرسی است.

خوشه 2: سرویس گیرندگان HTTP

این خوشه ظریف‌تر است، بنابراین خوب است سرعت را کم کنید.

کتابخانه های HTTP مرورگر که افراد به آنها دسترسی دارند هستند axios (17 کیلوبایت gz) و superagent (19 کیلوبایت gz). برای اکثر درخواست ها، fetch به علاوه AbortController آنچه شما نیاز دارید را پوشش می دهد و هر دو به طور گسترده در دسترس هستند.

GET اصلی به این صورت است:

// axios
const { data } = await axios.get("/api/users");

// fetch
const res = await fetch("/api/users");
const data = await res.json();

یک خط اضافی (res.json()) است fetch به طور خاص کجا axios ضمنی بود این الگو در سراسر این خوشه است: fetch به‌طور پیش‌فرض کمتر برای شما کار می‌کند و شما تصمیم می‌گیرید که آیا چیزهایی را که کنار گذاشته می‌خواهید می‌خواهید.

منتظر می ماند

axios یک وجود دارد timeout گزینه fetch وجود دارد AbortSignal.timeout():

const res = await fetch("/api/users", {
  signal: AbortSignal.timeout(5000), // abort after 5 seconds
});

کجا fetch جایگزین نمی شود axios

این جایی است که سؤال 3 بیشتر کار را انجام می دهد، بنابراین بیایید در مورد شکاف ها دقیق باشیم:

  • fetch خطاهای HTTP را رد نمی کند.
    الف 404 یا 500 یک قول قطعی است، نه یک رد. شما باید بررسی کنید res.ok خودت axios هر وضعیت غیر 2xx را رد می کند.
  • بدون رهگیر
    اگر تکیه کنید axios رهگیرهایی برای چسباندن توکن های احراز هویت یا رسیدگی به 401 ها در یک مکان، fetch معادلی وجود ندارد می پیچید fetch در تابع یا کلاس خود برای دریافت همان رفتار.
  • بدون تلاش مجدد خودکار
    axios (با افزونه) می تواند درخواست های ناموفق را دوباره امتحان کند. با fetch، این کد شما برای نوشتن است.
  • هیچ پیشرفتی در آپلود وجود ندارد.
    fetch هنوز نمی‌توان پیشرفت آپلود را به روشی ممتاز گزارش کرد. اگر یک آپلود کننده فایل با نوار پیشرفت دارید، این یک دلیل واقعی برای نگهداری یک کتابخانه است.

من به شخصه خیلی به آن اعتماد دارم رهگیرها در دوره‌های آنلاین تعاملی من مانند یادگیری جاوا اسکریپت، و سال‌هاست که با استفاده از سفارشی این مشکل را حل کرده‌ام. class در بالای fetch. من این را برای میلیون ها کاربر ارسال کرده ام و با آن موفقیت زیادی داشته ام.

بازیابی هیچ یک از اینها دشوار نیست و اکثر برنامه ها فقط از یک یا دو مورد از آنها استفاده می کنند. اما این دقیقاً همان خوشه‌ای است که شما نباید کورکورانه آن را پیدا کرده و جایگزین کنید. ابتدا به نحوه استفاده از کلاینت HTTP خود نگاه کنید. اگر GET و POST ساده است، رها کنید axios برای نازک fetch wrapper تقریبا شما را نجات می دهد 17 کیلوبایت گیزیپ شده.

Cluster 3: User Interface Primitives

این خوشه دارای برخی از رضایت‌بخش‌ترین مبادلات است، زیرا ویژگی‌های پلتفرم فقط با کتابخانه‌ها مطابقت ندارند، بلکه اغلب از آنچه تیم‌ها به صورت دستی ارسال می‌کنند در دسترس‌تر هستند.

کتابخانه‌های اینجا دیالوگ‌های مدال هستند (چیزی شبیه به a11y-dialog، 1.8 کیلوبایت gz)، نکات ابزار و کتابخانه های بازشو (tippy.js، 14 کیلوبایت gz که شامل پوپر برای موقعیت یابی است. focus-trap (6.6 کیلوبایت gz) و body-scroll-lock (1.3 کیلوبایت gz). آنها با سه عملکرد پلت فرم جایگزین می شوند:

عنصر، Popover API و موقعیت یابی لنگر CSS.

را عنصر

مقدار زیادی کد مرتبط با مودال برای حل مشکلات دسترسی وجود دارد: گرفتن تمرکز در داخل مدال، بسته شدن Escape، بازگرداندن فوکوس به عنصر قبلی هنگامی که گفتگو بسته است، و رندر کردن روی هر چیز دیگری. را

یک مورد به طور گسترده در دسترس همه این کارها را برای شما انجام می دهد.


  

Delete this file?

const dialog = document.querySelector("#confirm"); dialog.showModal(); // focus moves in, background goes inert, Escape closes it dialog.addEventListener("close", () => { console.log(dialog.returnValue); // "cancel" or "delete" });

یک تماس showModal() این کار را انجام می دهد focus-trap برای: فوکوس به دیالوگ منتقل می شود، بقیه صفحه بی اثر می شود، بنابراین نمی توانید از آن خارج شوید، Escape آن را می بندد و فوکوس به عنصری باز می گردد که آن را باز کرده است. کادر محاوره ای در مرورگر نمایش داده می شود لایه بالاییپس دعوا نکنید z-index. شما همچنین یک دریافت می کنید ::backdrop شبه عنصر برای استایل دادن به پوشش.

این مورد می تواند جایگزین کتابخانه مودال شما شود و focus-trap. تنها بخشی که به خودی خود از عهده آن بر نمی آید قفل پس زمینه از اسکرول است، یعنی همان body-scroll-lock برای بود. این اکنون یک خط از CSS است:

body:has(dialog:modal) {
  overflow: hidden;
}

اگر تعجب می کنید که چرا ما استفاده می کنیم dialog:modal به جای dialog[open]، این به این دلیل است open ویژگی به محض تماس تنظیم می شود show()، اما دیالوگ واقعاً اینطور نیست معین بنابراین هنوز نمی خواهید اسکرول را قفل کنید. را :modal کلاس شبه فقط زمانی درست است که گفتگو واقعی باشد معین، همانطور که در هنگام تماس وجود دارد showModal().

بنابراین سه کتابخانه در یک عنصر و یک قانون CSS جمع می شوند.

Popover API و موقعیت یابی لنگر

برای چیزهایی که کاملاً مدال نیستند (کرشوها، نکات ابزار، پانل های کوچک شناور که tippy.js دسته‌ها)، Popover API رفتاری برای رد نور، رندر کردن بالاترین لایه و Escape-برای بستن بدون جاوا اسکریپت:




با کلیک بر روی دکمه پنجره بازشو تغییر می کند. کلیک کردن در خارج از آن، آن را می بندد. این خط پایه اخیراً در دسترس است (از ژانویه 2025).

نیمه دیگر کاری که کتابخانه اشاره انجام می دهد این است موقعیت یابی: نگه داشتن شناور به ماشه خود و چرخاندن آن هنگام عبور از ویوپورت. این پوپر است (بسته داخل tippy.js) دستکاری می کند و اکنون یک تابع CSS به نام Anchor positioning است. در اینجا هم همینطور ضمیمه شده است #menu پاپاور مستقیماً زیر دکمه ماشه:

#options {
  anchor-name: --trigger;
}

.tooltip {
  position-anchor: --trigger;
  position-area: top;
  margin: 0;
}

تعیین موقعیت لنگر جدیدترین ویژگی در این مقاله است. زمانی که فایرفاکس 147 آن را ارسال کرد، به تازگی در ژانویه 2026 در دسترس قرار گرفت (Chrome آن را از نسخه 125 و سافاری از نسخه 26 در اختیار داشت). از آنجایی که بسیار تازه است، یک ویژگی سوال 1 است: برای یک مخاطب مدرن عالی است، اما ترافیک خود را بررسی کنید و توجه داشته باشید که برخی از قسمت های پیشرفته تر (مانند بک گراندهای موقعیت) از نسخه های مختلف پشتیبانی می کنند. برای مرورگرهای قدیمی یک بازگشت معقول داشته باشید.

بین

، Popover API و موقعیت یابی لنگر، خوشه ای از UI های اولیه (کتابخانه راهنمای ابزار، کتابخانه مدال، focus-trap، body-scroll-lock) تقریباً اضافه می کند 24 کیلوبایت گیزیپ شدهو شما با تنظیمات دسترسی پیش‌فرض بهتری نسبت به اکثر راه‌حل‌های دست‌ساز از آن طرف بیرون می‌آیید.

خوشه 4: Lodash Utilities

Lodash در حال حاضر به ندرت به طور کامل وارد می شود، اما عملکردهای فردی آن در همه جا ظاهر می شود یا به صورت کامل lodash بسته (25 کیلوبایت gz) یا به عنوان نصب مستقل به عنوان lodash.clonedeep و lodash.groupby. چندین مورد از رایج ترین ها در حال حاضر معادل های پلت فرم مستقیم دارند.

گروه بندی

lodash.groupby یک آرایه را به یک شی با یک کلید از برخی ویژگی ها سازماندهی مجدد می کند. Object.groupBy فقط این کار را انجام می دهد:

const products = [
  { name: "Apple", category: "fruit" },
  { name: "Carrot", category: "vegetable" },
  { name: "Banana", category: "fruit" },
];

const grouped = Object.groupBy(products, (product) => product.category);
// {
//   fruit: [{ name: "Apple", ... }, { name: "Banana", ... }],
//   vegetable: [{ name: "Carrot", ... }],
// }

نیز وجود دارد Map.groupBy برای زمانی که شما می خواهید Map به جای یک شیء ساده (در صورتی که کلیدهای شما رشته ای نیستند مفید است). هر دو به تازگی از مارس 2024 در دسترس هستند و در مسیری هستند که در اواخر سال 2026 به طور گسترده در دسترس قرار می گیرند.

شبیه سازی عمیق

lodash.clonedeep یک کپی عمیق از یک شی می سازد. structuredClone نسخه پلتفرم است و به طور گسترده در دسترس است:

const original = { user: { name: "Sam", roles: ["admin"] } };

const copy = structuredClone(original);
copy.user.roles.push("editor");

original.user.roles; // ["admin"] (unchanged)

structuredClone رسیدگی به پرونده های دشواری که دچار مشکل می شوند JSON.parse(JSON.stringify(...)): شبیه سازی شده است Date، Map، Set، ArrayBuffer، و ارجاعات دایره ای به درستی. محدودیتی که باید از آن آگاه بود (دوباره سوال 3) این است که نمی تواند توابع، گره های DOM یا نمونه های کلاس را شبیه سازی کند. توابع را می‌فرستد و نمونه اولیه را روی نمونه‌های کلاس می‌فرستد. برای داده‌های معمولی که بیشتر افراد آن را شبیه‌سازی عمیق می‌کنند، این یک جایگزین تمیز است.

عملیات را تنظیم کنید

اگر تا به حال از کمک کننده Lodash استفاده کرده اید union، intersection، یا difference، در Set شی از قبل دارای موارد داخلی است. این موارد اولیه از ژوئن 2024 در دسترس هستند:

const admins = new Set(["sam", "alex", "jo"]);
const editors = new Set(["alex", "kim"]);

admins.intersection(editors); // Set { "alex" }
admins.union(editors); // Set { "sam", "alex", "jo", "kim" }
admins.difference(editors); // Set { "sam", "jo" }

مجموعه کامل روش ها است union، intersection، difference، symmetricDifference، isSubsetOf، isSupersetOf، و isDisjointFrom.

چیزی که ارزش نگهداری دارد

همه لوداش به سکو منتقل نشده است. debounce و throttle آنها هنوز معادل طبیعی ندارند و واقعا مفید هستند، بنابراین چیدن گیلاس lodash.debounce منطقی است هدف از این خوشه “حذف Lodash” نیست، بلکه “توقف ارسال قطعاتی است که مرورگر از قبل دارد”. بیرون افتادن lodash.clonedeep و lodash.groupby تنهایی در اطراف است 8 کیلوبایت گیزیپ شده، و اگر کامل را وارد کنید lodash برای تعداد معدودی از ویژگی‌ها، جایگزینی آن‌هایی که توسط یک پلتفرم پوشش داده می‌شوند، به شما امکان می‌دهد به طور کامل انصراف دهید.

خوشه 5: آزمایشی، مطالعه موردی در مورد اینکه هنوز کتابخانه ای منتشر نشده است

هر خوشه تاکنون با “برو، بگذار برود” به پایان رسیده است. برعکس است، و به همین دلیل ارزش روشن کردن آن را دارد: قاب را نشان می دهد که به شما می گوید صبر کنید.

Temporal جایگزینی است که مدتها در انتظار جاوا اسکریپت بود Dateو این یک API واقعا بهتر است: اشیاء تغییرناپذیر، مدیریت معقول مناطق زمانی، و دیگر نمایه‌های ماهانه از صفر شروع نمی‌شود. در مارس 2026 به مرحله 4 TC39 رسید و بخشی از مشخصات ES2026 است. فایرفاکس آن را در نسخه 139 (در سال 2025) و کروم آن را در نسخه 144 (ژانویه 2026) ارسال کرد. سافاری هنوز آن را در نسخه پایدار ارسال نکرده است. در پیش‌نمایش فناوری سافاری قرار دارد و انتظار می‌رود تا اواخر سال 2026 پشتیبانی پایداری داشته باشد.

اگر Temporal برای شما جدید است، برای بررسی اجمالی و مقایسه سریع API، به Cheatsheet موقت مراجعه کنید. Date.

با این حال Temporal است نه سطح پایه. هنوز داخل است در دسترس بودن محدود، زیرا کاربران سافاری آن را ندارند. برای استفاده از آن در همه مرورگرهای امروزی، به پلی فیل نیاز دارید، و اینجاست که ریاضیات علیه شما تغییر می کند.

رسمی @js-temporal/polyfill در مورد است 44 کیلوبایت گیزیپ شده. یک پلی پر کوچکتر وجود دارد که در داخل به BigInt وابسته نیست و وزن دارد 19 کیلوبایت گیزیپ شده. کتابخانه سبک وزن با تاریخ هایی مانند dayjs در مورد است 3 کیلوبایت گیزیپ شده. پس اگر معاوضه کنید dayjs برای Temporal به علاوه polyfill آن در حال حاضر، شما 3 کیلوبایت ذخیره نمی کنید، اما علاوه بر این تقریباً 41 کیلوبایت به بسته شما، مگر اینکه بتوانید به صورت مشروط پلی فایل را بارگیری کنید.

آن را از طریق قاب اجرا کنید:

  • سوال 1 (مخاطب): زمان یک خط مبنا نیست. برای یک مخاطب گسترده، این تعداد افراد زیادی است.
  • سوال 2 (قیمت): polyfill بیش از ده برابر اندازه کتابخانه ای است که می خواهید حذف کنید. تبادل بسته شما را بزرگتر می کند.
  • سوال 3 (شکاف در توابع): Temporal در واقع در اینجا برنده است. بیشتر از dayjs. اما این مهم نیست تا زمانی که سوالات 1 و 2 شکست بخورند.

حکم به طور کلی روشن است: نگه دارید dayjs (یا date-fns) در حال حاضر. زمان بازبینی زمانی است که سافاری Temporal را به یک نسخه پایدار ارسال می کند و به خط اولیه می رسد. در این مرحله، می‌توانید از Temporal برای بارگیری بومی و مشروط polyfill برای کاربران مرورگرهای قدیمی‌تر استفاده کنید. این ویژگی است که باید آن را یادداشت کنید و چند ماه دیگر دوباره بررسی کنید، نه اینکه امروز به آن عمل کنید.

چگونه خودتان این ممیزی را انجام دهید package.json

خوشه های بالا یک نقشه شروع هستند، اما وابستگی های شما متعلق به خودتان است. در اینجا یک فرآیند تکرارپذیر وجود دارد که می توانید در این سه ماهه شروع کنید.

مرحله 1: وابستگی های تولید خود را فهرست کنید

با فهرست کردن آنچه واقعاً به کاربران ارائه می شود شروع کنید:

npm ls --omit=dev --depth=0

مرحله 2: ارزش هر کدام را اندازه بگیرید

برای یک عدد بسته سریع، Bundlephobia اندازه کوچک شده و gzip شده هر بسته npm را به شما می دهد. برای تصویر واقعی (هزینه هر وابستگی چقدر است در بسته واقعی شما، پس از تکان دادن درخت و حذف مجدد، یک تحلیلگر بسته را در مقابل ساخت خود اجرا کنید. npx source-map-explorer روی اکثر بسته ها کار می کند و npx vite-bundle-visualizer برای پروژه های Vite کار می کند.

وب‌سایت Bundlephobia نشان می‌دهد که وزن axios 44 کیلوبایت کوچک‌سازی شده و 16.6 کیلوبایت کوچک‌سازی شده &gzip شده است. دانلود چنین بسته‌ای در ۳G کند ۳۳۱ میلی‌ثانیه و در ۴G نوظهور ۱۹ میلی‌ثانیه طول می‌کشد.
(نمای بزرگ)

مرحله 3: وضعیت پایه هر جایگزین را بررسی کنید

برای هر نامزد، ویژگی پلتفرمی را پیدا کنید که جایگزین آن خواهد شد و وضعیت پایه آن را بررسی کنید. سریعترین راه webstatus.dev یا نشان Baseline در صفحه MDN این ویژگی است.

مرحله 4: سه سوال را کامل کنید

برای هر کتابخانه ای با تعویض پلتفرم، به چارچوب بازگردید: آیا خط پایه برای مخاطبان شما امن است؟ هزینه معاوضه چقدر است؟ آیا این ویژگی نحوه استفاده شما از کتابخانه را پوشش می دهد؟ بیشتر تصمیمات شما بر روی سوال 1 قرار می گیرد (وضعیت ویژگی را در مقابل خود بررسی کنید browserslist) و سوال 3 (استفاده خود را بررسی کنید).

مرحله 5: در صورت نیاز، در پشت بهبود تدریجی تبادل نظر کنید

برای ویژگی‌های گسترده، تغییر دهید و ادامه دهید. برای مواردی که به تازگی در دسترس هستند، یا تأیید کنید که مخاطبان شما از مرورگرهای مدرن استفاده می‌کنند، یا کد جدید را با بررسی سریع ویژگی‌ها نگه دارید و یک نسخه بازگشتی داشته باشید:

if (typeof Intl.DurationFormat === "function") {
  // use the platform feature
} else {
  // fall back to the library, or a simpler format
}

به این ترتیب، کد کمتری را برای کاربرانی ارسال می‌کنید که می‌توانند آن را بدون شکستن کاربرانی که نمی‌توانند اجرا کنند.

تکمیل

خوشه ها را اضافه کنید و تصویر ملموس است. خوشه بین‌المللی‌سازی حدود 14 کیلوبایت gzip شده است، HTTP حدود 17 کیلوبایت است، رابط‌های کاربری اولیه حدود 24 کیلوبایت هستند، و ابزارهای Lodash بسته به قسمتی از کتابخانه که ارسال می‌کنید، 8 کیلوبایت یا بیشتر هستند. برای یک برنامه معمولی با اندازه متوسط، چیزی بین 60 تا 90 کیلوبایت gzipped از وابستگی‌ها است که می‌توانید به پلتفرم بازگردانید، و در صورت ارسال کامل، بیشتر lodash یا چندین مورد از این کتابخانه ها به طور همزمان. (اعداد فشرده نشده دو تا سه برابر بزرگتر هستند که در تحلیلگر بسته قبل از gzip مشاهده خواهید کرد.)

من بسته‌های نسبتاً سبک را برای اکثر این ویژگی‌ها انتخاب کرده‌ام، اما برخی از بسته‌های فردی هنوز هم می‌توانند سنگین باشند. بسته محاوره ای شما، برای مثال، بسته به چیزی که استفاده می کنید، می تواند تا 50 کیلوبایت gzip وزن داشته باشد.

چند ویژگی ارزش توجه به آنها را در سال آینده دارند زیرا آنها مبادلات اضافی را باز می کنند:

  • به طور موقت متولد می شود.
    هنگامی که سافاری آن را به نسخه پایدار ارسال کرد و به خط پایه رسید، می‌توانید هر دو کتابخانه تاریخ خود را حذف کنید. و polyfill، پسرفت امروز را به یک پیروزی واقعی تبدیل می کند.
  • پیری موقعیت یابی لنگر CSS.
    به تازگی در ژانویه 2026 در دسترس قرار گرفته است، همانطور که به طور گسترده در دسترس قرار می گیرد، حذف راهنمای ابزار و کتابخانه های موقعیت یابی بازشو، آن را برای مخاطبان گسترده ایمن تر می کند.
  • Object.groupBy و دوستان به حالت گسترده در دسترس هستند.
    دسته‌ای از 2024 (گروه‌بندی آرایه، روش‌های تنظیم) در اواخر سال 2026 به طور گسترده در دسترس قرار می‌گیرد و آنها را از «مخاطبان خود را آزمایش کنید» به «فقط از آن استفاده کنید» منتقل می‌کند.

هیچ کدام از اینها پاکسازی یکباره نیست. این پلتفرم به طور مداوم ویژگی های جدید و تفاوت بین آنها را ارائه می دهد “برای آن به یک کتابخانه نیاز دارید” و “مرورگر این کار را انجام می دهد” همچنان بسته می شود عادتی که ارزش ساختن دارد عادت کوچکی است: هر سه ماه یک بار حسابرسی. وابستگی های خود را فهرست کنید، بررسی کنید که اکنون خط پایه چیست و آنچه را که می توانید پس دهید.

یک خوشه از این مقاله انتخاب کنید، خود را باز کنید package.jsonو ببینید که مرورگر در حال حاضر چقدر از این کار را برای شما انجام می دهد.

ویرایش شکسته
(Yk)


Source link

نوشته های مشابه

دیدگاهتان را بنویسید

دکمه بازگشت به بالا