As we build sites more heavily reliant on JavaScript, we sometimes pay for what we send down in ways that we can’t always easily see. در این مقاله، توضیح میدهیم که چرا کمی نظم میتواند به شما کمک کند تا سایتتان در دستگاههای همراه سریعتر بار شود و تعاملی باشد. ارائه جاوا اسکریپت کمتر میتواند بهمعنای زمان کمتر در انتقال شبکه، صرف زمان کمتر برای از حالت فشرده خارج کردن کد، و زمان کمتر برای تجزیه و کامپایل کردن این جاوا اسکریپت باشد.
شبکه
وقتی اکثر توسعهدهندگان به هزینه جاوا اسکریپت فکر میکنند، آن را ازنظر هزینه بارگیری و اجرا درنظر میگیرند. هرچه اتصال کاربر کندتر باشد، ارسال بایتهای بیشتر جاوا اسکریپت ازطریق سیم بیشتر طول میکشد.

این میتواند مشکلساز باشد، زیرا نوع اتصال شبکه مؤثر که کاربر دارد ممکن است درواقع 3G، 4G، یا Wi-Fi نباشد. ممکن است به Wi-Fi قهوهسرا متصل باشید اما به نقطه اتصال تلفن همراه با سرعت 2G وصل شده باشید.
میتوانید هزینه انتقال شبکه جاوا اسکریپت را ازطریق موارد زیر کاهش دهید:
- فقط کدی را که کاربر نیاز دارد ارسال میکند.
- کوچکسازی
- از UglifyJS برای کوچک کردن کد ES5 استفاده کنید.
- از babel-minify یا uglify-es برای کوچک کردن ES2015+ استفاده کنید.
- فشردهسازی
- برداشتن کد استفادهنشده.
- با پوشش کد DevTools، فرصتهای کدی را که میتوان حذف کرد یا بهصورت کُند بار کرد شناسایی کنید.
- از babel-preset-env و browserlist استفاده کنید تا از ترجمه مبدأ به مبدأ ویژگیهایی که درحالحاضر در مرورگرهای نو وجود دارند اجتناب کنید. توسعهدهندگان پیشرفته ممکن است متوجه شوند که تجزیهوتحلیل دقیق بستههای webpack به شناسایی فرصتهایی برای حذف وابستگیهای غیرضروری کمک میکند.
- برای حذف کد، به tree-shaking، بهینهسازیهای پیشرفته Closure Compiler، و افزایههای پیرایش کتابخانه مانند lodash-babel-plugin یا ContextReplacementPlugin webpack برای کتابخانههایی مانند Moment.js مراجعه کنید.
- کد ذخیرهسازی موقت برای بهحداقل رساندن سفرهای شبکه.
- از ذخیرهسازی HTTP در حافظه نهان استفاده کنید تا مطمئن شوید مرورگرها پاسخها را بهطور مؤثر در حافظه نهان ذخیره میکنند. طول عمر بهینه را برای اسکریپتها (max-age) تعیین کنید و کدهای اعتبارسنجی (ETag) را ارائه دهید تا از انتقال بایتهای تغییرنیافته جلوگیری شود.
- ذخیره مؤقت Service Worker میتواند برنامه شما را دربرابر شبکه مقاوم کند و به شما دسترسی مشتاقانه به ویژگیهایی مثل حافظه پنهان کد V8 بدهد.
- از ذخیره موقت بلندمدت استفاده کنید تا مجبور نباشید منابعی را که تغییر نکردهاند دوباره واکشی کنید. اگر از Webpack استفاده میکنید، درهمسازی نام فایل را ببینید.
تجزیه/ترجمه کردن
پساز بارگیری، یکی از سنگینترین هزینههای جاوا اسکریپت، زمان لازم برای موتور جاوا اسکریپت برای تجزیه/کامپایل این کد است. در Chrome DevTools، تجزیه و کامپایل کردن بخشی از زمان زرد «اسکریپتسازی» در پانل «عملکرد» است.

برگههای «پایین به بالا» و «درخت فراخوانی» زمانبندی دقیق تجزیه/ترجمه را به شما نشان میدهند:
اما چرا این موضوع اهمیت دارد؟

صرف زمان طولانی برای تجزیه/کامپایل کردن کد میتواند بهشدت زمان تعامل کاربر با سایتتان را بهتأخیر بیندازد. هرچه جاوا اسکریپت بیشتری ارسال کنید، تجزیه و کامپایل کردن آن قبلاز تعاملی شدن سایتتان بیشتر طول میکشد.
بایت به بایت، پردازش جاوا اسکریپت برای مرورگر گرانتر از تصویر یا قلم وب با اندازه معادل است — تام دیل
درمقایسه با جاوا اسکریپت، هزینههای متعددی در پردازش تصاویر با اندازه معادل وجود دارد (هنوز باید رمزگشایی شوند!) اما در سختافزار تلفن همراه متوسط، جاوا اسکریپت احتمالاً تأثیر منفی بیشتری بر تعاملپذیری صفحه دارد.
وقتی میگوییم تجزیه و کامپایل کردن کند است، بافت مهم است — در اینجا درباره تلفنهای همراه متوسط صحبت میکنیم. کاربران معمولی ممکن است تلفنهایی با CPU و GPU کند، بدون حافظه پنهان L2/L3، و حتی با محدودیت حافظه داشته باشند.
قابلیتهای شبکه و قابلیتهای دستگاه همیشه باهم مطابقت ندارند. کاربری که اتصال Fiber فوقالعادهای دارد لزوماً بهترین CPU را برای تجزیه و ارزیابی جاوا اسکریپت ارسالشده به دستگاهش ندارد. این موضوع برعکس هم صادق است… اتصال شبکه بسیار بد، اما واحد پردازش مرکزی بسیار سریع. — کریستوفر بکستر، LinkedIn
در زیر میتوانیم هزینه تجزیه کردن حدود ۱ مگابایت جاوا اسکریپت ازفشردهخارجشده (ساده) را در سختافزار ردهپایین و ردهبالا ببینیم. بین سریعترین تلفنهای موجود در بازار و تلفنهای معمولی، ۲ تا ۵ برابر تفاوت در زمان تجزیه/کامپایل کد وجود دارد.
درباره سایتهای دنیای واقعی، مثل CNN.com، چطور؟
در iPhone 8 ردهبالا، تجزیه/کامپایل کردن JS مربوط به CNN فقط حدود ۴ ثانیه طول میکشد، درحالیکه در یک تلفن متوسط (Moto G4) حدود ۱۳ ثانیه طول میکشد. این امر میتواند تأثیر قابلتوجهی بر سرعت تعامل کامل کاربر با این سایت داشته باشد.
این امر اهمیت آزمایش روی سختافزار معمولی (مانند Moto G4) را بهجای آزمایش روی تلفنی که ممکن است در جیب شما باشد، برجسته میکند. بافت مهم است بااینحال: برای شرایط دستگاه و شبکهای که کاربران شما دارند بهینهسازی کنید.
آیا واقعاً جاوا اسکریپت زیادی ارسال میکنیم؟ شاید :)
بااستفاده از HTTP Archive (تقریباً ۵۰۰ هزار سایت برتر) برای تجزیهوتحلیل وضعیت جاوا اسکریپت در تلفن همراه، میتوانیم ببینیم که ۱۴ ثانیه طول میکشد تا ۵۰٪ سایتها تعاملی شوند. این سایتها تا ۴ ثانیه را فقط صرف تجزیه و کامپایل JS میکنند.

با درنظر گرفتن زمان لازم برای واکشی و پردازش JS و منابع دیگر، شاید تعجبآور نباشد که کاربران ممکن است مدتی منتظر بمانند تا احساس کنند صفحهها آماده استفاده هستند. قطعاً میتوانیم در اینجا بهتر عمل کنیم.
برداشتن جاوا اسکریپت غیربحرانی از صفحههایتان میتواند زمان انتقال، تجزیه و کامپایل کردن با مصرف بالای واحد پردازش مرکزی، و سربار حافظه احتمالی را کاهش دهد. این کار همچنین کمک میکند صفحههایتان سریعتر تعاملی شوند.
زمان اجرا
فقط تجزیه و کامپایل نیست که میتواند هزینه داشته باشد. اجرای جاوا اسکریپت (اجرای کد پساز تجزیه/کامپایل شدن) یکی از عملیاتی است که باید در رشته اصلی اتفاق بیفتد. زمانهای اجرای طولانی همچنین میتواند زمان تعامل کاربر با سایت شما را به تأخیر بیندازد.

اگر اجرای اسکریپت بیشاز ۵۰ میلیثانیه طول بکشد، زمان تعاملی بهاندازه کل مدتزمانی که برای بارگیری، کامپایل، و اجرای JS لازم است بهتأخیر میافتد — الکس راسل
برای رفع این مشکل، جاوا اسکریپت از قرار گرفتن در تکههای کوچک بهره میبرد تا از قفل شدن رشته اصلی جلوگیری کند. بررسی کنید که آیا میتوانید میزان کاری را که درطول اجرا انجام میشود کاهش دهید.
سایر هزینهها
جاوا اسکریپت میتواند به روشهای دیگری بر عملکرد صفحه تأثیر بگذارد:
- حافظه. صفحهها ممکن است بهدلیل GC (جمعآوری زباله) بهطور مکرر دچار لرزش یا توقف شوند. وقتی مرورگر حافظه را بازپس میگیرد، اجرای JS موقتاً متوقف میشود، بنابراین مرورگری که بهطور مکرر زباله جمعآوری میکند میتواند اجرا را بیشتر از آنچه ما میخواهیم موقتاً متوقف کند. از نشت حافظه و وقفههای مکرر gc اجتناب کنید تا صفحات بدون لرزش باقی بمانند.
- درطول زمان اجرا، جاوا اسکریپت طولانیمدت میتواند رشته اصلی را مسدود کند و باعث شود
صفحهها پاسخگو نباشند. تقسیم کردن کار به بخشهای کوچکتر (بااستفاده از
requestAnimationFrame()یاrequestIdleCallback()برای زمانبندی) میتواند مشکلات پاسخدهی را بهحداقل برساند که این امر میتواند به بهبود تعامل با نقاشی بعدی (INP) کمک کند.
الگوهای کاهش هزینه ارائه جاوا اسکریپت
وقتی میخواهید زمانهای تجزیه/کامپایل و انتقال شبکه را برای جاوا اسکریپت آهسته نگه دارید، الگوهایی مانند تکهتکه کردن مبتنی بر مسیر یا PRPL میتوانند کمک کنند.
PRPL
PRPL (Push, Render, Pre-cache, Lazy-load) الگویی است که برای تعامل ازطریق تقسیم کد و ذخیره در حافظه نهان تهاجمی بهینهسازی میکند:

بیایید تأثیری را که میتواند داشته باشد تجسم کنیم.
ما زمان بارگیری سایتهای تلفن همراه پرطرفدار و برنامههای وب پیشرو را بااستفاده از «آمار تماس زمان اجرای» V8 تجزیهوتحلیل میکنیم. همانطور که میبینیم، زمان تجزیه (به رنگ نارنجی نشان داده شده است) بخش قابلتوجهی از زمانی است که بسیاری از این سایتها صرف میکنند:

Wego، سایتی که از PRPL استفاده میکند، موفق شده است زمان تجزیه پایینی برای مسیرهایش حفظ کند و خیلی سریع تعاملی شود. Many of the other sites above adopted code-splitting and performance budgets to try lowering their JS costs.
راهاندازی تدریجی
بسیاریاز سایتها رؤیتپذیری محتوا را به قیمت ازدست رفتن تعاملپذیری بهینهسازی میکنند. برای دریافت یک رنگآمیزی سریع اولیه وقتی که بستههای بزرگ جاوا اسکریپت دارید، توسعهدهندگان گاهی اوقات از رندرینگ سمت سرور استفاده میکنند؛ سپس آن را «ارتقا» میدهند تا گردانندههای رویداد را وقتی که جاوا اسکریپت در نهایت واکشی میشود، متصل کنند.
مراقب باشید — این کار هزینههای خودش را دارد. شما ۱) معمولاً پاسخ HTML بزرگتری ارسال میکنید که میتواند تعاملپذیری ما را تحت فشار قرار دهد، ۲) میتوانید کاربر را در دره وهمی رها کنید که نیمی از تجربه نمیتواند واقعاً تعاملی باشد تا زمانی که پردازش JavaScript به پایان برسد.
«راهاندازی تدریجی» ممکن است رویکرد بهتری باشد. صفحهای با حداقل عملکرد (متشکل از HTML/JS/CSS موردنیاز برای مسیر فعلی) ارسال کنید. با رسیدن منابع بیشتر، برنامه میتواند بارگیری کُند انجام دهد و ویژگیهای بیشتری را باز کند.
بار کردن کد متناسب با آنچه در نما است، هدف نهایی است. PRPL و Progressive Bootstrapping الگوهایی هستند که میتوانند به انجام این کار کمک کنند.
نتیجهگیریها
اندازه انتقال برای شبکههای ضعیف بسیار مهم است. زمان تجزیه برای دستگاههای محدود به واحد پردازش مرکزی مهم است. پایین نگه داشتن این موارد مهم است.
تیمها با اتخاذ بودجههای عملکردی سختگیرانه برای پایین نگه داشتن زمان انتقال و تجزیه/ترجمه جاوا اسکریپت خود به موفقیت دست یافتهاند. به مقاله الکس راسل با عنوان «Can You Afford It?: بودجههای عملکرد وب در دنیای واقعی» برای راهنمایی درباره بودجههای تلفن همراه.
اگر درحال ساختن سایتی هستید که دستگاههای همراه را هدف قرار میدهد، تمام تلاش خود را بکنید تا روی سختافزار نمونه توسعه دهید، زمانهای تجزیه/ترجمه JavaScript خود را پایین نگه دارید و یک «بودجه عملکرد» اتخاذ کنید تا مطمئن شوید تیم شما میتواند هزینههای JavaScript خود را زیرنظر داشته باشد.
بیشتر بدانید
- Chrome Dev Summit 2017 - Modern Loading Best Practices
- عملکرد راهاندازی جاوا اسکریپت
- حل بحران عملکرد وب — نولان لاوسون
- آیا میتوانید هزینه آن را بپردازید؟ بودجههای عملکرد دنیای واقعی — الکس راسل
- ارزیابی چارچوبها و کتابخانههای وب — کریستوفر باکستر
- نتایج آزمایش Cloudflare با Brotli برای فشردهسازی (توجه داشته باشید که Brotli پویا با کیفیت بالاتر میتواند رندر اولیه صفحه را بهتأخیر بیندازد، بنابراین با دقت ارزیابی کنید. احتمالاً میخواهید بهجای آن بهصورت ایستا فشردهسازی کنید.)
- Performance Futures — Sam Saccone