راه خود را برای پاسخ‌های فوری جریان دهید

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

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

هنگام نوشتن کنترل کننده رویداد fetch خود، معمول است که فقط متد respondWith() به عنوان یک Response (یا قولی برای یک Response ) که از طریق fetch() یا caches.match() دریافت می کنید، ارسال کنید و آن را یک روز فراخوانی کنید. خبر خوب این است که Response های ایجاد شده توسط هر دوی این روش ها از قبل قابل پخش هستند! خبر بد این است که Response ساخته شده به صورت دستی، حداقل تا کنون، قابل پخش نیستند. اینجاست که Streams API وارد تصویر می شود.

جریان ها؟

استریم منبع داده ای است که می تواند به صورت تدریجی ایجاد و دستکاری شود و رابطی برای خواندن یا نوشتن تکه های ناهمزمان از داده ها فراهم می کند که فقط زیر مجموعه ای از آن ممکن است در هر زمان معین در حافظه موجود باشد. در حال حاضر، ما به ReadableStream s علاقه مندیم که می تواند برای ساخت یک شی Response که به fetchEvent.respondWith() ارسال می شود استفاده شود:

self.addEventListener('fetch', event => {
    var stream = new ReadableStream({
    start(controller) {
        if (/* there's more data */) {
        controller.enqueue(/* your data here */);
        } else {
        controller.close();
        }
    });
    });

    var response = new Response(stream, {
    headers: {'content-type': /* your content-type here */}
    });

    event.respondWith(response);
});

صفحه‌ای که درخواست آن رویداد fetch را راه‌اندازی کرده است، به محض فراخوانی event.respondWith() یک پاسخ جریانی دریافت می‌کند و تا زمانی که سرویس‌کار به قرار دادن داده‌های اضافی enqueue() ادامه دهد، به خواندن از آن جریان ادامه می‌دهد. پاسخی که از کارگر سرویس به صفحه می‌رسد واقعاً ناهمزمان است و ما کنترل کاملی بر پر کردن جریان داریم!

استفاده در دنیای واقعی

احتمالاً متوجه شده‌اید که مثال قبلی دارای مقداری مکان‌نما /* your data here */ نظرات بود، و در جزئیات پیاده‌سازی واقعی کم بود. بنابراین یک مثال در دنیای واقعی چگونه خواهد بود؟

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

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

جریان ها؟ یا پوسته برنامه؟

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

استریم ها جایگزینی برای مدل App Shell به همراه دارند، مدلی که در آن هنگام رفتن کاربر به صفحه جدید، پاسخ HTML کامل تری به مرورگر پخش می شود. پاسخ جریانی می‌تواند از منابع ذخیره‌سازی شده استفاده کند—بنابراین هنوز می‌تواند بخش اولیه HTML را حتی در حالت آفلاین به سرعت ارائه کند!—اما در نهایت بیشتر شبیه به بدنه‌های پاسخ سنتی و ارائه‌شده توسط سرور به نظر می‌رسند. به عنوان مثال، اگر برنامه وب شما از یک سیستم مدیریت محتوا پشتیبانی می‌کند که HTML را با پیوند دادن قالب‌های جزئی به یکدیگر ارائه می‌کند، آن مدل مستقیماً به استفاده از پاسخ‌های جریانی تبدیل می‌شود، با منطق الگوسازی که در سرویس‌کار به جای سرور شما تکرار می‌شود. همانطور که ویدیوی زیر نشان می‌دهد، برای آن مورد استفاده، مزیت سرعتی که پاسخ‌های جریانی ارائه می‌دهند می‌تواند چشمگیر باشد:

یکی از مزیت‌های مهم پخش کل پاسخ HTML، که توضیح می‌دهد چرا سریع‌ترین جایگزین در ویدیو است، این است که HTML ارائه‌شده در طول درخواست ناوبری اولیه می‌تواند از مزیت تجزیه‌کننده جریانی HTML مرورگر به‌طور کامل استفاده کند. تکه‌های HTML که پس از بارگیری صفحه در سند درج می‌شوند (همانطور که در مدل App Shell معمول است) نمی‌توانند از این بهینه‌سازی استفاده کنند.

بنابراین، اگر در مراحل برنامه‌ریزی پیاده‌سازی کارگر خدمات خود هستید، کدام مدل را باید اتخاذ کنید: پاسخ‌های جریانی که به‌تدریج ارائه می‌شوند، یا یک پوسته سبک وزن همراه با درخواست سمت مشتری برای محتوای پویا؟ جای تعجب نیست که پاسخ این است که بستگی به این دارد: آیا شما یک پیاده سازی موجود دارید که به یک CMS و قالب های جزئی متکی است (مزیت: جریان). در مورد اینکه آیا شما انتظار بارهای تک و بزرگ HTML را دارید که از رندر پیشرو بهره مند شوند (مزیت: جریان). در مورد اینکه آیا برنامه وب شما به بهترین شکل به عنوان یک برنامه تک صفحه ای مدل سازی می شود یا خیر (مزیت: App Shell). و در مورد اینکه آیا به مدلی نیاز دارید که در حال حاضر در نسخه های پایدار چندین مرورگر پشتیبانی می شود (مزیت: App Shell).

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

غواصی عمیق تر در نهرها

اگر جریان‌های قابل خواندن خود را می‌سازید، فراخوانی ساده controller.enqueue() ممکن است کافی یا کارآمد نباشد. جیک به جزئیاتی در مورد اینکه چگونه متدهای start() ، pull() و cancel() می‌توانند به صورت پشت سر هم برای ایجاد جریان داده‌ای متناسب با مورد استفاده شما استفاده شوند، می‌پردازد.

برای کسانی که جزئیات بیشتری می خواهند، مشخصات Streams شما را پوشش می دهد.

سازگاری

پشتیبانی برای ساخت یک شی Response در داخل یک سرویس کار با استفاده از ReadableStream به عنوان منبع آن در Chrome 52 اضافه شد.

پیاده سازی سرویس کارگر فایرفاکس هنوز از پاسخ های پشتیبانی شده توسط ReadableStream پشتیبانی نمی کند، اما یک اشکال ردیابی مربوطه برای پشتیبانی Streams API وجود دارد که می توانید آن را دنبال کنید.

پیشرفت در پشتیبانی بدون پیشوند Streams API در Edge، همراه با پشتیبانی کلی سرویس‌دهنده ، در صفحه وضعیت پلتفرم مایکروسافت قابل پیگیری است.