هنگام بارگذاری اسکریپت ها، مرورگر برای ارزیابی آنها قبل از اجرا زمان می برد که می تواند باعث انجام کارهای طولانی شود. بیاموزید که ارزیابی اسکریپت چگونه کار می کند، و چه کاری می توانید انجام دهید تا از ایجاد کارهای طولانی در حین بارگذاری صفحه جلوگیری کنید.
وقتی صحبت از بهینهسازی Interaction to Next Paint (INP) میشود، بیشتر توصیههایی که با آن مواجه میشوید این است که خود تعاملات را بهینه کنید. به عنوان مثال، در راهنمای بهینه سازی وظایف طولانی ، تکنیک هایی مانند تسلیم شدن با setTimeout
و موارد دیگر مورد بحث قرار گرفته است. این تکنیکها سودمند هستند، زیرا با اجتناب از کارهای طولانی، به نخ اصلی اجازه میدهند تا فضای تنفسی داشته باشد، که میتواند فرصتهای بیشتری را برای تعاملات و سایر فعالیتها فراهم کند تا زودتر اجرا شوند، نه اینکه مجبور باشند برای یک کار طولانی منتظر بمانند.
با این حال، در مورد وظایف طولانی که از بارگذاری خود اسکریپت ها به وجود می آیند، چه می توان گفت؟ این کارها می توانند با تعاملات کاربر تداخل داشته باشند و بر INP صفحه در هنگام بارگذاری تأثیر بگذارند. این راهنما بررسی میکند که مرورگرها چگونه وظایفی را که با ارزیابی اسکریپت آغاز میشوند، انجام میدهند و به بررسی کارهایی که ممکن است بتوانید برای تجزیه کار ارزیابی اسکریپت انجام دهید، میپردازد تا موضوع اصلی شما بتواند در هنگام بارگیری صفحه به ورودی کاربر پاسخگوتر باشد.
ارزیابی فیلمنامه چیست؟
اگر برنامهای را که جاوا اسکریپت زیادی ارسال میکند پروفایل کردهاید، ممکن است کارهای طولانی را دیده باشید که مجرم با برچسب ارزیابی اسکریپت است.

ارزیابی اسکریپت بخشی ضروری از اجرای جاوا اسکریپت در مرورگر است، زیرا جاوا اسکریپت به موقع قبل از اجرا کامپایل می شود. هنگامی که یک اسکریپت ارزیابی می شود، ابتدا برای خطاها تجزیه می شود. اگر تجزیه کننده خطاها را پیدا نکرد، اسکریپت سپس در بایت کد کامپایل می شود و سپس می تواند به اجرا ادامه دهد.
اگرچه لازم است، ارزیابی اسکریپت می تواند مشکل ساز باشد، زیرا کاربران ممکن است سعی کنند با یک صفحه در مدت کوتاهی پس از ارائه اولیه آن تعامل داشته باشند. با این حال، فقط به این دلیل که یک صفحه رندر شده است به این معنی نیست که بارگیری صفحه تمام شده است. فعل و انفعالاتی که در حین بارگذاری انجام می شود می تواند به تاخیر بیفتد زیرا صفحه مشغول ارزیابی اسکریپت ها است. در حالی که هیچ تضمینی وجود ندارد که تعاملی در این مقطع زمانی انجام شود - زیرا ممکن است یک اسکریپت مسئول آن هنوز بارگیری نشده باشد - ممکن است تعاملاتی وابسته به جاوا اسکریپت وجود داشته باشد که آماده هستند یا اینکه تعامل اصلاً به جاوا اسکریپت بستگی ندارد.
رابطه بین اسکریپت ها و وظایفی که آنها را ارزیابی می کند
اینکه چگونه وظایفی که مسئول ارزیابی اسکریپت هستند، به این بستگی دارد که آیا اسکریپتی که بارگیری می کنید با یک عنصر معمولی <script>
بارگذاری شده است یا اینکه اسکریپت یک ماژول بارگذاری شده با type=module
است. از آنجایی که مرورگرها تمایل دارند مسائل را به گونهای متفاوت مدیریت کنند، نحوه انجام ارزیابی اسکریپت توسط موتورهای مرورگر اصلی در جایی که رفتارهای ارزیابی اسکریپت در آنها متفاوت است، مورد بررسی قرار خواهد گرفت.
اسکریپت های بارگذاری شده با عنصر <script>
تعداد وظایفی که برای ارزیابی اسکریپت ها ارسال می شود معمولاً با تعداد عناصر <script>
در یک صفحه رابطه مستقیم دارد. هر عنصر <script>
یک کار را برای ارزیابی اسکریپت درخواستی آغاز می کند تا بتوان آن را تجزیه، کامپایل و اجرا کرد. این مورد برای مرورگرهای مبتنی بر Chromium، Safari و Firefox است.
چرا این مهم است؟ فرض کنید از یک بستهکننده برای مدیریت اسکریپتهای تولید خود استفاده میکنید، و آن را طوری پیکربندی کردهاید که همه چیزهایی که صفحه شما برای اجرا شدن نیاز دارد در یک اسکریپت واحد قرار دهد. اگر این مورد برای وب سایت شما باشد، می توانید انتظار داشته باشید که یک وظیفه برای ارزیابی آن اسکریپت ارسال شود. آیا این چیز بدی است؟ نه لزوما - مگر اینکه آن اسکریپت بزرگ باشد.
میتوانید کار ارزیابی اسکریپت را با اجتناب از بارگیری تکههای بزرگ جاوا اسکریپت جدا کنید و اسکریپتهای فردی و کوچکتر را با استفاده از عناصر <script>
اضافی بارگیری کنید.
در حالی که همیشه باید تلاش کنید تا جاوا اسکریپت کمتری را در طول بارگذاری صفحه بارگیری کنید، تقسیم اسکریپت های خود تضمین می کند که به جای یک کار بزرگ که ممکن است رشته اصلی را مسدود کند، تعداد بیشتری کار کوچکتر دارید که به هیچ وجه رشته اصلی را مسدود نمی کند - یا حداقل کمتر از آنچه که با آن شروع کرده اید.

<script>
متعدد موجود در HTML صفحه ایجاد می شوند. این به ارسال یک بسته اسکریپت بزرگ برای کاربران ترجیح داده می شود، که احتمال بیشتری دارد تا رشته اصلی را مسدود کند.میتوانید تقسیم وظایف برای ارزیابی اسکریپت را تا حدودی شبیه به تسلیم شدن در طول تماسهای رویدادی که در طول یک تعامل اجرا میشوند، در نظر بگیرید. با این حال، با ارزیابی اسکریپت، مکانیسم بازده، جاوا اسکریپتی را که بارگذاری میکنید به چند اسکریپت کوچکتر تقسیم میکند، به جای تعداد کمتری از اسکریپتهای بزرگتر که احتمال مسدود کردن رشته اصلی وجود دارد.
اسکریپت های بارگذاری شده با عنصر <script>
و ویژگی type=module
اکنون می توان ماژول های ES را به صورت بومی در مرورگر با ویژگی type=module
در عنصر <script>
بارگیری کرد. این رویکرد برای بارگذاری اسکریپت دارای برخی از مزایای تجربه توسعهدهنده است، مانند عدم نیاز به تغییر کد برای استفاده در تولید - بهویژه زمانی که در ترکیب با نقشههای وارداتی استفاده میشود. با این حال، بارگیری اسکریپت ها به این روش، وظایفی را که از مرورگر به مرورگر متفاوت است، زمان بندی می کند.
مرورگرهای مبتنی بر کروم
در مرورگرهایی مانند کروم - یا مرورگرهای مشتق شده از آن - بارگیری ماژولهای ES با استفاده از ویژگی type=module
انواع مختلفی از وظایف را ایجاد میکند که معمولاً هنگام عدم استفاده از type=module
مشاهده میکنید. به عنوان مثال، یک کار برای هر اسکریپت ماژول اجرا می شود که شامل فعالیتی است که به عنوان ماژول کامپایل برچسب گذاری شده است.

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

اثر اینجا - حداقل در کروم و مرورگرهای مرتبط - این است که مراحل کامپایل هنگام استفاده از ماژولهای ES شکسته میشوند. این یک پیروزی آشکار از نظر مدیریت وظایف طولانی است. با این حال، کار ارزیابی ماژول حاصل که نتیجه میشود همچنان به این معنی است که شما هزینههای غیرقابل اجتنابی را متحمل میشوید. در حالی که باید تلاش کنید تا جاوا اسکریپت کمتری ارسال کنید، استفاده از ماژول های ES - صرف نظر از مرورگر - مزایای زیر را ارائه می دهد:
- همه کدهای ماژول به طور خودکار در حالت سخت اجرا می شوند، که امکان بهینه سازی های بالقوه توسط موتورهای جاوا اسکریپت را فراهم می کند که در غیر این صورت نمی توانند در یک زمینه غیر دقیق انجام شوند.
- اسکریپت هایی که با استفاده از
type=module
بارگذاری می شوند، به گونه ای رفتار می شوند که گویی به طور پیش فرض به تعویق افتاده اند. برای تغییر این رفتار می توان از ویژگیasync
در اسکریپت های بارگذاری شده باtype=module
استفاده کرد.
سافاری و فایرفاکس
هنگامی که ماژول ها در سافاری و فایرفاکس بارگذاری می شوند، هر یک از آنها در یک کار جداگانه ارزیابی می شوند. این بدان معناست که شما میتوانید از نظر تئوری یک ماژول سطح بالای منفرد را که فقط از گزارههای import
ثابت تشکیل شده است، به ماژولهای دیگر بارگذاری کنید، و هر ماژول بارگیری شده یک درخواست شبکه و وظیفه جداگانه برای ارزیابی آن متحمل میشود.
اسکریپت های بارگیری شده با import()
Dynamic import()
روش دیگری برای بارگذاری اسکریپت ها است. برخلاف دستورهای import
static که لازم است در بالای یک ماژول ES قرار گیرند، یک فراخوانی import()
پویا میتواند در هر جایی از یک اسکریپت ظاهر شود تا تکهای از جاوا اسکریپت را در صورت درخواست بارگیری کند. به این تکنیک تقسیم کد می گویند.
Dynamic import()
در بهبود INP دو مزیت دارد:
- ماژول هایی که بارگذاری آنها به تعویق افتاده است، با کاهش مقدار جاوا اسکریپت بارگذاری شده در آن زمان، اختلاف موضوع اصلی در هنگام راه اندازی را کاهش می دهند. این موضوع رشته اصلی را آزاد می کند تا بتواند به تعاملات کاربر پاسخگوتر باشد.
- هنگامی که فراخوانی های
import()
پویا انجام می شود، هر فراخوانی به طور موثر کامپایل و ارزیابی هر ماژول را به وظیفه خود جدا می کند. البته، یکimport()
پویا که یک ماژول بسیار بزرگ را بارگذاری میکند، یک کار ارزیابی اسکریپت نسبتاً بزرگ را آغاز میکند، و در صورتی که تعامل همزمان با فراخوانیimport()
دینامیک اتفاق بیفتد، میتواند در توانایی رشته اصلی برای پاسخ دادن به ورودی کاربر اختلال ایجاد کند. بنابراین، هنوز هم بسیار مهم است که جاوا اسکریپت کمتری را که ممکن است بارگیری کنید.
فراخوانی Dynamic import()
در تمام موتورهای مرورگر اصلی به طور یکسان عمل می کند: وظایف ارزیابی اسکریپت که نتیجه می شود با مقدار ماژول هایی که به صورت پویا وارد می شوند یکسان خواهد بود.
اسکریپت های بارگذاری شده در وب کارگر
کارمندان وب یک مورد خاص استفاده از جاوا اسکریپت هستند. کارگران وب روی رشته اصلی ثبت میشوند و کد درون worker روی رشته خودش اجرا میشود. این بسیار سودمند است به این معنا که - در حالی که کدی که وبکارگر را ثبت میکند روی رشته اصلی اجرا میشود - کد داخل وبکارگر اینطور نیست. این کار تراکم نخ اصلی را کاهش میدهد و میتواند به پاسخگویی بیشتر رشته اصلی به تعاملات کاربر کمک کند.
علاوه بر کاهش کار رشته اصلی، کارگران وب خود میتوانند اسکریپتهای خارجی را برای استفاده در زمینه کارگر بارگذاری کنند، یا از طریق importScripts
یا عبارات import
ثابت در مرورگرهایی که کارگران ماژول را پشتیبانی میکنند. نتیجه این است که هر اسکریپت درخواست شده توسط یک وب کارگر از موضوع اصلی ارزیابی می شود.
مبادلات و ملاحظات
در حالی که تقسیم کردن اسکریپتهای خود به فایلهای جداگانه و کوچکتر به محدود کردن وظایف طولانیتر به جای بارگیری فایلهای کمتر و بسیار بزرگتر کمک میکند، مهم است که هنگام تصمیمگیری درباره نحوه شکستن اسکریپتها، مواردی را در نظر بگیرید.
راندمان فشرده سازی
فشرده سازی یک عامل در هنگام شکستن اسکریپت ها است. وقتی اسکریپت ها کوچکتر هستند، فشرده سازی تا حدودی کارآمدتر می شود. اسکریپت های بزرگتر از فشرده سازی سود بیشتری خواهند برد. در حالی که افزایش راندمان فشردهسازی کمک میکند تا زمان بارگذاری اسکریپتها تا حد ممکن پایین بماند، این یک عمل متعادل کننده است تا اطمینان حاصل شود که اسکریپتها را به اندازه کافی کوچکتر تقسیم میکنید تا تعامل بهتر در هنگام راهاندازی تسهیل شود.
باندلرها ابزارهای ایده آلی برای مدیریت اندازه خروجی برای اسکریپت هایی هستند که وب سایت شما به آنها بستگی دارد:
- در مورد بسته وب، افزونه
SplitChunksPlugin
آن می تواند کمک کند. برای دریافت گزینه هایی که می توانید برای کمک به مدیریت اندازه دارایی تنظیم کنید، با اسنادSplitChunksPlugin
مشورت کنید. - برای سایر بستهها مانند Rollup و esbuild ، میتوانید اندازه فایلهای اسکریپت را با استفاده از فراخوانیهای
import()
پویا در کد خود مدیریت کنید. این بستهها - و همچنین بسته وب - بهطور خودکار داراییهای وارد شده بهصورت پویا را در فایل خود جدا میکنند، بنابراین از اندازههای بزرگتر بستههای اولیه جلوگیری میکنند.
عدم اعتبار کش
عدم اعتبار کش نقش مهمی در سرعت بارگیری صفحه در بازدیدهای مکرر دارد. هنگامی که بستههای اسکریپت بزرگ و یکپارچه را ارسال میکنید، در مورد ذخیرهسازی مرورگر در مضیقه هستید. این به این دلیل است که وقتی کد شخص اول خود را بهروزرسانی میکنید - چه از طریق بهروزرسانی بستهها یا رفع اشکال حمل و نقل - کل بسته نرم افزاری باطل میشود و باید دوباره دانلود شود.
با جدا کردن اسکریپتهای خود، نه تنها کار ارزیابی اسکریپت را در وظایف کوچکتر تقسیم میکنید، بلکه این احتمال را نیز افزایش میدهید که بازدیدکنندگان بازگشتی اسکریپتهای بیشتری را از حافظه پنهان مرورگر به جای از شبکه بگیرند. این به بارگذاری کلی صفحه سریعتر ترجمه می شود.
ماژول های تو در تو و عملکرد بارگذاری
اگر ماژولهای ES را در مرحله تولید ارسال میکنید و آنها را با ویژگی type=module
بارگیری میکنید، باید از نحوه تأثیرگذاری تودرتوی ماژولها بر زمان راهاندازی آگاه باشید. تودرتوی ماژول به زمانی اشاره دارد که یک ماژول ES به صورت ایستا ماژول ES دیگری را وارد می کند که به صورت ایستا ماژول ES دیگری را وارد می کند:
// a.js
import {b} from './b.js';
// b.js
import {c} from './c.js';
اگر ماژولهای ES شما با هم ترکیب نشده باشند، کد قبلی منجر به یک زنجیره درخواست شبکه میشود: وقتی a.js
از عنصر <script>
درخواست میشود، درخواست شبکه دیگری برای b.js
ارسال میشود که سپس درخواست دیگری برای c.js
را شامل میشود. یکی از راههای جلوگیری از این امر استفاده از باندلر است - اما مطمئن شوید که باندلر خود را به گونهای پیکربندی میکنید که اسکریپتها را برای گسترش کار ارزیابی اسکریپت تجزیه کنید.
اگر نمیخواهید از یک بستهکننده استفاده کنید، راه دیگری برای دور زدن تماسهای ماژول تودرتو، استفاده از اشاره منبع modulepreload
است که برای جلوگیری از زنجیره درخواست شبکه، ماژولهای ES را زودتر بارگیری میکند.
نتیجه گیری
بهینه سازی ارزیابی اسکریپت ها در مرورگر بدون شک یک شاهکار دشوار است. رویکرد به الزامات و محدودیت های وب سایت شما بستگی دارد. با این حال، با تقسیم کردن اسکریپتها، کار ارزیابی اسکریپت را روی بسیاری از وظایف کوچکتر پخش میکنید، و بنابراین به رشته اصلی این توانایی را میدهید که به جای مسدود کردن رشته اصلی، تعاملات کاربر را به طور مؤثرتری مدیریت کند.
برای جمع بندی، در اینجا چند کار وجود دارد که می توانید برای تجزیه وظایف ارزیابی اسکریپت بزرگ انجام دهید:
- هنگام بارگیری اسکریپت ها با استفاده از عنصر
<script>
بدون ویژگیtype=module
، از بارگیری اسکریپت هایی که بسیار بزرگ هستند خودداری کنید، زیرا این کارها وظایف ارزیابی اسکریپت با منابع فشرده را آغاز می کنند که رشته اصلی را مسدود می کند. اسکریپتهای خود را روی عناصر<script>
بیشتری پخش کنید تا این کار را تجزیه کنید. - استفاده از ویژگی
type=module
برای بارگیری ماژول های ES به صورت بومی در مرورگر، وظایف فردی را برای ارزیابی برای هر اسکریپت ماژول جداگانه آغاز می کند. - با استفاده از فراخوانی dynamic
import()
اندازه بستههای اولیه خود را کاهش دهید. این همچنین در باندلرها کار می کند، زیرا باندلرها با هر ماژول وارد شده به صورت پویا به عنوان یک "نقطه تقسیم" رفتار می کنند و در نتیجه یک اسکریپت جداگانه برای هر ماژول وارد شده به صورت پویا تولید می شود. - مطمئن شوید که مبادلاتی مانند راندمان فشرده سازی و باطل کردن حافظه پنهان را در نظر بگیرید. اسکریپتهای بزرگتر بهتر فشرده میشوند، اما احتمالاً کار ارزیابی اسکریپت گرانتری را در وظایف کمتری شامل میشوند و منجر به بیاعتبار کردن حافظه پنهان مرورگر میشوند که منجر به راندمان کلی ذخیرهسازی پایینتر میشود.
- اگر از ماژولهای ES به صورت بومی و بدون بستهبندی استفاده میکنید، از راهنمایی منبع
modulepreload
برای بهینهسازی بارگذاری آنها در هنگام راهاندازی استفاده کنید. - مثل همیشه، تا حد امکان جاوا اسکریپت کمتری ارسال کنید.
مطمئناً این یک عمل متعادل کننده است - اما با شکستن اسکریپت ها و کاهش بارهای اولیه با import()
پویا، می توانید به عملکرد راه اندازی بهتری دست پیدا کنید و تعاملات کاربر را در طول آن دوره راه اندازی حیاتی انجام دهید. این باید به شما کمک کند در معیار INP امتیاز بهتری کسب کنید و در نتیجه تجربه کاربری بهتری را ارائه دهید.
هنگام بارگذاری اسکریپت ها، مرورگر برای ارزیابی آنها قبل از اجرا زمان می برد که می تواند باعث انجام کارهای طولانی شود. بیاموزید که ارزیابی اسکریپت چگونه کار می کند، و چه کاری می توانید انجام دهید تا از ایجاد کارهای طولانی در حین بارگذاری صفحه جلوگیری کنید.
وقتی صحبت از بهینهسازی Interaction to Next Paint (INP) میشود، بیشتر توصیههایی که با آن مواجه میشوید این است که خود تعاملات را بهینه کنید. به عنوان مثال، در راهنمای بهینه سازی وظایف طولانی ، تکنیک هایی مانند تسلیم شدن با setTimeout
و موارد دیگر مورد بحث قرار گرفته است. این تکنیکها سودمند هستند، زیرا با اجتناب از کارهای طولانی، به نخ اصلی اجازه میدهند تا فضای تنفسی داشته باشد، که میتواند فرصتهای بیشتری را برای تعاملات و سایر فعالیتها فراهم کند تا زودتر اجرا شوند، نه اینکه مجبور باشند برای یک کار طولانی منتظر بمانند.
با این حال، در مورد وظایف طولانی که از بارگذاری خود اسکریپت ها به وجود می آیند، چه می توان گفت؟ این کارها می توانند با تعاملات کاربر تداخل داشته باشند و بر INP صفحه در هنگام بارگذاری تأثیر بگذارند. این راهنما بررسی میکند که مرورگرها چگونه وظایفی را که با ارزیابی اسکریپت آغاز میشوند، انجام میدهند و به بررسی کارهایی که ممکن است بتوانید برای تجزیه کار ارزیابی اسکریپت انجام دهید، میپردازد تا موضوع اصلی شما بتواند در هنگام بارگیری صفحه به ورودی کاربر پاسخگوتر باشد.
ارزیابی فیلمنامه چیست؟
اگر برنامهای را که جاوا اسکریپت زیادی ارسال میکند پروفایل کردهاید، ممکن است کارهای طولانی را دیده باشید که مجرم با برچسب ارزیابی اسکریپت است.

ارزیابی اسکریپت بخشی ضروری از اجرای جاوا اسکریپت در مرورگر است، زیرا جاوا اسکریپت به موقع قبل از اجرا کامپایل می شود. هنگامی که یک اسکریپت ارزیابی می شود، ابتدا برای خطاها تجزیه می شود. اگر تجزیه کننده خطاها را پیدا نکرد، اسکریپت سپس در بایت کد کامپایل می شود و سپس می تواند به اجرا ادامه دهد.
اگرچه لازم است، ارزیابی اسکریپت می تواند مشکل ساز باشد، زیرا کاربران ممکن است سعی کنند با یک صفحه در مدت کوتاهی پس از ارائه اولیه آن تعامل داشته باشند. با این حال، فقط به این دلیل که یک صفحه رندر شده است به این معنی نیست که بارگیری صفحه تمام شده است. فعل و انفعالاتی که در حین بارگذاری انجام می شود می تواند به تاخیر بیفتد زیرا صفحه مشغول ارزیابی اسکریپت ها است. در حالی که هیچ تضمینی وجود ندارد که تعاملی در این مقطع زمانی انجام شود - زیرا ممکن است یک اسکریپت مسئول آن هنوز بارگیری نشده باشد - ممکن است تعاملاتی وابسته به جاوا اسکریپت وجود داشته باشد که آماده هستند یا اینکه تعامل اصلاً به جاوا اسکریپت بستگی ندارد.
رابطه بین اسکریپت ها و وظایفی که آنها را ارزیابی می کند
اینکه چگونه وظایفی که مسئول ارزیابی اسکریپت هستند، به این بستگی دارد که آیا اسکریپتی که بارگیری می کنید با یک عنصر معمولی <script>
بارگذاری شده است یا اینکه اسکریپت یک ماژول بارگذاری شده با type=module
است. از آنجایی که مرورگرها تمایل دارند مسائل را به گونهای متفاوت مدیریت کنند، نحوه انجام ارزیابی اسکریپت توسط موتورهای مرورگر اصلی در جایی که رفتارهای ارزیابی اسکریپت در آنها متفاوت است، مورد بررسی قرار خواهد گرفت.
اسکریپت های بارگذاری شده با عنصر <script>
تعداد وظایفی که برای ارزیابی اسکریپت ها ارسال می شود معمولاً با تعداد عناصر <script>
در یک صفحه رابطه مستقیم دارد. هر عنصر <script>
یک کار را برای ارزیابی اسکریپت درخواستی آغاز می کند تا بتوان آن را تجزیه، کامپایل و اجرا کرد. این مورد برای مرورگرهای مبتنی بر Chromium، Safari و Firefox است.
چرا این مهم است؟ فرض کنید از یک بستهکننده برای مدیریت اسکریپتهای تولید خود استفاده میکنید، و آن را طوری پیکربندی کردهاید که همه چیزهایی که صفحه شما برای اجرا شدن نیاز دارد در یک اسکریپت واحد قرار دهد. اگر این مورد برای وب سایت شما باشد، می توانید انتظار داشته باشید که یک وظیفه برای ارزیابی آن اسکریپت ارسال شود. آیا این چیز بدی است؟ نه لزوما - مگر اینکه آن اسکریپت بزرگ باشد.
میتوانید کار ارزیابی اسکریپت را با اجتناب از بارگیری تکههای بزرگ جاوا اسکریپت جدا کنید و اسکریپتهای فردی و کوچکتر را با استفاده از عناصر <script>
اضافی بارگیری کنید.
در حالی که همیشه باید تلاش کنید تا جاوا اسکریپت کمتری را در طول بارگذاری صفحه بارگیری کنید، تقسیم اسکریپت های خود تضمین می کند که به جای یک کار بزرگ که ممکن است رشته اصلی را مسدود کند، تعداد بیشتری کار کوچکتر دارید که به هیچ وجه رشته اصلی را مسدود نمی کند - یا حداقل کمتر از آنچه که با آن شروع کرده اید.

<script>
متعدد موجود در HTML صفحه ایجاد می شوند. این به ارسال یک بسته اسکریپت بزرگ برای کاربران ترجیح داده می شود، که احتمال بیشتری دارد تا رشته اصلی را مسدود کند.میتوانید تقسیم وظایف برای ارزیابی اسکریپت را تا حدودی شبیه به تسلیم شدن در طول تماسهای رویدادی که در طول یک تعامل اجرا میشوند، در نظر بگیرید. با این حال، با ارزیابی اسکریپت، مکانیسم بازده، جاوا اسکریپتی را که بارگذاری میکنید به چند اسکریپت کوچکتر تقسیم میکند، به جای تعداد کمتری از اسکریپتهای بزرگتر که احتمال مسدود کردن رشته اصلی وجود دارد.
اسکریپت های بارگذاری شده با عنصر <script>
و ویژگی type=module
اکنون می توان ماژول های ES را به صورت بومی در مرورگر با ویژگی type=module
در عنصر <script>
بارگیری کرد. این رویکرد برای بارگذاری اسکریپت دارای برخی از مزایای تجربه توسعهدهنده است، مانند عدم نیاز به تغییر کد برای استفاده در تولید - بهویژه زمانی که در ترکیب با نقشههای وارداتی استفاده میشود. با این حال، بارگیری اسکریپت ها به این روش، وظایفی را که از مرورگر به مرورگر متفاوت است، زمان بندی می کند.
مرورگرهای مبتنی بر کروم
در مرورگرهایی مانند کروم - یا مرورگرهای مشتق شده از آن - بارگیری ماژولهای ES با استفاده از ویژگی type=module
انواع مختلفی از وظایف را ایجاد میکند که معمولاً هنگام عدم استفاده از type=module
مشاهده میکنید. به عنوان مثال، یک کار برای هر اسکریپت ماژول اجرا می شود که شامل فعالیتی است که به عنوان ماژول کامپایل برچسب گذاری شده است.

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

اثر اینجا - حداقل در کروم و مرورگرهای مرتبط - این است که مراحل کامپایل هنگام استفاده از ماژولهای ES شکسته میشوند. این یک پیروزی آشکار از نظر مدیریت وظایف طولانی است. با این حال، کار ارزیابی ماژول حاصل که نتیجه میشود همچنان به این معنی است که شما هزینههای غیرقابل اجتنابی را متحمل میشوید. در حالی که باید تلاش کنید تا جاوا اسکریپت کمتری ارسال کنید، استفاده از ماژول های ES - صرف نظر از مرورگر - مزایای زیر را ارائه می دهد:
- همه کدهای ماژول به طور خودکار در حالت سخت اجرا می شوند، که امکان بهینه سازی های بالقوه توسط موتورهای جاوا اسکریپت را فراهم می کند که در غیر این صورت نمی توانند در یک زمینه غیر دقیق انجام شوند.
- اسکریپت هایی که با استفاده از
type=module
بارگذاری می شوند، به گونه ای رفتار می شوند که گویی به طور پیش فرض به تعویق افتاده اند. برای تغییر این رفتار می توان از ویژگیasync
در اسکریپت های بارگذاری شده باtype=module
استفاده کرد.
سافاری و فایرفاکس
هنگامی که ماژول ها در سافاری و فایرفاکس بارگذاری می شوند، هر یک از آنها در یک کار جداگانه ارزیابی می شوند. این بدان معناست که شما میتوانید از نظر تئوری یک ماژول سطح بالای منفرد را که فقط از گزارههای import
ثابت تشکیل شده است، به ماژولهای دیگر بارگذاری کنید، و هر ماژول بارگیری شده یک درخواست شبکه و وظیفه جداگانه برای ارزیابی آن متحمل میشود.
اسکریپت های بارگیری شده با import()
Dynamic import()
روش دیگری برای بارگذاری اسکریپت ها است. برخلاف دستورهای import
static که لازم است در بالای یک ماژول ES قرار گیرند، یک فراخوانی import()
پویا میتواند در هر جایی از یک اسکریپت ظاهر شود تا تکهای از جاوا اسکریپت را در صورت درخواست بارگیری کند. به این تکنیک تقسیم کد می گویند.
Dynamic import()
در بهبود INP دو مزیت دارد:
- ماژول هایی که بارگذاری آنها به تعویق افتاده است، با کاهش مقدار جاوا اسکریپت بارگذاری شده در آن زمان، اختلاف موضوع اصلی در هنگام راه اندازی را کاهش می دهند. این موضوع رشته اصلی را آزاد می کند تا بتواند به تعاملات کاربر پاسخگوتر باشد.
- هنگامی که فراخوانی های
import()
پویا انجام می شود، هر فراخوانی به طور موثر کامپایل و ارزیابی هر ماژول را به وظیفه خود جدا می کند. البته، یکimport()
پویا که یک ماژول بسیار بزرگ را بارگذاری میکند، یک کار ارزیابی اسکریپت نسبتاً بزرگ را آغاز میکند، و در صورتی که تعامل همزمان با فراخوانیimport()
دینامیک اتفاق بیفتد، میتواند در توانایی رشته اصلی برای پاسخ دادن به ورودی کاربر اختلال ایجاد کند. بنابراین، هنوز هم بسیار مهم است که جاوا اسکریپت کمتری را که ممکن است بارگیری کنید.
فراخوانی Dynamic import()
در تمام موتورهای مرورگر اصلی به طور یکسان عمل می کند: وظایف ارزیابی اسکریپت که نتیجه می شود با مقدار ماژول هایی که به صورت پویا وارد می شوند یکسان خواهد بود.
اسکریپت های بارگذاری شده در وب کارگر
کارمندان وب یک مورد خاص استفاده از جاوا اسکریپت هستند. کارگران وب روی رشته اصلی ثبت میشوند و کد درون worker روی رشته خودش اجرا میشود. این بسیار سودمند است به این معنا که - در حالی که کدی که وبکارگر را ثبت میکند روی رشته اصلی اجرا میشود - کد داخل وبکارگر اینطور نیست. این کار تراکم نخ اصلی را کاهش میدهد و میتواند به پاسخگویی بیشتر رشته اصلی به تعاملات کاربر کمک کند.
علاوه بر کاهش کار رشته اصلی، کارگران وب خود میتوانند اسکریپتهای خارجی را برای استفاده در زمینه کارگر بارگذاری کنند، یا از طریق importScripts
یا عبارات import
ثابت در مرورگرهایی که کارگران ماژول را پشتیبانی میکنند. نتیجه این است که هر اسکریپت درخواست شده توسط یک وب کارگر از موضوع اصلی ارزیابی می شود.
مبادلات و ملاحظات
در حالی که تقسیم کردن اسکریپتهای خود به فایلهای جداگانه و کوچکتر به محدود کردن وظایف طولانیتر به جای بارگیری فایلهای کمتر و بسیار بزرگتر کمک میکند، مهم است که هنگام تصمیمگیری درباره نحوه شکستن اسکریپتها، مواردی را در نظر بگیرید.
راندمان فشرده سازی
فشرده سازی یک عامل در هنگام شکستن اسکریپت ها است. وقتی اسکریپت ها کوچکتر هستند، فشرده سازی تا حدودی کارآمدتر می شود. اسکریپت های بزرگتر از فشرده سازی سود بیشتری خواهند برد. در حالی که افزایش راندمان فشردهسازی کمک میکند تا زمان بارگذاری اسکریپتها تا حد ممکن پایین بماند، این یک عمل متعادل کننده است تا اطمینان حاصل شود که اسکریپتها را به اندازه کافی کوچکتر تقسیم میکنید تا تعامل بهتر در هنگام راهاندازی تسهیل شود.
باندلرها ابزارهای ایده آلی برای مدیریت اندازه خروجی برای اسکریپت هایی هستند که وب سایت شما به آنها بستگی دارد:
- در مورد بسته وب، افزونه
SplitChunksPlugin
آن می تواند کمک کند. برای دریافت گزینه هایی که می توانید برای کمک به مدیریت اندازه دارایی تنظیم کنید، با اسنادSplitChunksPlugin
مشورت کنید. - برای سایر بستهها مانند Rollup و esbuild ، میتوانید اندازه فایلهای اسکریپت را با استفاده از فراخوانیهای
import()
پویا در کد خود مدیریت کنید. این بستهها - و همچنین بسته وب - بهطور خودکار داراییهای وارد شده بهصورت پویا را در فایل خود جدا میکنند، بنابراین از اندازههای بزرگتر بستههای اولیه جلوگیری میکنند.
عدم اعتبار کش
عدم اعتبار کش نقش مهمی در سرعت بارگیری صفحه در بازدیدهای مکرر دارد. هنگامی که بستههای اسکریپت بزرگ و یکپارچه را ارسال میکنید، در مورد ذخیرهسازی مرورگر در مضیقه هستید. این به این دلیل است که وقتی کد شخص اول خود را بهروزرسانی میکنید - چه از طریق بهروزرسانی بستهها یا رفع اشکال حمل و نقل - کل بسته نرم افزاری باطل میشود و باید دوباره دانلود شود.
با جدا کردن اسکریپتهای خود، نه تنها کار ارزیابی اسکریپت را در وظایف کوچکتر تقسیم میکنید، بلکه این احتمال را نیز افزایش میدهید که بازدیدکنندگان بازگشتی اسکریپتهای بیشتری را از حافظه پنهان مرورگر به جای از شبکه بگیرند. این به بارگذاری کلی صفحه سریعتر ترجمه می شود.
ماژول های تو در تو و عملکرد بارگذاری
اگر ماژولهای ES را در مرحله تولید ارسال میکنید و آنها را با ویژگی type=module
بارگیری میکنید، باید از نحوه تأثیرگذاری تودرتوی ماژولها بر زمان راهاندازی آگاه باشید. تودرتوی ماژول به زمانی اشاره دارد که یک ماژول ES به صورت ایستا ماژول ES دیگری را وارد می کند که به صورت ایستا ماژول ES دیگری را وارد می کند:
// a.js
import {b} from './b.js';
// b.js
import {c} from './c.js';
اگر ماژولهای ES شما با هم ترکیب نشده باشند، کد قبلی منجر به یک زنجیره درخواست شبکه میشود: وقتی a.js
از عنصر <script>
درخواست میشود، درخواست شبکه دیگری برای b.js
ارسال میشود که سپس درخواست دیگری برای c.js
را شامل میشود. یکی از راههای جلوگیری از این امر استفاده از باندلر است - اما مطمئن شوید که باندلر خود را به گونهای پیکربندی میکنید که اسکریپتها را برای گسترش کار ارزیابی اسکریپت تجزیه کنید.
اگر نمیخواهید از یک بستهکننده استفاده کنید، راه دیگری برای دور زدن تماسهای ماژول تودرتو، استفاده از اشاره منبع modulepreload
است که برای جلوگیری از زنجیره درخواست شبکه، ماژولهای ES را زودتر بارگیری میکند.
نتیجه گیری
بهینه سازی ارزیابی اسکریپت ها در مرورگر بدون شک یک شاهکار دشوار است. رویکرد به الزامات و محدودیت های وب سایت شما بستگی دارد. با این حال، با تقسیم کردن اسکریپتها، کار ارزیابی اسکریپت را روی بسیاری از وظایف کوچکتر پخش میکنید، و بنابراین به رشته اصلی این توانایی را میدهید که به جای مسدود کردن رشته اصلی، تعاملات کاربر را به طور مؤثرتری مدیریت کند.
برای جمع بندی، در اینجا چند کار وجود دارد که می توانید برای تجزیه وظایف ارزیابی اسکریپت بزرگ انجام دهید:
- هنگام بارگیری اسکریپت ها با استفاده از عنصر
<script>
بدون ویژگیtype=module
، از بارگیری اسکریپت هایی که بسیار بزرگ هستند ، خودداری کنید ، زیرا این موارد وظایف ارزیابی اسکریپت با منابع پر فشار را که مسدود کردن موضوع اصلی است ، شروع می کنند. برای شکستن این کار ، اسکریپت های خود را بر روی عناصر بیشتر<script>
پخش کنید. - با استفاده از ویژگی
type=module
برای بارگذاری ماژول های ES به صورت بومی در مرورگر ، کارهای فردی را برای ارزیابی برای هر اسکریپت ماژول جداگانه شروع می کند. - با استفاده از تماس های پویا
import()
اندازه بسته های اولیه خود را کاهش دهید. این همچنین در Bundlers کار می کند ، زیرا Bundlers هر ماژول وارداتی پویا را به عنوان "نقطه تقسیم" درمان می کند ، و در نتیجه یک اسکریپت جداگانه برای هر ماژول پویا وارداتی ایجاد می شود. - حتماً از معاملات مانند راندمان فشرده سازی و عدم اعتبار در حافظه نهان استفاده کنید. اسکریپت های بزرگتر بهتر فشرده می شوند ، اما به احتمال زیاد شامل کار ارزیابی اسکریپت گران تر در کارهای کمتری هستند و منجر به بی اعتبار شدن حافظه نهان مرورگر می شوند و منجر به کارایی کلی حافظه پنهان می شوند.
- اگر از ماژول های ES به صورت بومی بدون بسته بندی استفاده می کنید ، از
modulepreload
Resource استفاده کنید تا بارگذاری آنها در هنگام راه اندازی بهینه شود. - مثل همیشه ، تا حد ممکن جاوا اسکریپت را حمل کنید.
این یک عمل متعادل مطمئناً است - اما با شکستن اسکریپت ها و کاهش بارهای اولیه با import()
، می توانید به عملکرد بهتر راه اندازی دست پیدا کنید و در آن دوره شروع کار مهم ، تعامل کاربر را بهتر کند. این به شما کمک می کند تا در متریک INP بهتر نمره کسب کنید ، بنابراین تجربه کاربری بهتری را ارائه می دهید.
هنگام بارگیری اسکریپت ها ، زمان لازم است که مرورگر قبل از اجرای آنها را ارزیابی کند ، که می تواند باعث انجام کارهای طولانی شود. بیاموزید که چگونه ارزیابی اسکریپت کار می کند ، و چه کاری می توانید انجام دهید تا از ایجاد کارهای طولانی در هنگام بار صفحه جلوگیری کنید.
وقتی نوبت بهینه سازی تعامل با رنگ بعدی (INP) می رسد ، بیشتر توصیه هایی که با آنها روبرو خواهید شد ، بهینه سازی تعامل خود است. به عنوان مثال ، در راهنمای بهینه سازی وظایف طولانی ، تکنیک هایی مانند عملکرد با setTimeout
و دیگران مورد بحث قرار می گیرد. این تکنیک ها مفید هستند ، زیرا با اجتناب از کارهای طولانی ، موضوع اصلی اتاق تنفس را به آنها امکان می دهد ، که می تواند فرصت های بیشتری را برای تعامل و فعالیت های دیگر زودتر انجام دهد ، به جای اینکه اگر مجبور بودند منتظر یک کار طولانی باشند.
با این حال ، در مورد کارهای طولانی که از بارگیری خود اسکریپت ها ناشی می شود چیست؟ این وظایف می تواند در تعامل کاربر تداخل داشته و در هنگام بار تأثیر INP یک صفحه را تحت تأثیر قرار دهد. این راهنما چگونگی انجام مرورگرها با ارزیابی اسکریپت را بررسی می کند ، و به آنچه می توانید برای تجزیه کار ارزیابی اسکریپت انجام دهید ، بررسی کنید تا در حالی که صفحه در حال بارگیری است ، موضوع اصلی شما می تواند نسبت به ورودی کاربر پاسخگوتر باشد.
ارزیابی اسکریپت چیست؟
اگر برنامه ای را که JavaScript زیادی ارسال می کند ، پروفایل کرده اید ، ممکن است کارهای طولانی را مشاهده کرده باشید که در آن مقصر برچسب ارزیابی اسکریپت است.

ارزیابی اسکریپت بخش لازم برای اجرای JavaScript در مرورگر است ، زیرا JavaScript قبل از اجرای آن فقط به موقع گردآوری می شود. هنگامی که یک اسکریپت ارزیابی می شود ، برای اولین بار برای خطاها تجزیه می شود. اگر پارسر خطایی پیدا نکند ، اسکریپت سپس به صورت بایت تهیه می شود و سپس می تواند به اجرای آن ادامه یابد.
گرچه لازم است ، ارزیابی اسکریپت می تواند مشکل ساز باشد ، زیرا کاربران ممکن است اندکی پس از آن که در ابتدا ارائه می شود ، سعی کنند با یک صفحه ارتباط برقرار کنند. با این حال ، فقط به این دلیل که یک صفحه ارائه شده است به این معنی نیست که صفحه بارگیری به پایان رسیده است. تعامل هایی که در هنگام بار انجام می شود می تواند به تأخیر بیفتد زیرا صفحه مشغول ارزیابی اسکریپت ها است. در حالی که هیچ تضمینی وجود ندارد که تعامل در این مقطع زمانی انجام شود - به عنوان یک اسکریپت که ممکن است هنوز بارگیری نشده باشد - می تواند تعامل وابسته به جاوا اسکریپت که آماده است ، وجود داشته باشد ، یا تعامل به هیچ وجه به جاوا اسکریپت بستگی ندارد.
رابطه بین اسکریپت ها و کارهایی که آنها را ارزیابی می کند
نحوه انجام وظایف مسئول ارزیابی اسکریپت ، بستگی به این دارد که آیا اسکریپتی که بارگیری می کنید با یک عنصر معمولی <script>
بارگذاری شده است ، یا اینکه اسکریپت ماژول ای است که با type=module
بارگذاری شده است. از آنجا که مرورگرها تمایل به رسیدگی به امور مختلف دارند ، چگونه موتورهای مهم مرورگر ارزیابی اسکریپت را به این نتیجه می رسانند که رفتارهای ارزیابی اسکریپت در سراسر آنها متفاوت است.
اسکریپت های بارگذاری شده با عنصر <script>
تعداد وظایف ارسال شده برای ارزیابی اسکریپت ها به طور کلی با تعداد عناصر <script>
در یک صفحه رابطه مستقیمی دارد. هر عنصر <script>
یک کار را برای ارزیابی اسکریپت درخواست شده انجام می دهد تا بتواند تجزیه ، تدوین و اجرا شود. این مورد در مورد مرورگرهای مبتنی بر کروم ، سافاری و فایرفاکس است.
چرا این مهم است؟ بگویید که برای مدیریت اسکریپت های تولیدی خود از یک دستهر استفاده می کنید ، و آن را پیکربندی کرده اید تا همه چیزهایی را که صفحه شما برای اجرای یک اسکریپت واحد نیاز دارد ، جمع کند. اگر این مورد برای وب سایت شما باشد ، می توانید انتظار داشته باشید که یک کار واحد برای ارزیابی آن اسکریپت انجام شود. آیا این چیز بدی است؟ لزوماً - مگر اینکه این فیلمنامه بسیار زیاد باشد.
شما می توانید با جلوگیری از بارگذاری تکه های بزرگ JavaScript ، کار ارزیابی اسکریپت را تجزیه کنید و اسکریپت های فردی و کوچکتر را با استفاده از عناصر <script>
اضافی بارگذاری کنید.
در حالی که همیشه باید در طول بار صفحه ، تا حد امکان جاوا اسکریپت را بارگیری کنید ، تقسیم اسکریپت های خود تضمین می کند که به جای یک کار بزرگ که ممکن است موضوع اصلی را مسدود کند ، شما تعداد بیشتری از کارهای کوچکتر را دارید که اصلاً موضوع اصلی را مسدود نمی کند - یا حداقل کمتر از آنچه که شروع کرده اید.

<script>
موجود در HTML صفحه ارائه شده است. این برای ارسال یک بسته نرم افزاری بزرگ به کاربران ارجح است که احتمالاً موضوع اصلی را مسدود می کند.شما می توانید به فکر شکستن وظایف برای ارزیابی اسکریپت باشید که تا حدودی شبیه به بازده در تماس های تلفنی است که در طول تعامل اجرا می شود . با این حال ، با ارزیابی اسکریپت ، مکانیسم بازده جاوا اسکریپت را که در چندین اسکریپت کوچکتر بارگذاری می کنید ، به جای تعداد کمتری از اسکریپت های بزرگتر از آن که بیشتر از این که موضوع اصلی را مسدود می کند ، شکسته می شود.
اسکریپت های بارگذاری شده با عنصر <script>
و ویژگی type=module
اکنون می توان ماژول های ES را به صورت بومی در مرورگر با ویژگی type=module
در عنصر <script>
بارگیری کرد. این رویکرد برای بارگیری اسکریپت برخی از مزایای تجربه توسعه دهنده را به همراه دارد ، از جمله عدم نیاز به تبدیل کد برای استفاده از تولید - خصوصاً در صورت استفاده در ترکیب با نقشه های وارداتی . با این حال ، بارگیری اسکریپت ها از این طریق وظایفی را که از مرورگر تا مرورگر متفاوت است ، برنامه ریزی می کند.
مرورگرهای مبتنی بر کروم
در مرورگرهایی مانند Chrome - یا آنهایی که از آن مشتق شده اند ، ماژول های ES را با استفاده از ویژگی type=module
انواع مختلفی از وظایف را از آنچه معمولاً هنگام استفاده از type=module
مشاهده نمی کنید ، تولید می کند. به عنوان مثال ، یک کار برای هر اسکریپت ماژول اجرا می شود که شامل فعالیت هایی با عنوان ماژول کامپایل است.

پس از گردآوری ماژول ها ، هر کدی که متعاقباً در آنها اجرا شود ، فعالیت هایی با عنوان ماژول ارزیابی را آغاز می کند.

تأثیر در اینجا - در کروم و مرورگرهای مرتبط ، حداقل - این است که مراحل تدوین هنگام استفاده از ماژول های ES شکسته می شود. این یک پیروزی واضح از نظر مدیریت کارهای طولانی است. با این حال ، کار ارزیابی ماژول حاصل که نتیجه می گیرد هنوز هم به این معنی است که شما در حال تحمل هزینه های اجتناب ناپذیر هستید. در حالی که شما باید تلاش کنید تا حد ممکن جاوا اسکریپت را حمل کنید ، با استفاده از ماژول های ES - صرف نظر از مرورگر - مزایای زیر را ارائه می دهد:
- تمام کد ماژول به طور خودکار در حالت سخت اجرا می شود ، که امکان بهینه سازی بالقوه موتورهای JavaScript را فراهم می کند که در غیر این صورت نمی توانند در یک زمینه غیر دقیق ساخته شوند.
- اسکریپت های بارگذاری شده با استفاده از
type=module
به گونه ای درمان می شوند که گویی به طور پیش فرض به تعویق می افتند. برای تغییر این رفتار می توان از ویژگیasync
در اسکریپت های بارگذاری شده باtype=module
استفاده کرد.
سافاری و فایرفاکس
هنگامی که ماژول ها در Safari و Firefox بارگیری می شوند ، هر یک از آنها در یک کار جداگانه ارزیابی می شوند. این بدان معناست که شما می توانید یک ماژول سطح بالا را که فقط از بیانیه های import
استاتیک به ماژول های دیگر متشکل است ، بارگذاری کنید ، و هر ماژول بارگذاری شده برای ارزیابی آن یک درخواست و کار جداگانه ای را متحمل می شود.
اسکریپت های پر از import()
import()
روش دیگری برای بارگیری اسکریپت ها است. بر خلاف اظهارات import
استاتیک که لازم است در صدر یک ماژول ES باشد ، یک تماس import()
می تواند در هر نقطه از یک اسکریپت ظاهر شود تا یک تکه جاوا اسکریپت را در صورت تقاضا بارگیری کند. این تکنیک را تقسیم کد می نامند.
import()
در مورد بهبود INP دو مزیت دارد:
- ماژول هایی که به تعویق می افتند برای بارگیری بعداً با کاهش میزان جاوا اسکریپت بارگذاری شده در آن زمان ، بحث اصلی نخ را کاهش می دهند. این موضوع اصلی را آزاد می کند تا بتواند نسبت به تعامل کاربر پاسخگوتر باشد.
- هنگامی که تماس های پویا
import()
برقرار می شود ، هر تماس به طور مؤثر ترکیب و ارزیابی هر ماژول را به کار خود جدا می کند. البته ، یکimport()
که یک ماژول بسیار بزرگ را بارگیری می کند ، یک کار ارزیابی اسکریپت نسبتاً بزرگ را آغاز می کند ، و اگر تعامل همزمان با تماس باimport()
باشد ، می تواند در توانایی موضوع اصلی برای پاسخ به ورودی کاربر تداخل داشته باشد. بنابراین ، هنوز هم بسیار مهم است که تا حد امکان جاوا اسکریپت را بارگیری کنید.
import()
تماس ها به طور مشابه در کلیه موتورهای اصلی مرورگر رفتار می کنند: وظایف ارزیابی اسکریپت که نتیجه آن همان میزان ماژول هایی است که به صورت پویا وارد می شوند.
اسکریپت های بارگذاری شده در یک کارگر وب
کارگران وب یک مورد خاص استفاده از جاوا اسکریپت هستند. کارگران وب در موضوع اصلی ثبت شده اند و کد موجود در کارگر سپس روی موضوع خود اجرا می شود. این بسیار سودمند است به این معنا که - در حالی که کدی که کارگر وب را ثبت می کند روی موضوع اصلی اجرا می شود - کد موجود در کارگر وب چنین نمی کند. این باعث کاهش احتقان اصلی موضوع می شود و می تواند به حفظ موضوع اصلی در تعامل کاربر کمک کند.
علاوه بر کاهش کار اصلی موضوع ، خود کارگران وب می توانند اسکریپت های خارجی را برای استفاده در زمینه کارگر ، از طریق importScripts
یا بیانیه import
استاتیک در مرورگرهایی که از کارگران ماژول پشتیبانی می کنند ، بارگیری کنند. نتیجه این است که هر اسکریپت درخواست شده توسط یک کارگر وب از موضوع اصلی ارزیابی می شود.
معاملات و ملاحظات
در حالی که اسکریپت های خود را در پرونده های جداگانه و جداگانه قرار می دهید ، به محدود کردن کارهای طولانی کمک می کند تا بر خلاف بارگیری پرونده های کمتر و بسیار بزرگتر ، مهم است که هنگام تصمیم گیری در مورد نحوه شکستن اسکریپت ها ، برخی موارد را در نظر بگیرید.
بازده فشرده سازی
فشرده سازی عاملی است که هنگام شکستن اسکریپت ها می آید. هنگامی که اسکریپت ها کوچکتر هستند ، فشرده سازی تا حدودی کارآمدتر می شود. اسکریپت های بزرگتر از فشرده سازی سود بیشتری خواهند برد. در حالی که افزایش راندمان فشرده سازی به نگه داشتن زمان بار برای اسکریپت ها تا حد ممکن کمک می کند ، این یک عمل متعادل کننده است تا اطمینان حاصل شود که اسکریپت ها را به اندازه کافی کوچکتر می شکنید تا تعامل بهتر در هنگام راه اندازی را تسهیل کنید.
Bundlers ابزارهای ایده آل برای مدیریت اندازه خروجی برای اسکریپت ها هستند که وب سایت شما به این بستگی دارد:
- در جایی که به صفحه وب مربوط می شود ، افزونه
SplitChunksPlugin
آن می تواند کمک کند. برای گزینه هایی که می توانید برای کمک به مدیریت اندازه دارایی تنظیم کنید ، با اسنادSplitChunksPlugin
مشورت کنید. - برای سایر بسته های مانند Rollup و Esbuild ، می توانید با استفاده از تماس های پویا
import()
در کد خود ، اندازه پرونده های اسکریپت را مدیریت کنید. این دسته ها - و همچنین وب - به طور خودکار دارایی های پویا وارد شده را در پرونده خود خراب می کنند ، بنابراین از اندازه بسته های اولیه بزرگتر جلوگیری می کنند.
عدم اعتبار کش
بی اعتبار بودن حافظه نهان نقش مهمی در سرعت بارگذاری یک صفحه در بازدیدهای مکرر دارد. هنگامی که بسته های اسکریپت بزرگ و یکپارچه را حمل می کنید ، وقتی صحبت از مرورگر می شود ، دچار ضرر می شوید. این امر به این دلیل است که وقتی کد شخص اول خود را به روز می کنید-یا از طریق به روزرسانی بسته ها یا رفع اشکالات حمل و نقل ، کل بسته نرم افزاری بی اعتبار می شود و باید دوباره بارگیری شود.
با شکستن اسکریپت های خود ، شما فقط کار ارزیابی اسکریپت را در کارهای کوچکتر نمی شکنید ، این احتمال را نیز افزایش می دهید که بازدیدکنندگان به جای شبکه ، اسکریپت های بیشتری را از حافظه نهان مرورگر بدست آورند. این به یک بار سریعتر صفحه تبدیل می شود.
ماژول های تو در تو و عملکرد بارگذاری
اگر ماژول های ES را در تولید حمل می کنید و آنها را با ویژگی type=module
بارگیری می کنید ، باید از این که چگونه لانه سازی ماژول می تواند بر زمان راه اندازی تأثیر بگذارد ، آگاه باشید. لانه سازی ماژول به زمانی اشاره دارد که یک ماژول ES به صورت استاتیک ماژول ES دیگری را وارد می کند که به صورت آماری ماژول ES دیگری را وارد می کند:
// a.js
import {b} from './b.js';
// b.js
import {c} from './c.js';
اگر ماژول های ES شما با هم همراه نباشند ، کد قبلی منجر به زنجیره درخواست شبکه می شود: هنگامی که a.js
از یک عنصر <script>
درخواست می شود ، درخواست شبکه دیگری برای b.js
ارسال می شود ، که سپس درخواست دیگری برای c.js
می کند. یکی از راه های جلوگیری از این کار استفاده از یک دسته از دسته است ، اما مطمئن باشید که بسته بندی خود را برای شکستن اسکریپت ها برای پخش کردن کار ارزیابی اسکریپت پیکربندی می کنید.
اگر نمی خواهید از یک بستهر استفاده کنید ، پس راه دیگری برای تماس با ماژول های تو در تو در تو در تو استفاده از modulepreload
Resource Hint است که ماژول های ES را قبل از زمان برای جلوگیری از زنجیره های درخواست شبکه از قبل بارگیری می کند.
نتیجه گیری
بهینه سازی ارزیابی اسکریپت ها در مرورگر بدون شک یک شاهکار دشوار است. این رویکرد به نیازها و محدودیت های وب سایت شما بستگی دارد. با این حال ، با تقسیم اسکریپت ها ، شما در حال گسترش کار ارزیابی اسکریپت بر روی کارهای کوچکتر هستیم ، و بنابراین به موضوع اصلی امکان رسیدگی به تعامل کاربر را با کارآمدتر می دهد ، نه اینکه مسدود کردن موضوع اصلی باشد.
برای یادآوری ، در اینجا مواردی وجود دارد که می توانید برای شکستن کارهای بزرگ ارزیابی اسکریپت انجام دهید:
- هنگام بارگیری اسکریپت ها با استفاده از عنصر
<script>
بدون ویژگیtype=module
، از بارگیری اسکریپت هایی که بسیار بزرگ هستند ، خودداری کنید ، زیرا این موارد وظایف ارزیابی اسکریپت با منابع پر فشار را که مسدود کردن موضوع اصلی است ، شروع می کنند. برای شکستن این کار ، اسکریپت های خود را بر روی عناصر بیشتر<script>
پخش کنید. - با استفاده از ویژگی
type=module
برای بارگذاری ماژول های ES به صورت بومی در مرورگر ، کارهای فردی را برای ارزیابی برای هر اسکریپت ماژول جداگانه شروع می کند. - با استفاده از تماس های پویا
import()
اندازه بسته های اولیه خود را کاهش دهید. این همچنین در Bundlers کار می کند ، زیرا Bundlers هر ماژول وارداتی پویا را به عنوان "نقطه تقسیم" درمان می کند ، و در نتیجه یک اسکریپت جداگانه برای هر ماژول پویا وارداتی ایجاد می شود. - حتماً از معاملات مانند راندمان فشرده سازی و عدم اعتبار در حافظه نهان استفاده کنید. اسکریپت های بزرگتر بهتر فشرده می شوند ، اما به احتمال زیاد شامل کار ارزیابی اسکریپت گران تر در کارهای کمتری هستند و منجر به بی اعتبار شدن حافظه نهان مرورگر می شوند و منجر به کارایی کلی حافظه پنهان می شوند.
- اگر از ماژول های ES به صورت بومی بدون بسته بندی استفاده می کنید ، از
modulepreload
Resource استفاده کنید تا بارگذاری آنها در هنگام راه اندازی بهینه شود. - مثل همیشه ، تا حد ممکن جاوا اسکریپت را حمل کنید.
این یک عمل متعادل مطمئناً است - اما با شکستن اسکریپت ها و کاهش بارهای اولیه با import()
، می توانید به عملکرد بهتر راه اندازی دست پیدا کنید و در آن دوره شروع کار مهم ، تعامل کاربر را بهتر کند. این به شما کمک می کند تا در متریک INP بهتر نمره کسب کنید ، بنابراین تجربه کاربری بهتری را ارائه می دهید.
هنگام بارگیری اسکریپت ها ، زمان لازم است که مرورگر قبل از اجرای آنها را ارزیابی کند ، که می تواند باعث انجام کارهای طولانی شود. بیاموزید که چگونه ارزیابی اسکریپت کار می کند ، و چه کاری می توانید انجام دهید تا از ایجاد کارهای طولانی در هنگام بار صفحه جلوگیری کنید.
وقتی نوبت بهینه سازی تعامل با رنگ بعدی (INP) می رسد ، بیشتر توصیه هایی که با آنها روبرو خواهید شد ، بهینه سازی تعامل خود است. به عنوان مثال ، در راهنمای بهینه سازی وظایف طولانی ، تکنیک هایی مانند عملکرد با setTimeout
و دیگران مورد بحث قرار می گیرد. این تکنیک ها مفید هستند ، زیرا با اجتناب از کارهای طولانی ، موضوع اصلی اتاق تنفس را به آنها امکان می دهد ، که می تواند فرصت های بیشتری را برای تعامل و فعالیت های دیگر زودتر انجام دهد ، به جای اینکه اگر مجبور بودند منتظر یک کار طولانی باشند.
با این حال ، در مورد کارهای طولانی که از بارگیری خود اسکریپت ها ناشی می شود چیست؟ این وظایف می تواند در تعامل کاربر تداخل داشته و در هنگام بار تأثیر INP یک صفحه را تحت تأثیر قرار دهد. این راهنما چگونگی انجام مرورگرها با ارزیابی اسکریپت را بررسی می کند ، و به آنچه می توانید برای تجزیه کار ارزیابی اسکریپت انجام دهید ، بررسی کنید تا در حالی که صفحه در حال بارگیری است ، موضوع اصلی شما می تواند نسبت به ورودی کاربر پاسخگوتر باشد.
ارزیابی اسکریپت چیست؟
اگر برنامه ای را که JavaScript زیادی ارسال می کند ، پروفایل کرده اید ، ممکن است کارهای طولانی را مشاهده کرده باشید که در آن مقصر برچسب ارزیابی اسکریپت است.

ارزیابی اسکریپت بخش لازم برای اجرای JavaScript در مرورگر است ، زیرا JavaScript قبل از اجرای آن فقط به موقع گردآوری می شود. هنگامی که یک اسکریپت ارزیابی می شود ، برای اولین بار برای خطاها تجزیه می شود. اگر پارسر خطایی پیدا نکند ، اسکریپت سپس به صورت بایت تهیه می شود و سپس می تواند به اجرای آن ادامه یابد.
گرچه لازم است ، ارزیابی اسکریپت می تواند مشکل ساز باشد ، زیرا کاربران ممکن است اندکی پس از آن که در ابتدا ارائه می شود ، سعی کنند با یک صفحه ارتباط برقرار کنند. با این حال ، فقط به این دلیل که یک صفحه ارائه شده است به این معنی نیست که صفحه بارگیری به پایان رسیده است. تعامل هایی که در هنگام بار انجام می شود می تواند به تأخیر بیفتد زیرا صفحه مشغول ارزیابی اسکریپت ها است. در حالی که هیچ تضمینی وجود ندارد که تعامل در این مقطع زمانی انجام شود - به عنوان یک اسکریپت که ممکن است هنوز بارگیری نشده باشد - می تواند تعامل وابسته به جاوا اسکریپت که آماده است ، وجود داشته باشد ، یا تعامل به هیچ وجه به جاوا اسکریپت بستگی ندارد.
رابطه بین اسکریپت ها و کارهایی که آنها را ارزیابی می کند
نحوه انجام وظایف مسئول ارزیابی اسکریپت ، بستگی به این دارد که آیا اسکریپتی که بارگیری می کنید با یک عنصر معمولی <script>
بارگذاری شده است ، یا اینکه اسکریپت ماژول ای است که با type=module
بارگذاری شده است. از آنجا که مرورگرها تمایل به رسیدگی به امور مختلف دارند ، چگونه موتورهای مهم مرورگر ارزیابی اسکریپت را به این نتیجه می رسانند که رفتارهای ارزیابی اسکریپت در سراسر آنها متفاوت است.
اسکریپت های بارگذاری شده با عنصر <script>
تعداد وظایف ارسال شده برای ارزیابی اسکریپت ها به طور کلی با تعداد عناصر <script>
در یک صفحه رابطه مستقیمی دارد. هر عنصر <script>
یک کار را برای ارزیابی اسکریپت درخواست شده انجام می دهد تا بتواند تجزیه ، تدوین و اجرا شود. این مورد در مورد مرورگرهای مبتنی بر کروم ، سافاری و فایرفاکس است.
چرا این مهم است؟ بگویید که برای مدیریت اسکریپت های تولیدی خود از یک دستهر استفاده می کنید ، و آن را پیکربندی کرده اید تا همه چیزهایی را که صفحه شما برای اجرای یک اسکریپت واحد نیاز دارد ، جمع کند. اگر این مورد برای وب سایت شما باشد ، می توانید انتظار داشته باشید که یک کار واحد برای ارزیابی آن اسکریپت انجام شود. آیا این چیز بدی است؟ لزوماً - مگر اینکه این فیلمنامه بسیار زیاد باشد.
شما می توانید با جلوگیری از بارگذاری تکه های بزرگ JavaScript ، کار ارزیابی اسکریپت را تجزیه کنید و اسکریپت های فردی و کوچکتر را با استفاده از عناصر <script>
اضافی بارگذاری کنید.
در حالی که همیشه باید در طول بار صفحه ، تا حد امکان جاوا اسکریپت را بارگیری کنید ، تقسیم اسکریپت های خود تضمین می کند که به جای یک کار بزرگ که ممکن است موضوع اصلی را مسدود کند ، شما تعداد بیشتری از کارهای کوچکتر را دارید که اصلاً موضوع اصلی را مسدود نمی کند - یا حداقل کمتر از آنچه که شروع کرده اید.

<script>
موجود در HTML صفحه ارائه شده است. این برای ارسال یک بسته نرم افزاری بزرگ به کاربران ارجح است که احتمالاً موضوع اصلی را مسدود می کند.شما می توانید به فکر شکستن وظایف برای ارزیابی اسکریپت باشید که تا حدودی شبیه به بازده در تماس های تلفنی است که در طول تعامل اجرا می شود . با این حال ، با ارزیابی اسکریپت ، مکانیسم بازده جاوا اسکریپت را که در چندین اسکریپت کوچکتر بارگذاری می کنید ، به جای تعداد کمتری از اسکریپت های بزرگتر از آن که بیشتر از این که موضوع اصلی را مسدود می کند ، شکسته می شود.
اسکریپت های بارگذاری شده با عنصر <script>
و ویژگی type=module
اکنون می توان ماژول های ES را به صورت بومی در مرورگر با ویژگی type=module
در عنصر <script>
بارگیری کرد. این رویکرد برای بارگیری اسکریپت برخی از مزایای تجربه توسعه دهنده را به همراه دارد ، از جمله عدم نیاز به تبدیل کد برای استفاده از تولید - خصوصاً در صورت استفاده در ترکیب با نقشه های وارداتی . با این حال ، بارگیری اسکریپت ها از این طریق وظایفی را که از مرورگر تا مرورگر متفاوت است ، برنامه ریزی می کند.
مرورگرهای مبتنی بر کروم
در مرورگرهایی مانند Chrome - یا آنهایی که از آن مشتق شده اند ، ماژول های ES را با استفاده از ویژگی type=module
انواع مختلفی از وظایف را از آنچه معمولاً هنگام استفاده از type=module
مشاهده نمی کنید ، تولید می کند. به عنوان مثال ، یک کار برای هر اسکریپت ماژول اجرا می شود که شامل فعالیت هایی با عنوان ماژول کامپایل است.

پس از گردآوری ماژول ها ، هر کدی که متعاقباً در آنها اجرا شود ، فعالیت هایی با عنوان ماژول ارزیابی را آغاز می کند.

تأثیر در اینجا - در کروم و مرورگرهای مرتبط ، حداقل - این است که مراحل تدوین هنگام استفاده از ماژول های ES شکسته می شود. این یک پیروزی واضح از نظر مدیریت کارهای طولانی است. با این حال ، کار ارزیابی ماژول حاصل که نتیجه می گیرد هنوز هم به این معنی است که شما در حال تحمل هزینه های اجتناب ناپذیر هستید. در حالی که شما باید تلاش کنید تا حد ممکن جاوا اسکریپت را حمل کنید ، با استفاده از ماژول های ES - صرف نظر از مرورگر - مزایای زیر را ارائه می دهد:
- تمام کد ماژول به طور خودکار در حالت سخت اجرا می شود ، که امکان بهینه سازی بالقوه موتورهای JavaScript را فراهم می کند که در غیر این صورت نمی توانند در یک زمینه غیر دقیق ساخته شوند.
- اسکریپت های بارگذاری شده با استفاده از
type=module
به گونه ای درمان می شوند که گویی به طور پیش فرض به تعویق می افتند. برای تغییر این رفتار می توان از ویژگیasync
در اسکریپت های بارگذاری شده باtype=module
استفاده کرد.
سافاری و فایرفاکس
هنگامی که ماژول ها در Safari و Firefox بارگیری می شوند ، هر یک از آنها در یک کار جداگانه ارزیابی می شوند. این بدان معناست که شما می توانید یک ماژول سطح بالا را که فقط از بیانیه های import
استاتیک به ماژول های دیگر متشکل است ، بارگذاری کنید ، و هر ماژول بارگذاری شده برای ارزیابی آن یک درخواست و کار جداگانه ای را متحمل می شود.
اسکریپت های پر از import()
import()
روش دیگری برای بارگیری اسکریپت ها است. بر خلاف اظهارات import
استاتیک که لازم است در صدر یک ماژول ES باشد ، یک تماس import()
می تواند در هر نقطه از یک اسکریپت ظاهر شود تا یک تکه جاوا اسکریپت را در صورت تقاضا بارگیری کند. این تکنیک را تقسیم کد می نامند.
import()
در مورد بهبود INP دو مزیت دارد:
- ماژول هایی که به تعویق می افتند برای بارگیری بعداً با کاهش میزان جاوا اسکریپت بارگذاری شده در آن زمان ، بحث اصلی نخ را کاهش می دهند. این موضوع اصلی را آزاد می کند تا بتواند نسبت به تعامل کاربر پاسخگوتر باشد.
- هنگامی که تماس های پویا
import()
برقرار می شود ، هر تماس به طور مؤثر ترکیب و ارزیابی هر ماژول را به کار خود جدا می کند. البته ، یکimport()
که یک ماژول بسیار بزرگ را بارگیری می کند ، یک کار ارزیابی اسکریپت نسبتاً بزرگ را آغاز می کند ، و اگر تعامل همزمان با تماس باimport()
باشد ، می تواند در توانایی موضوع اصلی برای پاسخ به ورودی کاربر تداخل داشته باشد. بنابراین ، هنوز هم بسیار مهم است که تا حد امکان جاوا اسکریپت را بارگیری کنید.
import()
تماس ها به طور مشابه در کلیه موتورهای اصلی مرورگر رفتار می کنند: وظایف ارزیابی اسکریپت که نتیجه آن همان میزان ماژول هایی است که به صورت پویا وارد می شوند.
اسکریپت های بارگذاری شده در یک کارگر وب
کارگران وب یک مورد خاص استفاده از جاوا اسکریپت هستند. کارگران وب در موضوع اصلی ثبت شده اند و کد موجود در کارگر سپس روی موضوع خود اجرا می شود. این بسیار سودمند است به این معنا که - در حالی که کدی که کارگر وب را ثبت می کند روی موضوع اصلی اجرا می شود - کد موجود در کارگر وب چنین نمی کند. این باعث کاهش احتقان اصلی موضوع می شود و می تواند به حفظ موضوع اصلی در تعامل کاربر کمک کند.
علاوه بر کاهش کار اصلی موضوع ، خود کارگران وب می توانند اسکریپت های خارجی را برای استفاده در زمینه کارگر ، از طریق importScripts
یا بیانیه import
استاتیک در مرورگرهایی که از کارگران ماژول پشتیبانی می کنند ، بارگیری کنند. نتیجه این است که هر اسکریپت درخواست شده توسط یک کارگر وب از موضوع اصلی ارزیابی می شود.
معاملات و ملاحظات
در حالی که اسکریپت های خود را در پرونده های جداگانه و جداگانه قرار می دهید ، به محدود کردن کارهای طولانی کمک می کند تا بر خلاف بارگیری پرونده های کمتر و بسیار بزرگتر ، مهم است که هنگام تصمیم گیری در مورد نحوه شکستن اسکریپت ها ، برخی موارد را در نظر بگیرید.
بازده فشرده سازی
فشرده سازی عاملی است که هنگام شکستن اسکریپت ها می آید. هنگامی که اسکریپت ها کوچکتر هستند ، فشرده سازی تا حدودی کارآمدتر می شود. اسکریپت های بزرگتر از فشرده سازی سود بیشتری خواهند برد. در حالی که افزایش راندمان فشرده سازی به نگه داشتن زمان بار برای اسکریپت ها تا حد ممکن کمک می کند ، این یک عمل متعادل کننده است تا اطمینان حاصل شود که اسکریپت ها را به اندازه کافی کوچکتر می شکنید تا تعامل بهتر در هنگام راه اندازی را تسهیل کنید.
Bundlers ابزارهای ایده آل برای مدیریت اندازه خروجی برای اسکریپت ها هستند که وب سایت شما به این بستگی دارد:
- در جایی که به صفحه وب مربوط می شود ، افزونه
SplitChunksPlugin
آن می تواند کمک کند. برای گزینه هایی که می توانید برای کمک به مدیریت اندازه دارایی تنظیم کنید ، با اسنادSplitChunksPlugin
مشورت کنید. - برای سایر بسته های مانند Rollup و Esbuild ، می توانید با استفاده از تماس های پویا
import()
در کد خود ، اندازه پرونده های اسکریپت را مدیریت کنید. این دسته ها - و همچنین وب - به طور خودکار دارایی های پویا وارد شده را در پرونده خود خراب می کنند ، بنابراین از اندازه بسته های اولیه بزرگتر جلوگیری می کنند.
عدم اعتبار کش
بی اعتبار بودن حافظه نهان نقش مهمی در سرعت بارگذاری یک صفحه در بازدیدهای مکرر دارد. هنگامی که بسته های اسکریپت بزرگ و یکپارچه را حمل می کنید ، وقتی صحبت از مرورگر می شود ، دچار ضرر می شوید. این امر به این دلیل است که وقتی کد شخص اول خود را به روز می کنید-یا از طریق به روزرسانی بسته ها یا رفع اشکالات حمل و نقل ، کل بسته نرم افزاری بی اعتبار می شود و باید دوباره بارگیری شود.
با شکستن اسکریپت های خود ، شما فقط کار ارزیابی اسکریپت را در کارهای کوچکتر نمی شکنید ، این احتمال را نیز افزایش می دهید که بازدیدکنندگان به جای شبکه ، اسکریپت های بیشتری را از حافظه نهان مرورگر بدست آورند. این به یک بار سریعتر صفحه تبدیل می شود.
Nested modules and loading performance
If you're shipping ES modules in production and loading them with the type=module
attribute, you need to be aware of how module nesting can impact startup time. Module nesting refers to when an ES module statically imports another ES module that statically imports another ES module:
// a.js
import {b} from './b.js';
// b.js
import {c} from './c.js';
If your ES modules are not bundled together, the preceding code results in a network request chain: when a.js
is requested from a <script>
element, another network request is dispatched for b.js
, which then involves another request for c.js
. One way to avoid this is to use a bundler—but be sure you're configuring your bundler to break up scripts to spread out script evaluation work.
If you don't want to use a bundler, then another way to get around nested module calls is to use the modulepreload
resource hint , which will preload ES modules ahead of time to avoid network request chains.
نتیجه گیری
Optimizing evaluation of scripts in the browser is no doubt a tricky feat. The approach depends on your website's requirements and constraints. However, by splitting up scripts, you're spreading the work of script evaluation over numerous smaller tasks, and therefore giving the main thread the ability to handle user interactions more efficiently, rather than blocking the main thread.
To recap, here are some things you can to do to break up large script evaluation tasks:
- When loading scripts using the
<script>
element without thetype=module
attribute, avoid loading scripts that are very large, as these will kick off resource-intensive script evaluation tasks that block the main thread. Spread out your scripts over more<script>
elements to break up this work. - Using the
type=module
attribute to load ES modules natively in the browser will kick off individual tasks for evaluation for each separate module script. - Reduce the size of your initial bundles by using dynamic
import()
calls. This also works in bundlers, as bundlers will treat each dynamically imported module as a "split point," resulting in a separate script being generated for each dynamically imported module. - Be sure to weigh trade-offs such as compression efficiency and cache invalidation. Larger scripts will compress better, but are more likely to involve more expensive script evaluation work in fewer tasks, and result in browser cache invalidation, leading to overall lower caching efficiency.
- If using ES modules natively without bundling, use the
modulepreload
resource hint to optimize the loading of them during startup. - As always, ship as little JavaScript as possible.
It's a balancing act for sure—but by breaking up scripts and reducing initial payloads with dynamic import()
, you can achieve better startup performance and better accommodate user interactions during that crucial startup period. This should help you score better on the INP metric, thus delivering a better user experience.