این روزها، وبسایتها – یا اگر ترجیح میدهید برنامههای وب – تمایل دارند از یکی از دو طرح ناوبری استفاده کنند:
- مرورگرهای طرح ناوبری به طور پیشفرض ارائه میکنند—یعنی یک URL را در نوار آدرس مرورگر خود وارد میکنید و درخواست ناوبری سندی را به عنوان پاسخ برمیگرداند. سپس روی پیوندی کلیک میکنید، که سند فعلی را برای یک سند دیگر، ad infinitum، بارگیری میکند.
- الگوی برنامه تک صفحه ای، که شامل یک درخواست ناوبری اولیه برای بارگیری پوسته برنامه است و به جاوا اسکریپت برای پر کردن پوسته برنامه با نشانه گذاری ارائه شده توسط مشتری با محتوای یک API پشتیبان برای هر "ناوبری" متکی است.
مزایای هر رویکرد توسط طرفداران آنها تبلیغ شده است:
- طرح ناوبری که مرورگرها به طور پیش فرض ارائه می کنند انعطاف پذیر است، زیرا مسیرها برای دسترسی به جاوا اسکریپت نیاز ندارند. ارائه نشانهگذاری توسط مشتری از طریق جاوا اسکریپت نیز میتواند یک فرآیند بالقوه گران باشد، به این معنی که دستگاههای پایینرده ممکن است در شرایطی قرار بگیرند که محتوا به تأخیر بیفتد زیرا دستگاه پردازش اسکریپتهای ارائهدهنده محتوا را مسدود میکند.
- از سوی دیگر، برنامه های کاربردی یک صفحه (SPAs) ممکن است ناوبری سریع تری را پس از بارگذاری اولیه ارائه دهند. به جای اتکا به مرورگر برای بارگیری یک سند برای یک سند کاملاً جدید (و تکرار این کار برای هر مسیریابی)، آنها میتوانند تجربهای سریعتر و «برنامهمانند» را ارائه دهند - حتی اگر برای عملکرد به جاوا اسکریپت نیاز باشد.
در این پست، قصد داریم در مورد روش سومی صحبت کنیم که بین دو رویکردی که در بالا توضیح داده شد، تعادل برقرار میکند: تکیه بر یک سرویسدهنده برای پیش کش کردن عناصر رایج یک وبسایت - مانند نشانهگذاری سرصفحه و پاورقی - و استفاده از جریانها برای پاسخ HTML را در سریع ترین زمان ممکن به مشتری ارائه دهید، در حالی که همچنان از طرح ناوبری پیش فرض مرورگر استفاده می کنید.
چرا پاسخهای HTML را در یک سرویسکار جریان میدهیم؟
پخش جریانی کاری است که مرورگر وب شما قبلاً هنگام درخواست انجام می دهد. این در زمینه درخواستهای ناوبری بسیار مهم است، زیرا اطمینان میدهد که مرورگر قبل از شروع به تجزیه نشانهگذاری سند و ارائه یک صفحه، در انتظار تمام پاسخ مسدود نمیشود.
برای کارکنان خدمات، پخش جریانی کمی متفاوت است زیرا از JavaScript Streams API استفاده می کند. مهمترین وظیفهای که یک کارگر خدماتی انجام میدهد، رهگیری و پاسخگویی به درخواستها از جمله درخواستهای ناوبری است.
این درخواستها میتوانند به روشهای مختلفی با حافظه پنهان تعامل داشته باشند، اما یک الگوی رایج ذخیرهسازی حافظه پنهان برای نشانهگذاری این است که ابتدا از پاسخی از شبکه استفاده شود، اما اگر نسخه قدیمیتری در دسترس باشد، به حافظه پنهان باز میگردند — و بهصورت اختیاری یک نسخه بازگشتی عمومی ارائه میکنند. اگر پاسخ قابل استفاده در حافظه پنهان نباشد، پاسخ دهید .
این یک الگوی آزمایش شده برای نشانه گذاری است که به خوبی کار می کند، اما در حالی که به قابلیت اطمینان از نظر دسترسی آفلاین کمک می کند، هیچ مزیت عملکرد ذاتی برای درخواست های ناوبری که ابتدا به یک شبکه یا استراتژی فقط شبکه متکی هستند، ارائه نمی دهد. اینجاست که پخش جریانی وارد میشود و ما نحوه استفاده از ماژول workbox-streams
مبتنی بر API Streams را در Workbox Service Workbox برای سرعت بخشیدن به درخواستهای پیمایش در وبسایت چند صفحهای خود بررسی خواهیم کرد.
شکستن یک صفحه وب معمولی
از نظر ساختاری، وب سایت ها تمایل دارند عناصر مشترکی داشته باشند که در هر صفحه وجود دارد. چیدمان معمولی عناصر صفحه اغلب چیزی شبیه به:
- سربرگ.
- محتوا.
- پاورقی.
با استفاده از web.dev به عنوان مثال، تجزیه عناصر رایج به صورت زیر است:
هدف در پشت شناسایی بخشهای یک صفحه این است که ما تعیین کنیم چه چیزی را میتوان بدون رفتن به شبکه از پیش کش کرد و بازیابی کرد - یعنی نشانهگذاری سرصفحه و پاورقی مشترک برای همه صفحات - و بخشی از صفحه که همیشه به شبکه میرویم. برای اول - محتوا در این مورد.
هنگامی که میدانیم چگونه بخشهای یک صفحه را تقسیمبندی کنیم و عناصر مشترک را شناسایی کنیم، میتوانیم یک سرویسکار بنویسیم که همیشه نشانهگذاری سرصفحه و پاورقی را فوراً از حافظه پنهان بازیابی میکند در حالی که فقط محتوا را از شبکه درخواست میکند.
سپس، با استفاده از Streams API از طریق workbox-streams
، میتوانیم تمام این بخشها را به هم بچسبانیم و فوراً به درخواستهای ناوبری پاسخ دهیم - در حالی که حداقل مقدار نشانهگذاری لازم را از شبکه درخواست میکنیم.
ساخت یک کارگر سرویس جریان
وقتی صحبت از پخش محتوای جزئی در یک سرویسدهنده میشود، بخشهای متحرک زیادی وجود دارد، اما هر مرحله از فرآیند با جزئیات بررسی میشود و از نحوه ساختار وبسایتتان شروع میشود.
بخش بندی وب سایت خود به جزئی
قبل از اینکه بتوانید شروع به نوشتن یک کارگر سرویس استریم کنید، باید سه کار را انجام دهید:
- فایلی ایجاد کنید که فقط حاوی نشانه گذاری هدر وب سایت شما باشد.
- فایلی ایجاد کنید که فقط حاوی نشانه گذاری فوتر وب سایت شما باشد.
- محتوای اصلی هر صفحه را در یک فایل جداگانه بیرون بیاورید یا قسمت پشتی خود را طوری تنظیم کنید که به صورت مشروط فقط محتوای صفحه را بر اساس سرصفحه درخواست HTTP ارائه دهد.
همانطور که ممکن است انتظار داشته باشید، آخرین مرحله سخت ترین مرحله است، به خصوص اگر وب سایت شما ثابت باشد. اگر این مورد برای شما صادق است، باید دو نسخه از هر صفحه ایجاد کنید: یک نسخه شامل نشانه گذاری کامل صفحه است، در حالی که نسخه دیگر فقط حاوی محتوا است.
آهنگسازی یک کارگر سرویس جریان
اگر ماژول workbox-streams
را نصب نکرده اید، باید علاوه بر ماژول های Workbox که در حال حاضر نصب کرده اید، این کار را نیز انجام دهید. برای این مثال خاص، که شامل بسته های زیر است:
npm i workbox-navigation-preload workbox-strategies workbox-routing workbox-precaching workbox-streams --save
از اینجا، گام بعدی این است که سرویسکار جدید خود را ایجاد کنید و قسمتهای سرصفحه و پاورقی خود را پیش کش کنید.
پیش کش کردن جزئی
اولین کاری که باید انجام دهید این است که یک سرویس دهنده در ریشه پروژه خود به نام sw.js
(یا هر نام فایلی که ترجیح می دهید) ایجاد کنید. در آن، شما با موارد زیر شروع خواهید کرد:
// sw.js
import * as navigationPreload from 'workbox-navigation-preload';
import {NetworkFirst} from 'workbox-strategies';
import {registerRoute} from 'workbox-routing';
import {matchPrecache, precacheAndRoute} from 'workbox-precaching';
import {strategy as composeStrategies} from 'workbox-streams';
// Enable navigation preload for supporting browsers
navigationPreload.enable();
// Precache partials and some static assets
// using the InjectManifest method.
precacheAndRoute([
// The header partial:
{
url: '/partial-header.php',
revision: __PARTIAL_HEADER_HASH__
},
// The footer partial:
{
url: '/partial-footer.php',
revision: __PARTIAL_FOOTER_HASH__
},
// The offline fallback:
{
url: '/offline.php',
revision: __OFFLINE_FALLBACK_HASH__
},
...self.__WB_MANIFEST
]);
// To be continued...
این کد چند کار را انجام می دهد:
- پیش بارگیری پیمایش را برای مرورگرهایی که از آن پشتیبانی می کنند فعال می کند.
- نشانه گذاری سرصفحه و پاورقی را از قبل ذخیره می کند. این بدان معنی است که نشانه گذاری سرصفحه و پاورقی برای هر صفحه فوراً بازیابی می شود، زیرا توسط شبکه مسدود نمی شود.
- داراییهای استاتیک را در مکاننمای
__WB_MANIFEST
که از روشinjectManifest
استفاده میکند، از پیش ذخیره میکند.
پاسخهای جریانی
وادار کردن کارمند خدمات خود به پخش پاسخ های پیوسته، بزرگترین بخش از کل این تلاش است. با این حال، Workbox و workbox-streams
آن باعث میشود که این موضوع بسیار مختصرتر از زمانی باشد که مجبور باشید همه این کارها را به تنهایی انجام دهید:
// sw.js
import * as navigationPreload from 'workbox-navigation-preload';
import {NetworkFirst} from 'workbox-strategies';
import {registerRoute} from 'workbox-routing';
import {matchPrecache, precacheAndRoute} from 'workbox-precaching';
import {strategy as composeStrategies} from 'workbox-streams';
// ...
// Prior navigation preload and precaching code omitted...
// ...
// The strategy for retrieving content partials from the network:
const contentStrategy = new NetworkFirst({
cacheName: 'content',
plugins: [
{
// NOTE: This callback will never be run if navigation
// preload is not supported, because the navigation
// request is dispatched while the service worker is
// booting up. This callback will only run if navigation
// preload is _not_ supported.
requestWillFetch: ({request}) => {
const headers = new Headers();
// If the browser doesn't support navigation preload, we need to
// send a custom `X-Content-Mode` header for the back end to use
// instead of the `Service-Worker-Navigation-Preload` header.
headers.append('X-Content-Mode', 'partial');
// Send the request with the new headers.
// Note: if you're using a static site generator to generate
// both full pages and content partials rather than a back end
// (as this example assumes), you'll need to point to a new URL.
return new Request(request.url, {
method: 'GET',
headers
});
},
// What to do if the request fails.
handlerDidError: async ({request}) => {
return await matchPrecache('/offline.php');
}
}
]
});
// Concatenates precached partials with the content partial
// obtained from the network (or its fallback response).
const navigationHandler = composeStrategies([
// Get the precached header markup.
() => matchPrecache('/partial-header.php'),
// Get the content partial from the network.
({event}) => contentStrategy.handle(event),
// Get the precached footer markup.
() => matchPrecache('/partial-footer.php')
]);
// Register the streaming route for all navigation requests.
registerRoute(({request}) => request.mode === 'navigate', navigationHandler);
// Your service worker can end here, or you can add more
// logic to suit your needs, such as runtime caching, etc.
این کد از سه بخش اصلی تشکیل شده است که شرایط زیر را برآورده می کند:
- استراتژی
NetworkFirst
برای رسیدگی به درخواستهای جزئی محتوا استفاده میشود. با استفاده از این استراتژی، یک نام کش سفارشیcontent
مشخص میشود که حاوی قسمتهای محتوا باشد، و همچنین یک افزونه سفارشی که تنظیم کردن سرصفحه درخواستX-Content-Mode
برای مرورگرهایی که از پیشبارگذاری ناوبری پشتیبانی نمیکنند (و در نتیجه نمیتوانند) تعیین شود. یک هدرService-Worker-Navigation-Preload
ارسال نکنید). این افزونه همچنین تشخیص می دهد که آیا باید آخرین نسخه کش شده یک محتوا را به طور جزئی ارسال کند یا در صورتی که هیچ نسخه کش برای درخواست فعلی ذخیره نشود، یک صفحه بازگشتی آفلاین ارسال کند. - روش
strategy
درworkbox-streams
(در اینجا با نام مستعارcomposeStrategies
) برای الحاق قسمتهای سرصفحه و پاورقی پیش کش شده به همراه محتوای جزئی درخواست شده از شبکه استفاده میشود. - کل طرح از طریق
registerRoute
برای درخواستهای ناوبری تقلب میشود.
با این منطق، ما پاسخهای جریانی را تنظیم کردهایم. با این حال، ممکن است برای اطمینان از اینکه محتوای شبکه یک صفحه جزئی است که میتوانید با جزئیهای از پیش ذخیرهشده ادغام کنید، باید کارهایی را در قسمت پشتی انجام دهید.
اگر وب سایت شما دارای بک اند است
به خاطر می آورید که وقتی پیش بارگذاری ناوبری فعال است، مرورگر یک سرصفحه Service-Worker-Navigation-Preload
با مقدار true
ارسال می کند. با این حال، در نمونه کد بالا، یک سرصفحه سفارشی از X-Content-Mode
ارسال کردیم در صورتی که پیشبارگذاری ناوبری رویداد در مرورگر پشتیبانی نمیشود. در پایان، شما پاسخ را بر اساس وجود این هدرها تغییر می دهید. در یک صفحه پشتی PHP، ممکن است برای یک صفحه معین چیزی شبیه به این باشد:
<?php
// Check if we need to render a content partial
$navPreloadSupported = isset($_SERVER['HTTP_SERVICE_WORKER_NAVIGATION_PRELOAD']) && $_SERVER['HTTP_SERVICE_WORKER_NAVIGATION_PRELOAD'] === 'true';
$partialContentMode = isset($_SERVER['HTTP_X_CONTENT_MODE']) && $_SERVER['HTTP_X_CONTENT_MODE'] === 'partial';
$isPartial = $navPreloadSupported || $partialContentMode;
// Figure out whether to render the header
if ($isPartial === false) {
// Get the header include
require_once($_SERVER['DOCUMENT_ROOT'] . '/includes/site-header.php');
// Render the header
siteHeader();
}
// Get the content include
require_once('./content.php');
// Render the content
content($isPartial);
// Figure out whether to render the footer
if ($isPartial === false) {
// Get the footer include
require_once($_SERVER['DOCUMENT_ROOT'] . '/includes/site-footer.php');
// Render the footer
siteFooter();
}
?>
در مثال بالا، جزئیهای محتوا بهعنوان توابعی فراخوانی میشوند که مقدار $isPartial
را برای تغییر نحوه رندر کردن جزئیها میگیرند. برای مثال، عملکرد ارائهدهنده content
ممکن است تنها نشانهگذاری خاصی را در شرایطی که بهصورت جزئی بازیابی میشود، شامل شود - چیزی که بهزودی پوشش داده میشود.
ملاحظات
قبل از اینکه یک سرویسکار را برای پخش جریانی و دوخت قطعات به یکدیگر مستقر کنید، مواردی وجود دارد که باید در نظر بگیرید. در حالی که درست است که استفاده از یک سرویس دهنده به این روش اساساً رفتار ناوبری پیش فرض مرورگر را تغییر نمی دهد، مواردی وجود دارد که احتمالاً باید به آنها توجه کنید.
به روز رسانی عناصر صفحه هنگام پیمایش
مشکل ترین بخش این رویکرد این است که برخی چیزها باید در مشتری به روز شوند. برای مثال، نشانگذاری هدر پیش از ذخیره به این معنی است که صفحه دارای محتوای یکسانی در عنصر <title>
خواهد بود، یا حتی مدیریت وضعیتهای روشن/خاموش برای موارد ناوبری باید در هر پیمایش بهروزرسانی شود. این موارد - و موارد دیگر - ممکن است برای هر درخواست ناوبری در مشتری به روز شوند.
راهی برای دور زدن این موضوع ممکن است قرار دادن یک عنصر <script>
درون خطی در محتوای جزئی که از شبکه می آید برای به روز رسانی چند چیز مهم باشد:
<!-- The JSON below contains information about the current page. -->
<script id="page-data" type="application/json">'{"title":"Sand Wasp — World of Wasps","description":"Read all about the sand wasp in this tidy little post."}'</script>
<script>
const pageData = JSON.parse(document.getElementById('page-data').textContent);
// Update the page title
document.title = pageData.title;
</script>
<article>
<!-- Page content omitted... -->
</article>
این فقط یک نمونه از کارهایی است که ممکن است مجبور شوید اگر تصمیم بگیرید با این راهاندازی کارگر سرویس بروید. برای مثال، برای برنامههای پیچیدهتر با اطلاعات کاربر، ممکن است مجبور شوید بیتهایی از دادههای مرتبط را در یک فروشگاه وب مانند localStorage
ذخیره کنید و صفحه را از آنجا بهروزرسانی کنید.
مقابله با شبکه های کند
یکی از اشکالات پاسخ های جریانی با استفاده از نشانه گذاری از پیش کش می تواند زمانی رخ دهد که اتصالات شبکه کند هستند. مشکل این است که نشانه گذاری هدر از پیش کش فوراً وارد می شود، اما محتوای جزئی از شبکه ممکن است پس از رنگ آمیزی اولیه نشانه گذاری سرصفحه، زمان زیادی طول بکشد.
این میتواند تجربهای گیجکننده ایجاد کند، و اگر شبکهها بسیار کند باشند، حتی ممکن است احساس کنید که صفحه شکسته است و دیگر رندر نمیشود. در مواردی مانند این، میتوانید نماد یا پیام بارگیری را در نشانهگذاری جزئی محتوا قرار دهید که میتوانید پس از بارگیری محتوا، آن را پنهان کنید.
یکی از راه های انجام این کار از طریق CSS است. بگویید هدر جزئی شما با یک عنصر باز <article>
به پایان می رسد که خالی است تا زمانی که محتوای جزئی وارد شود و آن را پر کند. شما می توانید یک قانون CSS مشابه این بنویسید:
article:empty::before {
text-align: center;
content: 'Loading...';
}
این کار می کند، اما بدون در نظر گرفتن سرعت شبکه، پیام بارگیری را روی مشتری نشان می دهد. اگر میخواهید از فلش پیامرسانی عجیب جلوگیری کنید، میتوانید این روش را امتحان کنید که در آن انتخابگر را در قطعه بالا در یک کلاس slow
قرار میدهیم:
.slow article:empty::before {
text-align: center;
content: 'Loading...';
}
از اینجا میتوانید از جاوا اسکریپت در هدر جزئی خود برای خواندن نوع اتصال مؤثر (حداقل در مرورگرهای Chromium) استفاده کنید تا کلاس slow
را به عنصر <html>
در انواع اتصال انتخابی اضافه کنید:
<script>
const effectiveType = navigator?.connection?.effectiveType;
if (effectiveType !== '4g') {
document.documentElement.classList.add('slow');
}
</script>
این اطمینان حاصل می کند که انواع اتصال موثر که کندتر از نوع 4g
هستند پیام بارگیری دریافت می کنند. سپس در محتوای جزئی، می توانید یک عنصر <script>
درون خطی قرار دهید تا کلاس slow
را از HTML حذف کنید تا از شر پیام بارگیری خلاص شوید:
<script>
document.documentElement.classList.remove('slow');
</script>
ارائه پاسخ بازگشتی
فرض کنید از یک استراتژی شبکه اول برای قسمت های محتوای خود استفاده می کنید. اگر کاربر آفلاین باشد و به صفحه ای که قبلاً در آن رفته است برود، تحت پوشش قرار می گیرد. با این حال، اگر به صفحهای بروند که هنوز به آن نرفتهاند ، چیزی دریافت نمیکنند. برای جلوگیری از این امر، باید یک پاسخ بازگشتی ارائه دهید.
کد مورد نیاز برای دستیابی به یک پاسخ بازگشتی در نمونه کدهای قبلی نشان داده شده است. این فرآیند به دو مرحله نیاز دارد:
- یک پاسخ بازگشتی آفلاین را از قبل ذخیره کنید.
- یک
handlerDidError
callback در افزونه برای استراتژی شبکه اول خود تنظیم کنید تا حافظه نهان را برای آخرین نسخه یک صفحه بررسی کنید. اگر هرگز به صفحه دسترسی نداشتید، باید از متدmatchPrecache
از ماژولworkbox-precaching
برای بازیابی پاسخ بازگشتی از پیش کش استفاده کنید.
حافظه پنهان و CDN
اگر از این الگوی پخش جریانی در کارمند خدمات خود استفاده میکنید، بررسی کنید که آیا موارد زیر برای وضعیت شما صدق میکند یا خیر:
- شما از CDN یا هر نوع دیگری از کش متوسط/عمومی استفاده می کنید.
- شما یک هدر
Cache-Control
با دستورالعمل(های)max-age
و/یاs-maxage
غیر صفر در ترکیب با دستورالعملpublic
مشخص کرده اید.
اگر هر دوی این موارد برای شما صادق است، حافظه پنهان میانی ممکن است پاسخهای درخواستهای ناوبری را نگه دارد. با این حال، به یاد داشته باشید که وقتی از این الگو استفاده می کنید، ممکن است دو پاسخ متفاوت برای هر URL داده شده ارائه دهید:
- پاسخ کامل، شامل هدر، محتوا و نشانه گذاری پاورقی.
- پاسخ جزئی، فقط شامل محتوا است.
این میتواند باعث برخی رفتارهای نامطلوب شود که در نتیجه نشانهگذاری سرصفحه و پاورقی دو برابر میشود، زیرا کارگر سرویس ممکن است پاسخ کاملی را از حافظه پنهان CDN دریافت کند و آن را با نشانهگذاری سرصفحه و پاورقی از پیش ذخیرهشده شما ترکیب کند.
برای دور زدن این موضوع، باید به هدر Vary
تکیه کنید، که با کلید زدن پاسخهای قابل ذخیرهسازی به یک یا چند سرصفحه موجود در درخواست، بر رفتار حافظه پنهان تأثیر میگذارد. از آنجا که ما پاسخها به درخواستهای ناوبری را بر اساس سرصفحههای درخواست Service-Worker-Navigation-Preload
و سفارشی X-Content-Mode
تغییر میدهیم، باید این هدر Vary
را در پاسخ مشخص کنیم:
Vary: Service-Worker-Navigation-Preload,X-Content-Mode
با استفاده از این هدر، مرورگر بین پاسخهای کامل و جزئی برای درخواستهای ناوبری تفاوت قائل میشود و از مشکلات مربوط به نشانهگذاری سرصفحه و پاورقی دوبرابر، و همچنین هر حافظه پنهان میانی جلوگیری میکند.
نتیجه
بیشتر توصیههای عملکردی در زمان بارگذاری به این صورت خلاصه میشود که «آنچه را که به دست آوردهاید به آنها نشان دهید» - درنگ نکنید، منتظر نمانید تا همه چیز را داشته باشید قبل از اینکه چیزی را به کاربر نشان دهید.
جیک آرچیبالد در هک های سرگرم کننده برای محتوای سریعتر
مرورگرها در برخورد با پاسخ به درخواستهای ناوبری، حتی برای بدنههای بزرگ پاسخ HTML، برتری دارند. بهطور پیشفرض، مرورگرها بهتدریج نشانهگذاری را در بخشهایی پخش و پردازش میکنند که از انجام کارهای طولانی اجتناب میکند، که برای عملکرد راهاندازی خوب است.
وقتی از الگوی کارگر سرویس پخش استفاده می کنیم، این به نفع ما است. هر زمان که از همان ابتدا به درخواستی از کش سرویس دهنده پاسخ دهید، شروع پاسخ تقریباً فوراً می رسد. هنگامی که نشانه گذاری سرصفحه و پاورقی پیش کش شده را با پاسخی از شبکه به هم می چسبانید، مزایای عملکرد قابل توجهی دریافت می کنید:
- زمان تا اولین بایت (TTFB) اغلب بسیار کاهش می یابد، زیرا اولین بایت پاسخ به درخواست ناوبری فوری است.
- First Contentful Paint (FCP) بسیار سریع خواهد بود، زیرا نشانه گذاری سرصفحه از پیش ذخیره شده حاوی ارجاع به یک شیوه نامه ذخیره شده در حافظه پنهان است، به این معنی که صفحه بسیار بسیار سریع رنگ می شود.
- در برخی موارد، بزرگترین رنگ محتوایی (LCP) میتواند سریعتر نیز باشد، بهویژه اگر بزرگترین عنصر روی صفحه توسط هدر جزئی از پیش کش ارائه شده باشد. حتی در این صورت، فقط ارائه چیزی خارج از کش سرویس در اسرع وقت در کنار بارهای نشانه گذاری کوچکتر ممکن است منجر به LCP بهتری شود.
راهاندازی و تکرار جریانسازی معماریهای چند صفحهای میتواند کمی دشوار باشد، اما پیچیدگی آن اغلب از نظر تئوری سختتر از SPA نیست. مزیت اصلی این است که شما طرح ناوبری پیش فرض مرورگر را جایگزین نمی کنید، بلکه آن را بهبود می بخشید .
بهتر از آن، Workbox این معماری را نه تنها ممکن میکند، بلکه آسانتر از اجرای آن به تنهایی است. آن را در وب سایت خود امتحان کنید و ببینید که وب سایت چند صفحه ای شما چقدر می تواند برای کاربران در این زمینه سریعتر باشد.