سفر شاپیفای برای رسوندن اکستنشنهای چکاوت به زیر ۶۴ کیلوبایت
خلاصهٔ کاملتر
به گفتهٔ جاستین هنریکس، اکستنشنهای رابط کاربریِ اپ Checkout Blocks روی یکسوم همهٔ چکاوتهای سفارشیشده اجرا میشن و روی ریاکت و پل قدیمیِ Remote UI شاپیفای، با نسخهٔ API ۲۰۲۵-۰۷ که قراره بازنشسته بشه، ساخته شده بودن. چون شاپیفای داره کل سطح اکستنشنهاش رو به remote-dom و وبکامپوننتهای Polaris منتقل میکنه، موندن روی مسیر قدیمی گزینه نبود. ضمناً از اول اکتبر ۲۰۲۶، دیپلوی اپهایی که نسخهٔ اکستنشنشون قدیمیتر از ۲۰۲۶-۰۱ باشه بلاک میشه.
انگیزهٔ فنی هم روشنه: چکاوت بهشدت به کارایی حساسه و هر اکستنشن یعنی کدی که دقیقاً موقع تصمیمگیریِ خریدار باید دانلود، پارس و اجرا بشه. نتیجهٔ مهاجرت این بود که حجم منتقلشدهٔ هر پنج اکستنشن بین ۴۰ تا ۸۵ درصد کم شد — از ۸۴.۴٪ برای payment-icons تا ۴۰.۵٪ برای line-item-actions. معیار Extension Load Time هم بهطور میانگین و وزندار بر اساس حجم چکاوت، ۸٪ در صدک ۵۰ و ۷٪ در صدک ۹۰ بهتر شد.
تغییر اصلی، رفتن از ریاکت به Preact بود. اکستنشنهای قدیمی از طریق @shopify/ui-extensions-react رندر میشدن که react-reconciler رو با خودش میآورد تا درخت ریاکت رو به پروتکل سریالشدهٔ remote-ui ترجمه کنه. remote-dom جور دیگهای کار میکنه: نودهای واقعی DOM رو از سندباکس روی هاست آینه میکنه، پس هر فریمورک رندرکنندهٔ DOM (یا حتی هیچ فریمورکی) کار میکنه و وبکامپوننتهای Polaris فقط المانهای سفارشیِ مستقل از فریمورکن. کدبیس هم همونجا به TypeScript منتقل شد.
روش کار «تدریجی، از کوچیکترین» بود: یه core-next جدید (Preact/TypeScript/remote-dom) کنار core قدیمی بالا آوردن و هر اکستنشن که ارتقا میگرفت به اون سوییچ میکرد، بدون اینکه بقیه دست بخورن؛ آخر کار core-next تو یه core واحد ادغام شد و کد قدیمی پاک شد. بخش مکانیکی تبدیل هم بهشدت با کمک هوش مصنوعی انجام شد: یه agent skill داخلی که به مستندات وصل بود، تبدیل ریاکت به Preact، جایگزینی کامپوننتهای Polaris با معادلهای s-* و انتقال هوکها به APIهای جدید رو به عهده گرفت.
سختترین بخش، سقف سفت ۶۴ کیلوبایت gzip برای هر باندل بود که CLI نسخهٔ ۲۰۲۶-۰۱ اعمالش میکنه؛ اکستنشنها حدود ۱۰۰ تا ۱۱۲ کیلوبایت gzip بودن. بزرگترین برد رایگان بود: کنارگذاشتن react-reconciler با رفتن به Preact حدود ۸۹ کیلوبایت آزاد کرد. liquidjs هم با یه پارسر مینیمالِ داخلی به اسم «droplet» جایگزین شد که با کمک هوش مصنوعی ولی با انضباط ساخته شد: اسپک رسمی Liquid بهعنوان منبع حقیقت، و یه مجموعهٔ تست همارزی از هزاران پیکربندی واقعی مرچنتها که فایل فیکسچرش بیش از ۴۲ هزار خطه.
یه رولبک واقعی هم داشتن: هوک useId() در Preact شناسههای قطعی و محدود به یه درخت رندر میسازه، پس دو نمونه از یه اکستنشن شناسهٔ یکسان تولید میکردن و چون Polaris برای اتصال commandFor به id تکیه میکنه، کلیک روی لینک فیلد دوم مودالِ فیلد اول رو باز میکرد؛ راهحل، هوک useStableId با شناسهٔ تصادفی بود. حذف textAlign از Paragraph و Heading هم متنهای وسطچین رو خراب کرد که با باز کردن دوبارهٔ textAlignment حل شد، و برای لیبل s-checkbox اسلاتی اضافه شد که لینک درونخطی رو قبول کنه.
نکات کلیدی:
- پنج اکستنشن به API ۲۰۲۶-۰۱ روی remote-dom با Preact و وبکامپوننتهای Polaris منتقل شدن
- کاهش ۴۰ تا ۸۵ درصدی حجم منتقلشده و بهبود ۸٪ / ۷٪ زمان لود در صدکهای ۵۰ و ۹۰
- سقف سفت ۶۴ کیلوبایت gzip، تصمیمهای بهتعویقافتاده دربارهٔ وابستگیهای سنگین رو اجباری کرد
- بردهای اصلی: حذف react-reconciler (~۸۹KB)، پارسر داخلی Liquid بهجای liquidjs، و alias کردن markdown-to-jsx روی Preact
- از اول اکتبر ۲۰۲۶ دیپلوی اکستنشنهای قدیمیتر از ۲۰۲۶-۰۱ بلاک میشه
- درس تیم: هوش مصنوعی کارهای مکانیکی رو خوب انجام میده، ولی اعتبارسنجی باید با دادهٔ واقعی پروداکشن باشه نه نمونههای ساختگی




