بسیاری از ما یک وابستگی (dependency) را نصب میکنیم و دیگر هرگز به آن نگاه نمیکنیم. کار خود را انجام میدهد، تستها پاس میشوند و ما به سراغ کارهای بعدی میرویم. اما پلتفرم وب نیز در حال حرکت است و تعداد قابل توجهی از کتابخانههایی که امروز در فایل package.json شما قرار دارند، اکنون در خود مرورگر ساخته شدهاند.
در یک برنامه جاوااسکریپت متوسط، اغلب میتوانید بین ۶۰ تا ۹۰ کیلوبایت (فشرده و کدگذاری شده) وابستگی پیدا کنید که پلتفرم اکنون میتواند به تنهایی از پس آنها برآید. قالببندی تاریخ و اعداد، درخواستهای HTTP، مودالها، تولتیپها، کپی عمیق (deep cloning)، گروهبندی آرایهها: همه اینها چند سال پیش شکافهای واقعی بودند. بسیاری از آنها دیگر شکاف نیستند.
دلیل ماندگاری این کتابخانهها تنبلی نیست. بلکه این است که اکثر تیمها وابستگیهای خود را با ریتم Baseline بازرسی نمیکنند، یا به سادگی از سرعت توسعه مرورگرها در این روزها بیاطلاع هستند. شما npm audit را برای امنیت بررسی میکنید، اما این سوال که «آیا این کتابخانه هنوز کاری انجام میدهد که مرورگر نمیتواند؟» به ندرت پرسیده میشود. بنابراین کتابخانهها باقی میمانند.
در این مقاله، ما با هم این بازرسی را انجام خواهیم داد. به جای بررسی تک به تک وابستگیها، به صورت خوشهای کار خواهیم کرد، زیرا مزایا معمولاً به صورت گروهی حاصل میشوند. ما محاسبات باندل را انجام خواهیم داد، یک چارچوب تصمیمگیری کوچک برای استفاده مجدد شما خواهیم ساخت و در مورد مواردی که پلتفرم هنوز کاستی دارد، صادق خواهیم بود. در پایان، شما یک فرآیند قابل تکرار خواهید داشت که میتوانید روی package.json خود اجرا کنید.
Baseline واقعاً به چه معناست؟
قبل از اینکه شروع به حذف چیزها کنیم، بیایید به سرعت مرور کنیم که Baseline چیست. اگر قبلاً با آن آشنا هستید، میتوانید از این بخش صرف نظر کنید.
Baseline پروژهای از گروه جامعه WebDX است که به زبان ساده به شما میگوید یک ویژگی وب چقدر برای استفاده در مرورگرهای اصلی (کروم، اج، فایرفاکس و سافاری) ایمن است. یک ویژگی میتواند در یکی از سه حالت زیر باشد:
- دسترسی محدود: این ویژگی هنوز در همه موتورهای اصلی منتشر نشده است. بدون یک جایگزین (fallback) نمیتوان به آن تکیه کرد.
- Baseline تازه در دسترس: این ویژگی به تازگی در همه موتورهای اصلی قرار گرفته است. برای کاربران با مرورگرهای بهروز کار میکند، اما دستگاههای قدیمیتر ممکن است هنوز آن را نداشته باشند.
- Baseline به طور گسترده در دسترس: این ویژگی به مدت ۳۰ ماه در همه موتورهای اصلی بوده است. در این مرحله، میتوانید بدون فکر زیاد از آن استفاده کنید.
این فاصله ۳۰ ماهه بین «تازه» و «به طور گسترده» برای این بازرسی بسیار مهم است. یک ویژگی که به طور گسترده در دسترس است، چیزی است که معمولاً میتوانید امروز یک کتابخانه را برای آن حذف کنید. یک ویژگی که فقط تازه در دسترس است، چیزی است که میتوانید یک کتابخانه را برای آن حذف کنید، اگر ابتدا مخاطبان خود را بررسی کنید، یا اگر با یک بررسی ویژگی کوچک راحت هستید. ما این دو مورد را در طول مقاله متفاوت بررسی خواهیم کرد.
میتوانید هر ویژگی را در webstatus.dev، در MDN (هر صفحه مرجع یک نشان Baseline در بالای صفحه نشان میدهد)، یا به صورت برنامهنویسی با بسته npm web-features جستجو کنید. ما در ادامه هنگام اجرای بازرسی روی یک پروژه واقعی از هر سه استفاده خواهیم کرد.
یک چارچوب تصمیمگیری قبل از حذف هر چیزی
وسوسهانگیز است که بخوانید «مرورگر اکنون این کار را انجام میدهد» و شروع به حذف کتابخانهها کنید. بیایید این کار را نکنیم. یک جایگزینی که روی کاغذ رایگان به نظر میرسد، میتواند بیسروصدا برای بخشی از کاربران شما مشکل ایجاد کند، یا هزینهای برای شما داشته باشد که بدون اینکه متوجه شوید به آن تکیه کردهاید.
بنابراین قبل از حذف هر کتابخانهای، سه سوال بپرسید. ما این سوالات را در هر خوشه زیر دوباره استفاده خواهیم کرد.
۱. آیا جایگزین برای مخاطبان من Baseline-safe است؟
نه «آیا Baseline است» به صورت انتزاعی، بلکه «آیا برای افرادی که واقعاً از برنامه من استفاده میکنند ایمن است». اگر ویژگی بومی به طور گسترده در دسترس باشد، معمولاً پاسخ مثبت است. اگر فقط تازه در دسترس باشد، تجزیه و تحلیل یا پیکربندی browserslist خود را بررسی کنید و ببینید چه سهمی از کاربران شما آن دی بلاگ را از دست خواهند داد. یک داشبورد B2B که همه از آخرین مرورگر استفاده میکنند، وضعیتی بسیار متفاوت از یک سایت عمومی با تعداد زیادی دستگاه اندروید قدیمی است.
۲. هزینه واقعی این جایگزینی چقدر است؟
حذف یک کتابخانه همیشه رایگان نیست. گاهی اوقات ویژگی بومی به اندازه کافی گسترده پشتیبانی نمیشود، بنابراین به یک polyfill نیاز خواهید داشت. اگر آن polyfill سنگینتر از کتابخانهای باشد که حذف میکنید، باندل خود را بزرگتر کردهاید، مگر اینکه آن را به صورت شرطی بارگذاری کنید. ما دقیقاً این مورد را با Temporal در ادامه خواهیم دید.
۳. آیا ویژگی پلتفرم مورد استفاده واقعی من را پوشش میدهد؟
کتابخانهها اغلب کاری بیشتر از ویژگی پلتفرمی که شبیه آن هستند، انجام میدهند. axios فقط fetch با تجزیه خودکار JSON نیست؛ دارای interceptor، لغو درخواست و تلاش مجدد است. اگر از اینها استفاده میکنید، جایگزینی مستقیم با fetch شما را مجبور به پیادهسازی مجدد آنها خواهد کرد. قبل از فرض اینکه یک جایگزین مستقیم است، بررسی کنید که واقعاً از چه چیزی استفاده میکنید.
این سه نکته را در ذهن داشته باشید. هر خوشه زیر در واقع فقط همین سوالات است که در گوشهای متفاوت از وابستگیهای شما اعمال میشود.
خوشه ۱: بینالمللیسازی (بزرگترین برد امروز)
این خوشهای است که معمولاً بیشترین کیلوبایت را روی ویژگیهایی که قبلاً به طور گسترده در دسترس هستند، پیدا خواهید کرد. مرورگر مجموعهای کامل از ابزارهای قالببندی را تحت نام Intl ارائه میدهد و بسیاری از کتابخانههای کوچک و محبوب غیرضروری شدهاند.
در اینجا مظنونین معمول و آنچه جایگزین آنها میشود آورده شده است:
timeago.js(۱ کیلوبایت فشرده) ←Intl.RelativeTimeFormatpluralize(۲.۳ کیلوبایت فشرده) ←Intl.PluralRulesnumeral(۳.۹ کیلوبایت فشرده) ←Intl.NumberFormathumanize-duration(۶.۶ کیلوبایت فشرده) ←Intl.DurationFormat- کمککنندههای پیوستن لیست ←
Intl.ListFormat
بیایید برخی از آنها را بررسی کنیم.