با اسکنر پیش بارگذاری مرورگر مبارزه نکنید

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

یکی از جنبه های نادیده گرفته شده بهینه سازی سرعت صفحه شامل دانستن اندکی در مورد داخلی مرورگر است. مرورگرها بهینه‌سازی‌های خاصی را برای بهبود عملکرد به روش‌هایی انجام می‌دهند که ما به‌عنوان توسعه‌دهنده نمی‌توانیم - اما تا زمانی که این بهینه‌سازی‌ها ناخواسته خنثی نشده باشند.

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

اسکنر پیش بارگذاری چیست؟

هر مرورگر دارای یک تجزیه کننده اولیه HTML است که نشانه گذاری خام را نشانه گذاری می کند و آن را به یک مدل شی پردازش می کند. همه اینها با خوشحالی ادامه می‌یابد تا زمانی که تجزیه‌کننده وقتی یک منبع مسدودکننده را پیدا می‌کند، مانند یک شیوه نامه بارگذاری شده با عنصر <link> ، یا اسکریپت بارگیری شده با عنصر <script> بدون ویژگی async یا defer ، متوقف می‌شود.

نمودار تجزیه کننده HTML.
شکل 1: نموداری از نحوه مسدود کردن تجزیه کننده اولیه HTML مرورگر. در این مورد، تجزیه‌کننده به عنصر <link> برای یک فایل CSS خارجی اجرا می‌شود، که مرورگر را از تجزیه بقیه سند - یا حتی رندر کردن هر یک از آن - تا زمانی که CSS دانلود و تجزیه شود، مسدود می‌کند.

در مورد فایل‌های CSS، هم تجزیه و هم رندر کردن به منظور جلوگیری از فلش محتوای بدون استایل (FOUC) مسدود می‌شوند، یعنی زمانی که یک نسخه بدون استایل یک صفحه قبل از اعمال سبک‌ها روی آن به‌طور مختصر دیده می‌شود.

صفحه اصلی web.dev در حالت بدون استایل (سمت چپ) و حالت استایل شده (راست).
شکل 2: یک مثال شبیه سازی شده از FOUC. در سمت چپ صفحه اول web.dev بدون سبک است. در سمت راست همان صفحه با سبک های اعمال شده است. اگر مرورگر هنگام دانلود و پردازش یک شیوه نامه، رندر را مسدود نکند، حالت بدون استایل می‌تواند در یک لحظه رخ دهد.

مرورگر همچنین هنگام برخورد با عناصر <script> بدون ویژگی defer یا async ، تجزیه و رندر صفحه را مسدود می کند.

دلیل این امر این است که مرورگر نمی تواند با اطمینان بداند که آیا هر اسکریپت داده شده DOM را تغییر می دهد در حالی که تجزیه کننده اولیه HTML هنوز کار خود را انجام می دهد. به همین دلیل است که بارگذاری جاوا اسکریپت خود در انتهای سند به طوری که اثرات تجزیه و رندر مسدود شده حاشیه ای شود، یک روش معمول بوده است.

اینها دلایل خوبی برای این است که چرا مرورگر باید هم تجزیه و هم رندر را مسدود کند. با این حال، مسدود کردن هر یک از این مراحل مهم نامطلوب است، زیرا آنها می توانند نمایش را با تاخیر در کشف منابع مهم دیگر حفظ کنند. خوشبختانه، مرورگرها تمام تلاش خود را برای کاهش این مشکلات از طریق یک تجزیه کننده HTML ثانویه به نام اسکنر پیش بارگذاری انجام می دهند.

نموداری از تجزیه کننده اولیه HTML (چپ) و اسکنر پیش بارگذاری (راست) که تجزیه کننده HTML ثانویه است.
شکل 3: نموداری که نشان می دهد چگونه اسکنر پیش بارگذاری به موازات تجزیه کننده HTML اولیه برای بارگیری دارایی ها به صورت فرضی کار می کند. در اینجا، تجزیه‌کننده اولیه HTML مسدود می‌شود، زیرا CSS را بارگیری و پردازش می‌کند قبل از اینکه بتواند پردازش نشانه‌گذاری تصویر را در عنصر <body> آغاز کند، اما اسکنر پیش‌بارگیری می‌تواند به جلو در نشانه‌گذاری خام نگاه کند تا آن منبع تصویر را پیدا کند و بارگیری آن را قبل از تجزیه کننده اولیه HTML رفع انسداد است.

نقش یک اسکنر پیش بارگذاری گمانه‌زنی است ، به این معنی که نشانه‌گذاری خام را به منظور یافتن منابعی برای واکشی فرصت‌طلبانه قبل از تجزیه‌کننده اولیه HTML بررسی می‌کند.

چگونه بفهمیم اسکنر پیش بارگذاری چه زمانی کار می کند

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

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

نمودار آبشار شبکه WebPageTest تأخیر مصنوعی 2 ثانیه ای را نشان می دهد که بر صفحه سبک اعمال می شود.
شکل 4: نمودار آبشار شبکه WebPageTest از یک صفحه وب که بر روی Chrome بر روی یک دستگاه تلفن همراه از طریق اتصال 3G شبیه سازی شده اجرا می شود. حتی اگر صفحه سبک به طور مصنوعی از طریق یک پروکسی دو ثانیه قبل از شروع بارگیری به تأخیر می افتد، تصویری که بعداً در بارگذاری نشانه گذاری قرار دارد توسط اسکنر پیش بارگذاری کشف می شود.

همانطور که در آبشار می بینید، اسکنر پیش بارگذاری عنصر <img> را حتی زمانی که رندر و تجزیه سند مسدود شده است، کشف می کند. بدون این بهینه‌سازی، مرورگر نمی‌تواند موارد را به‌طور فرصت‌طلبانه در طول دوره مسدود کردن واکشی کند و درخواست‌های منابع بیشتر متوالی خواهد بود تا همزمان.

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

اسکریپت های async تزریق شد

فرض کنید HTML در <head> خود دارید که شامل جاوا اسکریپت داخلی مانند این است:

<script>
  const scriptEl = document.createElement('script');
  scriptEl.src = '/yall.min.js';

  document.head.appendChild(scriptEl);
</script>

اسکریپت های تزریق شده به طور پیش فرض async هستند، بنابراین وقتی این اسکریپت تزریق می شود، طوری رفتار می کند که گویی ویژگی async روی آن اعمال شده است. یعنی در اسرع وقت اجرا می شود و رندر را مسدود نمی کند. به نظر بهینه می رسد، درست است؟ با این حال، اگر فرض کنید که این <script> درون خطی بعد از یک عنصر <link> که یک فایل CSS خارجی را بارگیری می‌کند می‌آید، یک نتیجه کمتر از حد مطلوب دریافت خواهید کرد:

این نمودار WebPageTest نشان می دهد که اسکن پیش بارگذاری با تزریق یک اسکریپت شکست خورده است.
شکل 5: نمودار آبشار شبکه WebPageTest از یک صفحه وب که بر روی Chrome بر روی یک دستگاه تلفن همراه از طریق اتصال 3G شبیه سازی شده اجرا می شود. صفحه شامل یک شیوه نامه و یک اسکریپت async تزریق شده است. اسکنر پیش بارگذاری نمی تواند اسکریپت را در مرحله مسدود کردن رندر پیدا کند، زیرا به مشتری تزریق می شود.

بیایید آنچه را که در اینجا رخ داده است، تجزیه کنیم:

  1. در 0 ثانیه، سند اصلی درخواست می شود.
  2. در 1.4 ثانیه، اولین بایت درخواست ناوبری می رسد.
  3. در 2.0 ثانیه، CSS و تصویر درخواست می شود.
  4. از آنجایی که تجزیه کننده هنگام بارگیری شیوه نامه مسدود شده است و جاوا اسکریپت درون خطی که اسکریپت async را تزریق می کند در 2.6 ثانیه بعد از آن شیوه نامه می آید، عملکردی که اسکریپت ارائه می دهد به زودی در دسترس نیست.

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

بنابراین، اگر از یک تگ <script> معمولی با ویژگی async به جای تزریق اسکریپت به DOM استفاده کنید، چه اتفاقی می‌افتد؟

<script src="/yall.min.js" async></script>

این هم نتیجه:

یک آبشار شبکه WebPageTest که نشان می‌دهد چگونه یک اسکریپت ناهمگام بارگیری شده با استفاده از عنصر اسکریپت HTML هنوز توسط اسکنر پیش‌بارگذاری مرورگر قابل کشف است، حتی اگر تجزیه‌کننده HTML اولیه مرورگر هنگام دانلود و پردازش یک شیوه نامه مسدود شده باشد.
شکل 6: نمودار آبشار شبکه WebPageTest از یک صفحه وب که بر روی Chrome بر روی یک دستگاه تلفن همراه از طریق اتصال 3G شبیه سازی شده اجرا می شود. صفحه شامل یک شیوه نامه و یک عنصر <script> منفرد async . اسکنر پیش بارگذاری اسکریپت را در مرحله مسدود کردن رندر کشف می کند و همزمان با CSS بارگذاری می کند.

ممکن است وسوسه ای وجود داشته باشد که پیشنهاد کنیم این مشکلات را می توان با استفاده از rel=preload اصلاح کرد. این مطمئناً کار می کند، اما ممکن است عوارض جانبی داشته باشد. به هر حال، چرا از rel=preload برای رفع مشکلی استفاده می کنیم که با تزریق نکردن عنصر <script> به DOM می توان از آن جلوگیری کرد؟

یک آبشار WebPageTest که نشان می‌دهد چگونه از اشاره منبع rel=preload برای ترویج کشف یک اسکریپت تزریقی غیر همگام استفاده می‌شود - البته به‌طریقی که ممکن است عوارض جانبی ناخواسته داشته باشد.
شکل 7: نمودار آبشار شبکه WebPageTest از یک صفحه وب که بر روی Chrome بر روی یک دستگاه تلفن همراه از طریق اتصال 3G شبیه سازی شده اجرا می شود. این صفحه شامل یک شیوه نامه و یک اسکریپت async تزریق شده است، اما اسکریپت async از قبل بارگذاری شده است تا اطمینان حاصل شود که زودتر کشف می‌شود.

بارگذاری از قبل مشکل را در اینجا "رفع" می کند، اما یک مشکل جدید را معرفی می کند: اسکریپت async در دو دمو اول - علیرغم بارگیری در <head> - در اولویت "Low" بارگذاری می شود، در حالی که شیوه نامه در "Highest" بارگذاری می شود. اولویت. در آخرین نسخه نمایشی که اسکریپت async از قبل بارگذاری شده است، شیوه نامه همچنان در اولویت "بالاترین" بارگیری می شود، اما اولویت اسکریپت به "بالا" ارتقا یافته است.

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

پاسخ در اینجا ساده است: اگر در هنگام راه‌اندازی به اسکریپت نیاز است، اسکنر پیش‌بارگذاری را با تزریق آن به DOM شکست ندهید. در صورت نیاز با قرار دادن عنصر <script> و همچنین با ویژگی هایی مانند defer و async آزمایش کنید.

بارگذاری تنبل با جاوا اسکریپت

بارگذاری تنبل یک روش عالی برای حفظ داده است، روشی که اغلب بر روی تصاویر اعمال می شود. با این حال، گاهی اوقات بارگذاری تنبل به اشتباه روی تصاویری که به اصطلاح «در بالای صفحه» هستند اعمال می شود.

این موضوع مشکلات بالقوه ای را در مورد قابلیت کشف منبع در مورد اسکنر پیش بارگذاری معرفی می کند و می تواند به طور غیرضروری مدت زمان لازم برای کشف یک مرجع به یک تصویر، دانلود آن، رمزگشایی و ارائه آن را به تاخیر بیاندازد. بیایید این نشانه گذاری تصویر را به عنوان مثال در نظر بگیریم:

<img data-src="/sand-wasp.jpg" alt="Sand Wasp" width="384" height="255">

استفاده از پیشوند data- یک الگوی رایج در لودرهای تنبل با جاوا اسکریپت است. هنگامی که تصویر به نمای درگاه اسکرول می شود، لودر تنبل پیشوند data- را حذف می کند، به این معنی که در مثال قبل، data-src به src تبدیل می شود. این به روز رسانی از مرورگر می خواهد که منبع را واکشی کند.

این الگو تا زمانی که روی تصاویری که در هنگام راه‌اندازی در نمای نمایش هستند اعمال نشود مشکل ساز نیست. از آنجایی که اسکنر پیش بارگذاری ویژگی data-src را به همان روشی که ویژگی src (یا srcset ) می خواند، نمی خواند، مرجع تصویر زودتر کشف نمی شود. بدتر از آن، بارگیری تصویر تا زمانی که بارگذار تنبل جاوا اسکریپت بارگیری، کامپایل و اجرا شود به تأخیر می افتد.

نمودار آبشار شبکه WebPageTest که نشان می‌دهد چگونه یک تصویر با تنبلی بارگذاری شده که در هنگام راه‌اندازی در پنجره نمایش قرار دارد، لزوماً به تأخیر می‌افتد، زیرا اسکنر پیش‌بارگذاری مرورگر نمی‌تواند منبع تصویر را پیدا کند و تنها زمانی بارگیری می‌شود که جاوا اسکریپت مورد نیاز برای بارگذاری تنبل برای بارگیری کار کند. تصویر بسیار دیرتر از آنچه که باید کشف می شود.
شکل 8: نمودار آبشار شبکه WebPageTest از یک صفحه وب که بر روی Chrome بر روی یک دستگاه تلفن همراه از طریق اتصال 3G شبیه سازی شده اجرا می شود. منبع تصویر بدون نیاز به تنبلی بارگذاری می‌شود، حتی اگر در هنگام راه‌اندازی در ویوپورت قابل مشاهده باشد. این کار اسکنر پیش بارگذاری را از بین می برد و باعث تاخیر غیر ضروری می شود.

بسته به اندازه تصویر - که ممکن است به اندازه درگاه دید بستگی داشته باشد - ممکن است یک عنصر نامزد برای بزرگترین رنگ محتوایی (LCP) باشد. هنگامی که اسکنر پیش بارگذاری نمی تواند منبع تصویر را پیش از موعد واکشی کند - احتمالاً در نقطه ای که صفحه سبک (های) صفحه نمایش را مسدود می کند - LCP آسیب می بیند.

راه حل این است که نشانه گذاری تصویر را تغییر دهید:

<img src="/sand-wasp.jpg" alt="Sand Wasp" width="384" height="255">

این الگوی بهینه برای تصاویری است که در هنگام راه‌اندازی در نما هستند، زیرا اسکنر پیش‌بارگذاری منبع تصویر را سریع‌تر کشف و واکشی می‌کند.

یک نمودار آبشار شبکه WebPageTest که سناریوی بارگیری یک تصویر را در هنگام راه‌اندازی در نما نمایش می‌دهد. تصویر با تنبلی بارگذاری نمی شود، به این معنی که برای بارگیری به اسکریپت وابسته نیست، به این معنی که اسکنر پیش بارگذاری می تواند آن را زودتر کشف کند.
شکل 9: نمودار آبشار شبکه WebPageTest از یک صفحه وب که بر روی Chrome بر روی یک دستگاه تلفن همراه از طریق اتصال 3G شبیه سازی شده اجرا می شود. اسکنر پیش بارگذاری، منبع تصویر را قبل از شروع بارگیری CSS و جاوا اسکریپت کشف می کند، که به مرورگر برای بارگیری آن شروع می کند.

نتیجه در این مثال ساده شده بهبود 100 میلی ثانیه ای در LCP در یک اتصال آهسته است. این ممکن است پیشرفت بزرگی به نظر نرسد، اما زمانی است که فکر می‌کنید راه‌حل یک اصلاح سریع نشانه‌گذاری است و بیشتر صفحات وب پیچیده‌تر از این مجموعه نمونه‌ها هستند. این بدان معناست که نامزدهای LCP ممکن است مجبور باشند برای پهنای باند با بسیاری از منابع دیگر مبارزه کنند، بنابراین بهینه سازی هایی مانند این اهمیت فزاینده ای پیدا می کنند.

تصاویر پس زمینه CSS

به یاد داشته باشید که اسکنر پیش بارگذاری مرورگر نشانه گذاری را اسکن می کند . انواع دیگر منابع مانند CSS را که ممکن است شامل واکشی برای تصاویر ارجاع شده توسط ویژگی background-image باشد، اسکن نمی کند.

مانند HTML، مرورگرها CSS را به مدل شیء خود پردازش می کنند که به نام CSSOM شناخته می شود. اگر منابع خارجی در حین ساخت CSSOM کشف شوند، آن منابع در زمان کشف درخواست می شوند و نه توسط اسکنر پیش بارگذاری.

فرض کنید کاندید LCP صفحه شما یک عنصر با ویژگی background-image CSS است. موارد زیر هنگام بارگیری منابع اتفاق می افتد:

یک نمودار آبشار شبکه WebPageTest که صفحه ای را با نامزد LCP بارگیری شده از CSS با استفاده از ویژگی background-image نشان می دهد. از آنجایی که تصویر کاندید LCP از نوع منبعی است که اسکنر پیش بارگذاری مرورگر نمی تواند آن را بررسی کند، بارگیری منبع تا دانلود و پردازش CSS به تاخیر می افتد و زمان رنگ آمیزی کاندید LCP را به تاخیر می اندازد.
شکل 10: نمودار آبشار شبکه WebPageTest از یک صفحه وب که بر روی Chrome بر روی دستگاه تلفن همراه از طریق اتصال 3G شبیه سازی شده اجرا می شود. کاندید LCP صفحه یک عنصر با ویژگی background-image CSS (ردیف 3) است. تصویری که درخواست می کند تا زمانی که تجزیه کننده CSS آن را پیدا نکند واکشی شروع نمی شود.

در این مورد، اسکنر پیش بارگذاری آنقدر شکست نمی خورد که درگیر نمی شود. با این حال، اگر یک نامزد LCP در صفحه از یک ویژگی CSS background-image باشد، می‌خواهید آن تصویر را از قبل بارگذاری کنید:

<!-- Make sure this is in the <head> below any
     stylesheets, so as not to block them from loading -->
<link rel="preload" as="image" href="lcp-image.jpg">

این راهنمایی rel=preload کوچک است، اما به مرورگر کمک می کند تا تصویر را زودتر از آنچه در غیر این صورت انجام می داد، کشف کند:

یک نمودار آبشار شبکه WebPageTest که یک تصویر پس‌زمینه CSS (که نامزد LCP است) را نشان می‌دهد که به دلیل استفاده از راهنمایی rel=preload خیلی زودتر بارگیری می‌شود. زمان LCP تقریباً 250 میلی ثانیه بهبود می یابد.
شکل 11: نمودار آبشار شبکه WebPageTest از یک صفحه وب که بر روی Chrome بر روی یک دستگاه تلفن همراه از طریق اتصال 3G شبیه سازی شده اجرا می شود. کاندید LCP صفحه یک عنصر با ویژگی background-image CSS (ردیف 3) است. راهنمایی rel=preload به مرورگر کمک می کند تا تصویر را حدود 250 میلی ثانیه زودتر از بدون اشاره کشف کند.

با اشاره rel=preload ، نامزد LCP زودتر کشف می شود و زمان LCP را کاهش می دهد. در حالی که این راهنمایی به رفع این مشکل کمک می کند، گزینه بهتر ممکن است ارزیابی این باشد که آیا نامزد LCP تصویر شما باید از CSS بارگیری شود یا خیر. با یک تگ <img> ، کنترل بیشتری بر بارگذاری تصویری که برای نمای نمایش مناسب است خواهید داشت و در عین حال به اسکنر پیش بارگذاری اجازه می‌دهید آن را کشف کند.

گنجاندن منابع بسیار زیاد

Inlining عملی است که یک منبع را در داخل HTML قرار می دهد. می‌توانید شیوه نامه‌ها را در عناصر <style> ، اسکریپت‌ها در عناصر <script> و تقریباً هر منبع دیگری را با استفاده از کدگذاری base64 درون خطی کنید.

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

  • اگر HTML خود را در حافظه پنهان ذخیره نمی کنید - و اگر پاسخ HTML پویا باشد نمی توانید - منابع درون خطی هرگز کش نمی شوند. این بر عملکرد تأثیر می گذارد زیرا منابع درون خطی قابل استفاده مجدد نیستند.
  • حتی اگر بتوانید HTML را حافظه پنهان کنید، منابع درون خطی بین اسناد به اشتراک گذاشته نمی شود. این کار راندمان کش را در مقایسه با فایل‌های خارجی که می‌توان آن‌ها را در حافظه پنهان ذخیره کرد و در کل یک منبع دوباره استفاده کرد، کاهش می‌دهد.
  • اگر بیش از حد خط خطی کنید، اسکنر پیش بارگذاری را از کشف منابع بعدی در سند به تأخیر می اندازید، زیرا دانلود آن محتوای اضافی و خطی بیشتر طول می کشد.

این صفحه را به عنوان مثال در نظر بگیرید. در شرایط خاص، کاندید LCP تصویر بالای صفحه است و CSS در یک فایل جداگانه است که توسط عنصر <link> بارگذاری شده است. این صفحه همچنین از چهار فونت وب استفاده می کند که به عنوان فایل های جداگانه از منبع CSS درخواست می شوند.

یک نمودار صفحه آبشار شبکه WebPageTest با یک فایل CSS خارجی با چهار فونت ارجاع شده در آن. تصویر کاندید LCP در زمان مناسب توسط اسکنر پیش بارگذاری کشف می شود.
شکل 12: نمودار آبشار شبکه WebPageTest از یک صفحه وب که بر روی Chrome بر روی یک دستگاه تلفن همراه از طریق اتصال 3G شبیه سازی شده اجرا می شود. کاندید LCP صفحه، تصویری است که از یک عنصر <img> بارگذاری شده است، اما توسط اسکنر پیش بارگذاری کشف می شود زیرا CSS و فونت های مورد نیاز برای بارگیری صفحه در منابع جداگانه، که اسکنر پیش بارگذاری را از انجام کار خود به تاخیر نمی اندازد.

حال اگر CSS و تمام فونت ها به عنوان منابع base64 خط بندی شوند چه اتفاقی می افتد؟

یک نمودار صفحه آبشار شبکه WebPageTest با یک فایل CSS خارجی با چهار فونت ارجاع شده در آن. اسکنر پیش بارگذاری به طور قابل توجهی در کشف تصویر LCP تاخیر دارد.
شکل 13: نمودار آبشار شبکه WebPageTest از یک صفحه وب که بر روی Chrome بر روی یک دستگاه تلفن همراه از طریق اتصال 3G شبیه سازی شده اجرا می شود. کاندید LCP صفحه یک تصویر است که از عنصر <img> بارگیری شده است، اما خط‌بندی CSS و چهار منبع فونت آن در ` ` اسکنر پیش بارگذاری را از کشف تصویر به تاخیر می اندازد تا زمانی که آن منابع به طور کامل دانلود شوند.

تأثیر inlining پیامدهای منفی برای LCP در این مثال و عملکرد به طور کلی به همراه دارد. نسخه ای از صفحه که هیچ چیزی را درون خطی نمی کند، تصویر LCP را در حدود 3.5 ثانیه رنگ می کند. صفحه‌ای که همه چیز را در آن قرار می‌دهد، تصویر LCP را تا بیش از ۷ ثانیه ترسیم نمی‌کند.

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

آیا یک پیش بارگذاری می تواند همه چیز را در اینجا بهبود بخشد؟ مطمئن. می‌توانید تصویر LCP را از قبل بارگذاری کنید و زمان LCP را کاهش دهید، اما پرکردن HTML غیرقابل ذخیره‌سازی بالقوه‌تان با منابع درون‌خط شده، پیامدهای عملکرد منفی دیگری دارد. First Contentful Paint (FCP) نیز تحت تأثیر این الگو قرار می گیرد. در نسخه‌ای از صفحه که در آن هیچ چیز خطی نیست، FCP تقریباً 2.7 ثانیه است. در نسخه ای که همه چیز به صورت خطی است، FCP تقریباً 5.8 ثانیه است.

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

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

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

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

یک آبشار شبکه WebPageTest که یک صفحه اصلی با تصاویر و متن ارائه شده به طور کامل روی کلاینت در جاوا اسکریپت را نشان می دهد. از آنجا که نشانه گذاری در جاوا اسکریپت قرار دارد، اسکنر پیش بارگذاری نمی تواند هیچ یک از منابع را شناسایی کند. علاوه بر این، تمام منابع به دلیل شبکه و زمان پردازش اضافی که چارچوب‌های جاوا اسکریپت نیاز دارند، به تأخیر می‌افتند.
شکل 14: نمودار آبشار شبکه WebPageTest از یک صفحه وب ارائه شده توسط سرویس گیرنده که بر روی Chrome بر روی یک دستگاه تلفن همراه از طریق اتصال 3G شبیه سازی شده اجرا می شود. از آنجایی که محتوا در جاوا اسکریپت موجود است و برای ارائه به چارچوبی متکی است، منبع تصویر در نشانه گذاری ارائه شده توسط مشتری از اسکنر پیش بارگذاری پنهان می شود. تجربه معادل ارائه شده توسط سرور در شکل 9 نشان داده شده است.

هنگامی که بارهای نشانه گذاری در مرورگر قرار می گیرند و به طور کامل توسط جاوا اسکریپت ارائه می شوند، هر منبعی در آن نشانه گذاری برای اسکنر پیش بارگذاری نامرئی است. این امر کشف منابع مهم را به تأخیر می اندازد که مطمئناً بر LCP تأثیر می گذارد. در مورد این مثال‌ها، درخواست تصویر LCP در مقایسه با تجربه مشابه ارائه‌شده توسط سرور که برای نمایش نیازی به جاوا اسکریپت ندارد، به‌طور قابل‌توجهی به تأخیر می‌افتد.

این موضوع کمی از تمرکز این مقاله دور می‌شود، اما اثرات رندر نشانه‌گذاری بر روی مشتری بسیار فراتر از شکست اسکنر پیش‌بارگذاری است. برای مثال، معرفی جاوا اسکریپت برای تقویت تجربه‌ای که نیازی به آن ندارد، زمان پردازش غیرضروری را معرفی می‌کند که می‌تواند بر تعامل با رنگ بعدی (INP) تأثیر بگذارد. ارائه مقادیر بسیار زیاد نشانه گذاری روی کلاینت در مقایسه با همان مقدار نشانه گذاری ارسال شده توسط سرور، به احتمال زیاد کارهای طولانی را ایجاد می کند. دلیل این امر - جدای از پردازش اضافی که جاوا اسکریپت شامل می شود - این است که مرورگرها نشانه گذاری را از سرور پخش می کنند و رندر را به گونه ای تقسیم می کنند که تمایل دارد کارهای طولانی را محدود کند. از سوی دیگر، نشانه‌گذاری ارائه‌شده توسط مشتری، به عنوان یک کار منفرد و یکپارچه مدیریت می‌شود که ممکن است بر INP صفحه تأثیر بگذارد.

راه حل این سناریو به پاسخ این سوال بستگی دارد: آیا دلیلی وجود دارد که نشان‌گذاری صفحه شما توسط سرور ارائه نمی‌شود و برخلاف اینکه روی کلاینت ارائه می‌شود؟ اگر پاسخ به این "نه" است، رندر سمت سرور (SSR) یا نشانه‌گذاری استاتیکی باید در صورت امکان در نظر گرفته شود، زیرا به اسکنر پیش‌بارگذاری کمک می‌کند تا منابع مهم را زودتر کشف کند و به‌طور فرصت‌طلبانه واکشی کند.

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

به اسکنر پیش بارگذاری کمک کنید تا به شما کمک کند

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

برای جمع بندی، در اینجا موارد زیر وجود دارد که می خواهید از این پست حذف کنید:

  • اسکنر پیش بارگذاری مرورگر یک تجزیه‌کننده HTML ثانویه است که در صورت مسدود شدن برای کشف فرصت‌طلبانه منابعی که می‌تواند زودتر دریافت کند، پیش از اسکنر اولیه اسکن می‌کند.
  • منابعی که در نشانه گذاری ارائه شده توسط سرور در درخواست ناوبری اولیه وجود ندارند توسط اسکنر پیش بارگذاری قابل کشف نیستند. راه هایی که می توان اسکنر پیش بارگذاری را شکست داد ممکن است شامل موارد زیر باشد (اما محدود به موارد زیر نیست):
    • تزریق منابع به DOM با جاوا اسکریپت، اعم از اسکریپت، تصاویر، شیوه نامه، یا هر چیز دیگری که در بارگذاری اولیه نشانه گذاری از سرور بهتر باشد.
    • بارگذاری تنبل تصاویر یا آیفریم های بالا با استفاده از راه حل جاوا اسکریپت.
    • ارائه نشانه گذاری روی کلاینت که ممکن است حاوی ارجاع به منابع فرعی سند با استفاده از جاوا اسکریپت باشد.
  • اسکنر پیش بارگذاری فقط HTML را اسکن می کند. محتویات منابع دیگر - به ویژه CSS - که ممکن است شامل ارجاع به دارایی‌های مهم، از جمله نامزدهای LCP باشد را بررسی نمی‌کند.

اگر به هر دلیلی نمی‌توانید از الگویی که بر توانایی اسکنر پیش‌بارگذاری برای سرعت بخشیدن به عملکرد بارگذاری تأثیر منفی می‌گذارد اجتناب کنید، اشاره منبع rel=preload را در نظر بگیرید. اگر rel=preload استفاده می کنید، در ابزارهای آزمایشگاهی تست کنید تا مطمئن شوید که اثر مورد نظر را به شما می دهد. در نهایت، منابع زیادی را از قبل بارگذاری نکنید، زیرا وقتی همه چیز را اولویت بندی کنید، هیچ چیز نخواهد بود.

منابع

تصویر قهرمان از Unsplash اثر محمد رحمانی .