আউট-অফ-অর্ডার (OOO) HTML স্ট্রিমিং (ডিক্লারেটিভ আংশিক আপডেট হিসেবেও পরিচিত) হল HTML-এর প্রথাগত "উপর-থেকে-নিচে" লিনিয়ার প্রসেসিংয়ের বিকল্প। এটি ডেভেলপারদের কোনও ডকুমেন্টে আগে থেকে প্লেসহোল্ডার নির্ধারণ করতে এবং একই নেটওয়ার্ক স্ট্রিমে পরে আসা কন্টেন্ট বা নতুন ইম্পারেটিভ জাভাস্ক্রিপ্ট স্ট্রিমিং API-এর মাধ্যমে সেগুলিকে "প্যাচ" করার অনুমতি দেয়।
দ্রুত এক নজরে
এই ফিচারে দুটি প্রাথমিক মেকানিজম আছে:
- ডিক্লারেটিভ প্যাচিং (HTML-ভিত্তিক): সার্ভার থেকে স্ট্রিম করার সময় DOM-এ কন্টেন্ট সোয়্যাপ করার জন্য নতুন প্রসেসিং নির্দেশাবলী (
<?marker>,<?start>,<?end>) এবং<template for>ব্যবহার করে। - ইম্পারেটিভ সেটিং ও স্ট্রিমিং (JS-ভিত্তিক): নতুন পদ্ধতির একটি স্যুট (যেমন,
streamHTML(),setHTMLUnsafe()) যা নেটিভ পারফর্ম্যান্স ও ঐচ্ছিক স্ক্রিপ্ট এক্সিকিউশন সহ HTML সেট করা বা সরাসরি DOM এলিমেন্টে রিডেবল স্ট্রিম পাইপ করার অনুমতি দেয়।
পেশাদার পদ্ধতি
- অ্যাবাভ-দ্য-ফোল্ড কন্টেন্টকে অগ্রাধিকার দিন: গুরুত্বপূর্ণ UI (হেডার, হিরো, প্রাথমিক নেভিগেশন, প্রাথমিক কন্টেন্ট) প্রথমে স্ট্রিম করুন। "দামী" বা কম অগ্রাধিকারযুক্ত কম্পোনেন্ট যেমন কমেন্ট, বিজ্ঞাপন বা সম্পর্কিত কন্টেন্টের জন্য প্লেসহোল্ডার ব্যবহার করুন।
- নেটিভ লোডিং স্টেট প্রয়োগ করা: ফলব্যাক কন্টেন্ট র্যাপ করতে
<?start>এবং<?end>মার্কার ব্যবহার করুন। সংশ্লিষ্ট<template for>এলে, ব্রাউজার অটোমেটিক এইসব মার্কারের মধ্যে থাকা সবকিছু পরিবর্তন করে দেয়। - Cumulative Layout Shift (CLS) কমান: প্লেসহোল্ডারের জন্য সবসময় স্টেবল ডাইমেনশন প্রদান করুন। কন্টেন্টের চূড়ান্ত সাইজ জানা না থাকলে, জায়গা রিজার্ভ করতে এবং আকস্মিক শিফ্ট প্রতিরোধ করতে স্কেলিটন স্ক্রিন বা CSS
aspect-ratioব্যবহার করুন। - অ্যাক্সেসিবিলিটি ও ফোকাস ম্যানেজমেন্ট: মনে রাখবেন যে আউট-অফ-অর্ডার আপডেট স্ক্রিন রিডার ব্যবহারকারীদের বিভ্রান্ত করতে পারে। গুরুত্বপূর্ণ আপডেটের জন্য
aria-liveরিজিয়ন ব্যবহার করুন এবং অ্যাক্টিভ এলিমেন্ট সহ প্লেসহোল্ডার পরিবর্তন করা হলে ফোকাস যাতে হারিয়ে না যায় তা নিশ্চিত করুন।
প্রয়োগ সংক্রান্ত বিবরণ
১. ডিক্লারেটিভ HTML মার্কার
কন্টেন্ট কোথায় প্যাচ করতে হবে তা শনাক্ত করার জন্য ব্রাউজার নির্দিষ্ট প্রসেসিং নির্দেশাবলী খোঁজে।
<!-- A simple insertion point -->
<div id="sidebar">
<?marker name="dynamic-comments">
</div>
<!-- A replacement range with loading state -->
<main>
<?start name="main-content">
<div class="skeleton">Loading content...</div>
<?end>
</main>
... (other content) ...
<!-- Later in the same stream, provide the content -->
<template for="dynamic-comments">
<div class="comments">...</div>
</template>
<template for="main-content">
<article>
<h1>The Real Content</h1>
<p>This replaces the skeleton div automatically.</p>
</article>
</template>
<template> কোনও ইনসার্শন পয়েন্টকে রিপ্লেস করলে, সেই ইনসার্শন পয়েন্ট আর থাকে না এবং সেটি আবার ব্যবহার করা যায় না। তবে, <template>-এ ইনসার্শন পয়েন্ট থাকতে পারে যা পরে স্ট্রিমে ব্যবহার করা যেতে পারে।
<?start name="replaced-content">
<div class="skeleton">
<?end>
<!-- Later in the same stream, provide initial content -->
<template for="replaced-content">
<?start name="replaced-content">
<div>Quickly computed result</div>
<?end>
</template>
<!-- Later in the same stream, provide full content -->
<template for="replaced-content">
<?start name="replaced-content">
<div>Full result</div>
<?end>
</template>
২. ইমপ্যারেটিভ JS স্ট্রিমিং
ব্রাউজার ২৪টি পদ্ধতির (৬টি অ্যাকশন, প্রতিটির ৪টি ভেরিয়েশন) একটি স্যুট প্রদান করে যাতে স্ট্যাটিক্যালি (স্ট্রিং থেকে) বা স্ট্রিমের মাধ্যমে DOM আপডেট করা যায়।
API রেফারেন্স ম্যাট্রিক্স
| অ্যাকশন | স্ট্যাটিক (নিরাপদ) | স্ট্রিমিং (নিরাপদ) | স্ট্যাটিক (অসুরক্ষিত) | স্ট্রিমিং (অসুরক্ষিত) |
|---|---|---|---|---|
| সেট করুন | setHTML() |
streamHTML() |
setHTMLUnsafe() |
streamHTMLUnsafe() |
| বদল করুন | replaceWithHTML() |
streamReplaceWithHTML() |
replaceWithHTMLUnsafe() |
streamReplaceWithHTMLUnsafe() |
| আগে | beforeHTML() |
streamBeforeHTML() |
beforeHTMLUnsafe() |
streamBeforeHTMLUnsafe() |
| প্রিপেন্ড করুন | prependHTML() |
streamPrependHTML() |
prependHTMLUnsafe() |
streamPrependHTMLUnsafe() |
| শেষে যোগ করুন | appendHTML() |
streamAppendHTML() |
appendHTMLUnsafe() |
streamAppendHTMLUnsafe() |
| পরে | afterHTML() |
streamAfterHTML() |
afterHTMLUnsafe() |
streamAfterHTMLUnsafe() |
মূল ধারণা
- নিরাপদ বনাম অনিরাপদ:
- নিরাপদ পদ্ধতি (যেমন,
setHTML()) ডিফল্ট হিসেবে বিল্ট-ইন স্যানিটাইজার ব্যবহার করে যাতে<script>ট্যাগের মতো সম্ভাব্য বিপজ্জনক কন্টেন্ট বাদ দেওয়া যায়। ডিফল্ট স্যানিটাইজার ছাড়াও, আপনি বিকল্পে কাস্টমSanitizerঅবজেক্ট পাস করতে পারবেন। - অসুরক্ষিত মেথড (যেমন,
setHTMLUnsafe()) ডিফল্ট হিসেবে স্যানিটাইজ করে না, তবে আপনি এখনও কাস্টমSanitizerপাস করতে পারবেন। নতুন কন্টেন্টে স্ক্রিপ্ট এক্সিকিউট করার অনুমতি দিতে, আপনাকে অবশ্যই বিকল্পে{ runScripts: true }পাস করতে হবে। গুরুত্বপূর্ণ: নিরাপদ পদ্ধতি কাজ না করলে, শুধুমাত্র বিশ্বস্ত কন্টেন্টের ক্ষেত্রে অসুরক্ষিত পদ্ধতি ব্যবহার করুন।
- নিরাপদ পদ্ধতি (যেমন,
- স্ট্যাটিক বনাম স্ট্রিমিং:
- Static মেথড একটি স্ট্রিং (বা
TrustedHTML) নেয় এবং অবিলম্বে এটি প্রয়োগ করে। - স্ট্রিমিং পদ্ধতি
WritableStreamরিটার্ন করে। এটি আপনাকে সরাসরি DOM-এ কন্টেন্ট (যেমন,fetch-এর উত্তর থেকে) পাইপ করার অনুমতি দেয় এবং ব্রাউজারটি চাঙ্ক আসার সাথে সাথে এটিকে ক্রমবর্ধমানভাবে রেন্ডার করবে।
- Static মেথড একটি স্ট্রিং (বা
উদাহরণ: ফেচ রেসপন্স স্ট্রিম করা হচ্ছে
আপনি ম্যানুয়ালি চাঙ্ক ম্যানেজ না করেই সরাসরি DOM-এ ফেচ রেসপন্স পাইপ করতে পারবেন।
const main = document.querySelector('main');
const response = await fetch('/api/partial-update');
// Pipe the stream directly into the element
await response.body
.pipeThrough(new TextDecoderStream())
.pipeTo(main.streamHTMLUnsafe({ runScripts: true }));
// Or use the `textStream()` convenience method which streams directly without needing the intermediate `TextDecoderStream()` step
await response
.textStream()
.pipeTo(main.streamHTMLUnsafe({ runScripts: true }))
ব্যবহারের উদাহরণ সংক্রান্ত রেফারেন্স ম্যাট্রিক্স
- আইল্যান্ড আর্কিটেকচার: সম্পূর্ণ ফ্রেমওয়ার্ক রানটাইম ছাড়াই স্ট্যাটিক HTML-এর উপরে স্বাধীন ইন্ট্যার্যাক্টিভ কম্পোনেন্ট হাইড্রেট করুন।
- বিলম্বিত "এক্সপেনসিভ" ব্লক: কোনও পৃষ্ঠার শেল অবিলম্বে ডেলিভার করুন এবং ডেটাবেস-হেভি কম্পোনেন্ট উপলভ্য হওয়ার সাথে সাথে স্ট্রিম করুন।
- সিঙ্গেল পেজ অ্যাপ্লিকেশন (SPA) আপডেট: সম্পূর্ণ JSON পেলোড এবং ম্যানুয়াল DOM কনস্ট্রাকশনের জন্য অপেক্ষা করার পরিবর্তে
streamHTML()ব্যবহার করে SPA-তে বড় UI ট্রানজিশন স্ট্রিম করুন।
অ্যান্টি-প্যাটার্ন ও সতর্কতা (এটি করবেন না)
- সবকিছুর জন্য OOO স্ট্রিমিং ব্যবহার করবেন না। কোনও পৃষ্ঠা অতিরিক্ত ফ্র্যাগমেন্ট করলে, স্ট্রিমের জটিলতা বেড়ে যেতে পারে এবং ব্রাউজার ছোট নোড প্যাচ করতে অনেক বেশি সময় নিলে কন্টেন্ট দেখাতে দেরি হতে পারে।
- বিশ্বস্ত প্রকার উপেক্ষা করবেন না। বিশ্বস্ত প্রকার এনফোর্স করা আছে এমন পরিবেশে
*Unsafeপদ্ধতি ব্যবহার করার সময়, প্রয়োজন হলে আপনি স্যানিটাইজ করা নীতি অবজেক্ট পাস করছেন কিনা তা নিশ্চিত করুন। - স্ক্রিপ্ট এক্সিকিউশন অর্ডার অনুমান করবেন না।
<template for>-এর মধ্যে থাকা স্ক্রিপ্ট ডকুমেন্টে প্যাচ করা মাত্রই রান করবে। অন্যান্য বিলম্বিত টেমপ্লেটের সাপেক্ষে নির্দিষ্ট ক্রমে সেগুলি কার্যকর করার উপর নির্ভর করবেন না। - পলিফিল স্ট্র্যাটেজি ছাড়া ব্যবহার করবেন না। এই ফিচার বেসলাইন না হওয়া পর্যন্ত আপনার প্রয়োজনীয় ব্রাউজার যাতে কাজ করে তার জন্য ফলব্যাক বা পলিফিল (
html-setters-polyfillএবংtemplate-for-polyfill) ব্যবহার করুন।
ফলব্যাক স্ট্র্যাটেজি
যেসব ব্রাউজার API সারফেস সাপোর্ট করে না, সেগুলির জন্য আপনি template-for-polyfill এবং html-setters-polyfill-এর মতো পলিফিল ব্যবহার করতে পারেন।
html-processing-instructions সাপোর্ট করে না এমন ব্রাউজার <?marker>, <?start> এবং <?end>-কে কমেন্ট হিসেবে পার্স করে। template-for-polyfill এখনও এই কমেন্টগুলিকে মার্কার হিসেবে শনাক্ত করে, তাই সব ব্রাউজারের জন্য একই প্রসেসিং নির্দেশাবলী সিনট্যাক্স রাখুন। যেসব ব্রাউজারে কাজ করে না সেগুলির জন্য HTML কমেন্ট বা এলিমেন্ট হিসেবে মার্কার আবার লিখবেন না।