مقالات

چگونه Turbopack جاوا اسکریپت شما را خراب می کند


تب Network را در این صفحه باز کنید و لیستی از فایل های جاوا اسکریپت را با نام های به ظاهر تصادفی مشاهده خواهید کرد:

شبکه

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

روی یکی از آنها کلیک کنید، آن را از بین ببرید، و چیزی شبیه به این پیدا خواهید کرد:

(globalThis.TURBOPACK || (globalThis.TURBOPACK = [])).push([
  "object" == typeof document ? document.currentScript : void 0,
  7284,
  (e) => {
    "use strict";
    function r() {
      for (var e, r, o = 0, t = "", l = arguments.length; o  l; o++) {
        // ...
      }
      return t;
    }
    e.s(["clsx", 0, r, "default", 0, r]);
  },
  395264,
  (e) => {
    "use strict";
    var r = e.i(7284);
    let o = function () {
      // ...
    };
  },
]);
 
//# debugId=e60a5ad0-3ac6-bb3a-e12b-6130e99fb7a6

این یک قطعه است. Turbopack ده‌ها مورد از آنها را برای برنامه Next.js شما تولید می‌کند که شامل کد شما، بسته‌هایی که به آن‌ها بستگی دارد و زمان اجرا که همه آن‌ها را به هم مرتبط می‌کند.

“Chunking” فرآیندی است که در آن تصمیم می گیریم کدام کد در کدام قطعه قرار گیرد. راه‌های زیادی برای انجام گروه‌بندی وجود دارد که هرکدام دارای معاوضه‌های خاص خود هستند.

بیایید با ساده ترین رویکرد شروع کنیم: یک تکه شامل تمام جاوا اسکریپت مورد استفاده برنامه شما.

همه 355 ماژول در یک قطعه در هر صفحه بارگذاری شده اند.

1 قسمت · 1.09 مگابایت

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

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

ما می توانیم به یک قطعه در هر صفحه حرکت کنیم. این تکه ها را نازک نگه می دارد و ما هرگز کد را اضافه بار نمی کنیم. کامل!

یک قطعه در هر صفحه همان 355 ماژول به 8 قسمت تقسیم شده و هر چیزی که بین صفحات به اشتراک گذاشته می شود در هر قسمتی که به آن نیاز دارد کپی شده است.

8 قسمت · 1.20 مگابایت

اما پس از آن ما حافظه پنهان را از دست خواهیم داد. اگر هر صفحه استفاده می کند

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

بنابراین ما به چیزی حتی ظریف تر نیاز داریم. اگر هر ماژول قسمت مخصوص به خود را داشته باشد چه می شود؟ هیچ چیز بیش از حد بارگیری نمی شود و یک ماژول به اشتراک گذاشته شده بین صفحات فقط یک بار دانلود می شود.

یک قسمت در هر ماژول: 355 قسمت جداگانه که هر کدام یک بار ارسال می شود و هر کدام درخواست شبکه خاص خود را دارند.

355 آهنگ · 1.09 مگابایت

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

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

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

برای رسیدن به آنجا باید اصطلاح جدیدی را معرفی کنیم، یک گروه از قطعات. گروه خرده ها مجموعه ای از خرده ها هستند که با هم بارگذاری می شوند. به عنوان مثال، تمام قطعات مورد استفاده برای /home متعلق به یک گروه از قطعات و /blog دیگر:

دو گروه قطعه، یکی در هر مسیر. گروه “/home” سه قطعه را بارگیری می کند. گروه “/blog” دو بار می شود. یک قطعه متعلق به هر دو گروه است، بنابراین ادغام آن با یک همسایه فقط در گروه امن باقی می ماند.

گروه های تکه مشکل مازاد عرضه را حل می کنند. Turbopack فقط قطعات یک گروه را ادغام می کند، و به هر حال قطعات یک گروه همیشه با هم بارگیری می شوند، بنابراین ادغام آنها نمی تواند چیزی را که صفحه قبلا دانلود نکرده است اضافه کند.

اما چگونه می‌توانیم برای بازدید از حافظه پنهان بدون بارگذاری بیش از حد درخواست‌ها، مرورگر را بهینه کنیم؟

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

برای این موارد، بیایید هزینه یا فایده ادغام قطعات را بررسی کنیم

و . تماس بگیرید

یک قطعه است A و در یک قطعه است B.

A در هر صفحه و B فقط در صفحه اصلی استفاده می شود. هر دو در گروه تکه‌های صفحه اصلی هستند، بنابراین کاندیدای ادغام هستند.

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

اگر صفحه دوم را بارگذاری کنند، بستگی به این دارد که آن صفحه به هر دو قسمت نیاز دارد یا فقط به یکی. بگویید آنها از صفحه اصلی به صفحه قانونی می روند. نیازهای صفحه حقوقی A اما نه B. چون A و B در یک فایل ادغام شدند، فایل ادغام شده در آنجا بی فایده است، بنابراین مرورگر دانلود می شود A دوباره تنها بازدیدکننده قبلا دانلود شده است A دو بار

ادغام فقط زمانی در پیمایش هزینه دارد که هر دو صفحه به هر دو قسمت نیاز داشته باشند. فایل ادغام شده مجددا مورد استفاده قرار می گیرد و شما یک پرس و جو را ذخیره کرده اید.

در اینجا دیگر سناریوهای ناوبری احتمالی وجود دارد. هر خط زیر یک جلسه دو صفحه ای است که به عنوان آنچه صفحه اول نیاز دارد، سپس آنچه صفحه دوم نیاز دارد، نوشته شده است. اعداد نشان می دهد که چگونه آنها ادغام می شوند A و B درخواست های رایج و کد دانلود شده در آن جلسه را در مقایسه با جدا نگه داشتن آنها تغییر می دهد.

ناوبری تغییر در درخواست ها تغییر کد انجام شده است
A → A 0 0
A → B 0 0
B → B 0 0
A → A + B 0 + A
B → A + B 0 + B
A + B → A 0 + A
A + B → B 0 + B
A + B → A + B -1 0

هنگام در نظر گرفتن ادغام تکه ها A و B، تعداد گروه های تکه ای را که فقط استفاده می کنند محاسبه می کنیم A، فقط استفاده کنید B، و استفاده کنید A + B. ما هزینه یا سود ادغام را در مقابل احتمال هر سناریو می سنجیم.

در نهایت موارد بازدید یک صفحه و دو صفحه را با توجه به احتمالات آنها وزن می کنیم. قدردانی می کنیم 2/3 از جلسات یک صفحه و 1/3 شامل دو یا بیشتر

در اینجا مقایسه ای بین نسخه های ریپ که در مورد آن بحث کردیم، وجود دارد.

برای ایجاد اعداد برای هر کدام، من بازدید کردم nextjs.org با سه پیکربندی مختلف تقسیم Turbopack: هرگز ادغام نکنید، تنظیمات پیش فرض، و همه چیز را در هر گروه تکه ادغام کنید.

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

ناوبری بدون ادغام تنظیمات پیش فرض Turbopack هر گروه یک عدد
1 nextjs.org (بارگذاری اولیه صفحه) 363.6 کیلوبایت (76 درخواست) 344.2 کیلوبایت (24 درخواست) 315.3 کیلوبایت (6 درخواست)
2 /blog 35.0 کیلوبایت (4) 35.0 کیلوبایت (3) 34.0 کیلوبایت (2)
3 /blog/next-16-3-turbopack 6.0 کیلوبایت (2) 8.7 کیلوبایت (1) 38.3 کیلوبایت (1)
4 /learn 7.4 کیلوبایت (5) 6.6 کیلوبایت (2) 6.6 کیلوبایت (2)
5 /learn/dashboard-app 109.6 کیلوبایت (3) 115.0 کیلوبایت (3) 142.0 کیلوبایت (1)
6 /learn/dashboard-app/getting-started 0 کیلوبایت (0) 0 کیلوبایت (0) 0 کیلوبایت (0)
7 /showcase 24.6 کیلوبایت (2) 25.5 کیلوبایت (2) 25.0 کیلوبایت (1)
8 /docs 15.4 کیلوبایت (4) 19.9 کیلوبایت (3) 48.8 کیلوبایت (2)
به طور کلی 561.6 کیلوبایت (96 درخواست) 554.8 کیلوبایت (38 درخواست) 610.0 کیلوبایت (15 درخواست)

همانطور که می بینید، برش یک عمل متعادل کننده است. در nextjs.org، تنظیمات پیش‌فرض درخواست‌ها را در مقایسه با عدم ادغام بیش از نصف کاهش می‌دهد، در حالی که کد کمی کمتر ارسال می‌شود. حداکثر ادغام پرس و جوها را بیشتر کاهش می دهد اما در کل 10٪ کد بیشتری ارسال می کند. با این حال، اگر ما کمتر پیمایش کرده بودیم، حداکثر ادغام بهینه تر بود. ادغام هر تکه در یک گروه در یک تکه بزرگ مزایایی را در بارگذاری اولیه صفحه به همراه داشت، اما در دراز مدت پرهزینه بود.

دو چیز نحوه عملکرد خوب برش را محدود می کند. ادغام در زمان ساخت و قبل از بازدید هر کسی انجام می شود، بنابراین نمی تواند به آنچه مرورگر قبلاً ذخیره کرده است واکنش نشان دهد. و الگوریتم باید بداند مردم چگونه در سایت شما حرکت می کنند، به همین دلیل است که بازدیدهای تک صفحه ای وزن دارند 2/3. تابستان امسال، به عنوان بخشی از دوره کارآموزی ام با تیم Turbopack، من روی هر دو کار کردم، همراه با اصلاح چیزهایی که در نهایت ضایعات بودند.

لینک عنوان را کپی کنیداستخراج تکه هوشمندتر

جدول بالا هزینه ادغام را نشان می دهد. هنگامی که یک بازدید کننده یک صفحه را با A و سپس یکی با A + B، ادغام باعث دانلود آنها می شود A دو بار بسته نمی تواند از این امر جلوگیری کند زیرا در زمان کامپایل نمی داند مرورگر قبلاً چه چیزی دارد. زمان اجرا انجام می دهد.

در Next.js 16.3 یا جدیدتر، فعال کنید experimental.turbopackChunking.generateComponentChunks در مال شما next.config.js باعث می شود Turbopack نسخه های ادغام نشده تکه ها را همراه با نسخه های ادغام شده استریم کند. ما پیگیری می‌کنیم که کدام اقلام هر قسمت جمع‌شده را تشکیل می‌دهند و کدام یک از آنها قبلاً ذخیره شده‌اند، بنابراین در طول درخواست می‌توانیم ارزان‌تر را انتخاب کنیم: قسمت جمع‌شده یا فقط قطعاتی که گم شده‌اند.

همچنین در جهت مخالف عمل می کند. اگر یک بازدیدکننده قبلاً ادغام شده را بارگیری کرده باشد A + B، می توانیم از بارگیری مجدد صرف نظر کنیم A به طور مستقل

سپس پیمایش‌های نرم کدهای غیرضروری کمتری بارگیری می‌کنند و ما از مزایای ادغام بدون هزینه ناوبری برخوردار می‌شویم.

برای مشاهده تفاوت، این برنامه آزمایشی را بررسی کنید:

generateComponentChunks: نادرست

component-pieces-demo-off.labs.vercel.dev

generateComponentChunks: درست است

component-pieces-demo-of.labs.vercel.dev

ما نیز آزمایش می کنیم only-if-cached دستورالعملی که به ما امکان می دهد بررسی کنیم که بازدیدکننده هنگام ورود چه چیزی را در حافظه پنهان ذخیره کرده است. این همان پیشرفت‌ها را برای افرادی که یک سایت را ترک می‌کنند و بعداً بازمی‌گردند، گسترش می‌دهد.

لینک عنوان را کپی کنیدشکست مبتنی بر تجزیه و تحلیل

شاید متوجه شده باشید که ما در الگوریتم برش فرضیات زیادی در مورد وب سایت ها می کنیم. به عنوان مثال، در 2/3 وزن یک حدس است این یک تنظیم پیش‌فرض معقول برای بسیاری از سایت‌ها است، اما لزوماً برای هر سایتی مناسب نیست. اگر می‌دانید مردم واقعاً چگونه از طریق شما عبور می‌کنند، می‌توانید به ما بگویید.

در شما next.config.js، اکنون می توانید آنها را در زیر پیکربندی کنید experimental.turbopackChunking:

  • firstPageLoadPriority: وزن را بین موارد تک صفحه ای و دو صفحه ای تغییر می دهد. یک مقدار بالاتر (بین 0 و 1) بارگذاری اولیه سریع را در اولویت قرار می دهد که به طور بالقوه به قیمت ناوبری تمام می شود. نرخ پرش یک نقطه شروع معقول است. به طور پیش فرض ما 0.67 هستیم.
  • priorityRoutes: لیستی از صفحاتی که سرعت بارگذاری آنها مهمتر است. ما قطعات را در طول این مسیرها به صورت فرصت طلبانه تری ادغام خواهیم کرد.
  • clusters: گروه‌هایی از مسیرهایی که اغلب با هم بازدید می‌شوند و هر کدام با آرایه‌ای از عبارات منظم تعریف می‌شوند. قطعات همپوشانی را راحت‌تر در یک خوشه ادغام می‌کنیم. اما اگر یک خوشه صفحاتی را که فقط استفاده می کنند ترکیب کند A یا به سادگی B با صفحاتی که از هر دو استفاده می کنند، کمتر ادغام می شویم.

لینک عنوان را کپی کنیدقطعات کوچکتر و کمتر

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

  • ماژول های CJS تکان دادن درخت: ما قبلا فقط از این مورد برای ESM پشتیبانی می‌کردیم، بنابراین ماژول‌های CJS وارداتی و صادراتی استفاده نشده برای مشتری ارسال شد. آن را با آن فعال کنید experimental.turbopackCjsTreeShaking. این به طور پیش فرض در نسخه بعدی Next.js گنجانده خواهد شد.
  • زمان اجرا Turbopack اشتراکی: اکنون یک قطعه زمان اجرا جایگزین آن در هر صفحه می شود. آن را با آن فعال کنید experimental.turbopackSharedRuntime. این یک درخواست بلوک و حدود 10 کیلوبایت جاوا اسکریپت سمت سرویس گیرنده را در هر ناوبری پس از اولین مورد ذخیره می کند. Later نیز به طور پیش فرض روشن خواهد بود.
  • زمان اجرای پیش فرض سبک تر: زمان اجرا دیگر کد WebAssembly و Web Worker را به طور پیش فرض ارسال نمی کند. ما تشخیص می دهیم که چه زمانی از این ماژول ها استفاده می کنید و سپس کد بارگیری را وارد می کنیم.

لینک عنوان را کپی کنیدآن را امتحان کنید

این ویژگی های جدید را در Next.js نسخه 16.3 یا جدیدتر امتحان کنید. و اگر علاقه مند به یادگیری بیشتر در مورد برش (از جمله برش CSS) هستید، نگاهی بیندازید توبیاسگفتگوی اخیر در مورد معاوضه ها و محدودیت های ریپینگ.




Source link

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

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

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