ব্রাউজার প্রিলোড স্ক্যানার কী, এটি কীভাবে পারফরম্যান্স উন্নত করতে সাহায্য করে এবং কীভাবে আপনি এর হস্তক্ষেপ এড়াতে পারেন, তা জেনে নিন।
পেজের গতি অপ্টিমাইজ করার একটি উপেক্ষিত দিক হলো ব্রাউজারের অভ্যন্তরীণ কার্যপ্রণালী সম্পর্কে কিছুটা জানা। ব্রাউজারগুলো পারফরম্যান্স উন্নত করার জন্য এমন কিছু অপ্টিমাইজেশন করে যা আমরা ডেভেলপাররা করতে পারি না—তবে তা কেবল তখনই সম্ভব, যখন সেই অপ্টিমাইজেশনগুলো অনিচ্ছাকৃতভাবে ব্যাহত না হয়।
ব্রাউজারের একটি অভ্যন্তরীণ অপটিমাইজেশন যা বোঝা প্রয়োজন, তা হলো ব্রাউজার প্রিলোড স্ক্যানার। এই পোস্টে আলোচনা করা হবে প্রিলোড স্ক্যানার কীভাবে কাজ করে—এবং আরও গুরুত্বপূর্ণভাবে, কীভাবে আপনি এর কাজে বাধা দেওয়া এড়াতে পারেন।
প্রিলোড স্ক্যানার বলতে কী বোঝায়?
প্রতিটি ব্রাউজারে একটি প্রাথমিক HTML পার্সার থাকে যা মূল মার্কআপকে টোকেনাইজ করে এবং সেটিকে একটি অবজেক্ট মডেলে রূপান্তর করে। এই প্রক্রিয়াটি নির্বিঘ্নে চলতে থাকে যতক্ষণ না পার্সারটি কোনো বাধা সৃষ্টিকারী রিসোর্স খুঁজে পায়, যেমন <link> এলিমেন্ট দিয়ে লোড করা স্টাইলশিট, অথবা async বা defer অ্যাট্রিবিউট ছাড়া <script> এলিমেন্ট দিয়ে লোড করা স্ক্রিপ্ট।
<link> এলিমেন্টের সম্মুখীন হয়, যা সিএসএস ফাইলটি ডাউনলোড ও পার্স না হওয়া পর্যন্ত ব্রাউজারকে ডকুমেন্টের বাকি অংশ পার্স করা—এমনকি এর কোনো অংশ রেন্ডার করা—থেকেও ব্লক করে দেয়।CSS ফাইলের ক্ষেত্রে, ' ফ্ল্যাশ অফ আনস্টাইলড কন্টেন্ট' (FOUC) প্রতিরোধ করার জন্য রেন্ডারিং ব্লক করা হয়। 'ফ্ল্যাশ অফ আনস্টাইলড কন্টেন্ট' হলো এমন একটি অবস্থা যখন কোনো পেজে স্টাইল প্রয়োগ করার আগে ক্ষণিকের জন্য সেটির একটি স্টাইলবিহীন সংস্করণ দেখা যায়।

যখন ব্রাউজার defer বা async অ্যাট্রিবিউট ছাড়া <script> এলিমেন্টের সম্মুখীন হয়, তখন এটি পেজটির পার্সিং এবং রেন্ডারিংও ব্লক করে দেয়।
এর কারণ হলো, মূল এইচটিএমএল পার্সার যখন তার কাজ চালিয়ে যাচ্ছে, তখন ব্রাউজার নিশ্চিতভাবে জানতে পারে না যে কোনো নির্দিষ্ট স্ক্রিপ্ট DOM পরিবর্তন করবে কি না। এই কারণেই ডকুমেন্টের শেষে জাভাস্ক্রিপ্ট লোড করা একটি প্রচলিত অভ্যাস, যাতে ব্লকড পার্সিং এবং রেন্ডারিং-এর প্রভাব নগণ্য হয়ে পড়ে।
ব্রাউজারের পার্সিং এবং রেন্ডারিং উভয়ই ব্লক করার পেছনে এগুলো যথেষ্ট কারণ। তবুও, এই গুরুত্বপূর্ণ ধাপগুলোর যেকোনো একটি ব্লক করা অনাকাঙ্ক্ষিত, কারণ এগুলো অন্যান্য গুরুত্বপূর্ণ রিসোর্স খুঁজে পেতে দেরি করিয়ে পুরো প্রক্রিয়াটিকে বাধাগ্রস্ত করতে পারে। সৌভাগ্যবশত, ব্রাউজারগুলো প্রিলোড স্ক্যানার নামক একটি সেকেন্ডারি এইচটিএমএল পার্সারের মাধ্যমে এই সমস্যাগুলো প্রশমিত করার জন্য যথাসাধ্য চেষ্টা করে।
<body> এলিমেন্টের ভেতরের ইমেজ মার্কআপ প্রসেস করা শুরু করার আগে CSS লোড ও প্রসেস করার জন্য ব্লক হয়ে যায়, কিন্তু প্রিলোড স্ক্যানারটি র মার্কআপের মধ্যে আগে থেকেই সেই ইমেজ রিসোর্সটি খুঁজে বের করতে পারে এবং প্রাইমারি এইচটিএমএল পার্সার আনব্লক হওয়ার আগেই তা লোড করা শুরু করতে পারে।একটি প্রিলোড স্ক্যানারের ভূমিকা হলো অনুমানমূলক , যার অর্থ হলো এটি মূল এইচটিএমএল পার্সারের খুঁজে পাওয়ার আগেই সুযোগ বুঝে রিসোর্সগুলি খুঁজে বের করার জন্য কাঁচা মার্কআপ পরীক্ষা করে।
প্রিলোড স্ক্যানার কখন কাজ করছে তা কীভাবে বুঝবেন
রেন্ডারিং এবং পার্সিং ব্লক হওয়ার কারণেই প্রিলোড স্ক্যানারের অস্তিত্ব রয়েছে। যদি এই দুটি পারফরম্যান্স সমস্যা না থাকত, তাহলে প্রিলোড স্ক্যানার খুব একটা কার্যকর হতো না। কোনো ওয়েব পেজ প্রিলোড স্ক্যানার থেকে উপকৃত হবে কি না, তা বোঝার মূল চাবিকাঠি হলো এই ব্লকিং ঘটনাগুলো। এটি করার জন্য, প্রিলোড স্ক্যানারটি কোথায় কাজ করছে তা খুঁজে বের করতে আপনি রিকোয়েস্টগুলোর জন্য একটি কৃত্রিম বিলম্ব যোগ করতে পারেন।
স্টাইলশীটসহ সাধারণ টেক্সট ও ছবিযুক্ত এই পৃষ্ঠাটিকে উদাহরণ হিসেবে নিন। যেহেতু CSS ফাইলগুলো রেন্ডারিং এবং পার্সিং উভয়কেই বাধা দেয়, তাই আপনি একটি প্রক্সি সার্ভিসের মাধ্যমে স্টাইলশীটটির জন্য দুই সেকেন্ডের একটি কৃত্রিম বিলম্ব তৈরি করেন। এই বিলম্বের ফলে নেটওয়ার্ক ওয়াটারফলে প্রিলোড স্ক্যানারটি কোথায় কাজ করছে তা দেখা সহজ হয়।

ওয়াটারফলে যেমন দেখতে পাচ্ছেন, রেন্ডারিং এবং ডকুমেন্ট পার্সিং ব্লক থাকা অবস্থাতেও প্রিলোড স্ক্যানার <img> এলিমেন্টটি খুঁজে পায়। এই অপটিমাইজেশনটি ছাড়া, ব্রাউজার ব্লকিং পিরিয়ডের সময় সুযোগ বুঝে বিভিন্ন জিনিস ফেচ করতে পারে না, এবং রিসোর্সের জন্য আরও বেশি অনুরোধ যুগপৎ না হয়ে ধারাবাহিক হতে থাকে।
এই খেলনা-সদৃশ উদাহরণটি বাদ দিয়ে, চলুন বাস্তব জগতের এমন কিছু ধরণ দেখে নেওয়া যাক যেখানে প্রিলোড স্ক্যানারকে অকার্যকর করা যায়—এবং সেগুলো সমাধানের জন্য কী করা যেতে পারে।
ইনজেক্টেড async স্ক্রিপ্ট
ধরা যাক, আপনার <head> ট্যাগে এমন HTML আছে যাতে এইরকম কিছু ইনলাইন জাভাস্ক্রিপ্ট অন্তর্ভুক্ত রয়েছে:
<script>
const scriptEl = document.createElement('script');
scriptEl.src = '/yall.min.js';
document.head.appendChild(scriptEl);
</script>
ইনজেক্টেড স্ক্রিপ্টগুলো ডিফল্টভাবে async হয়, তাই যখন এই স্ক্রিপ্টটি ইনজেক্ট করা হয়, তখন এটি এমনভাবে আচরণ করবে যেন এতে async অ্যাট্রিবিউটটি প্রয়োগ করা হয়েছে। এর মানে হলো, এটি যত তাড়াতাড়ি সম্ভব রান করবে এবং রেন্ডারিং ব্লক করবে না। বেশ ভালো শোনাচ্ছে, তাই না? কিন্তু, যদি আপনি ধরে নেন যে এই ইনলাইন <script> এমন একটি <link> এলিমেন্টের পরে এসেছে যা একটি এক্সটার্নাল CSS ফাইল লোড করে, তাহলে আপনি একটি নিম্নমানের ফলাফল পাবেন:

async স্ক্রিপ্ট রয়েছে। রেন্ডার ব্লকিং পর্যায়ে প্রিলোড স্ক্যানারটি স্ক্রিপ্টটি খুঁজে পায় না, কারণ এটি ক্লায়েন্টে ইনজেক্ট করা হয়েছে।চলুন এখানে কী ঘটেছে তা বিশ্লেষণ করা যাক:
- ০ সেকেন্ডে মূল নথিটি অনুরোধ করা হয়।
- ১.৪ সেকেন্ডে নেভিগেশন অনুরোধের প্রথম বাইটটি এসে পৌঁছায়।
- ২.০ সেকেন্ডে CSS এবং ইমেজটির জন্য অনুরোধ করা হয়।
- যেহেতু পার্সারটি স্টাইলশিট লোড করতে গিয়ে আটকে যায় এবং
asyncস্ক্রিপ্টটি ইনজেক্ট করা ইনলাইন জাভাস্ক্রিপ্টটি সেই স্টাইলশিটের পরে ২.৬ সেকেন্ডে আসে, তাই স্ক্রিপ্টটি যে কার্যকারিতা প্রদান করে তা যত দ্রুত সম্ভব পাওয়া যায় না।
এটি সর্বোত্তম নয়, কারণ স্টাইলশিটটি ডাউনলোড শেষ হওয়ার পরেই স্ক্রিপ্টের জন্য অনুরোধটি করা হয়। এর ফলে স্ক্রিপ্টটি যত দ্রুত সম্ভব চলতে দেরি হয়। এর বিপরীতে, যেহেতু <img> এলিমেন্টটি সার্ভার-প্রদত্ত মার্কআপে শনাক্তযোগ্য, তাই এটি প্রিলোড স্ক্যানার দ্বারা খুঁজে পাওয়া যায়।
তাহলে, স্ক্রিপ্টটিকে DOM-এ ইনজেক্ট করার পরিবর্তে async অ্যাট্রিবিউটসহ একটি সাধারণ <script> ট্যাগ ব্যবহার করলে কী হয়?
<script src="/yall.min.js" async></script>
এই হলো ফলাফল:

async <script> এলিমেন্ট রয়েছে। প্রিলোড স্ক্যানারটি রেন্ডার ব্লকিং পর্যায়ে স্ক্রিপ্টটি শনাক্ত করে এবং সিএসএস-এর সাথে একযোগে এটি লোড করে। এমন পরামর্শ দেওয়ার একটি প্রলোভন থাকতে পারে যে rel=preload ব্যবহার করে এই সমস্যাগুলোর প্রতিকার করা যেতে পারে। এটি অবশ্যই কাজ করবে, কিন্তু এর কিছু পার্শ্বপ্রতিক্রিয়া থাকতে পারে। সর্বোপরি, যে সমস্যাটি DOM-এ একটি <script> এলিমেন্ট যুক্ত না করেই এড়ানো যায়, তা ঠিক করার জন্য rel=preload কেন ব্যবহার করা হবে?

async স্ক্রিপ্ট রয়েছে, কিন্তু async স্ক্রিপ্টটি আগে থেকেই লোড করা থাকে যাতে এটি দ্রুত খুঁজে পাওয়া যায়। প্রি-লোডিং এখানে সমস্যাটির সমাধান করে, কিন্তু এটি একটি নতুন সমস্যা তৈরি করে: প্রথম দুটি ডেমোতে async স্ক্রিপ্টটি <head> ট্যাগের মধ্যে লোড হওয়া সত্ত্বেও "Low" প্রায়োরিটিতে লোড হয়, যেখানে স্টাইলশিটটি "Highest" প্রায়োরিটিতে লোড হয়। শেষ ডেমোটিতে, যেখানে async স্ক্রিপ্টটি প্রি-লোড করা হয়েছে, সেখানেও স্টাইলশিটটি "Highest" প্রায়োরিটিতে লোড হয়, কিন্তু স্ক্রিপ্টটির প্রায়োরিটি বেড়ে "High" হয়ে যায়।
যখন কোনো রিসোর্সের প্রায়োরিটি বাড়ানো হয়, তখন ব্রাউজার সেটির জন্য আরও বেশি ব্যান্ডউইথ বরাদ্দ করে। এর মানে হলো—যদিও স্টাইলশিটটির প্রায়োরিটি সর্বোচ্চ, স্ক্রিপ্টটির এই বর্ধিত প্রায়োরিটির কারণে ব্যান্ডউইথ নিয়ে প্রতিযোগিতা তৈরি হতে পারে। ধীরগতির সংযোগে, অথবা রিসোর্সগুলো বেশ বড় হলে এটি একটি সমস্যা হয়ে দাঁড়াতে পারে।
এর উত্তরটা খুবই সহজ: স্টার্টআপের সময় যদি কোনো স্ক্রিপ্টের প্রয়োজন হয়, তবে সেটিকে DOM-এ ইনজেক্ট করে প্রিলোড স্ক্যানারকে অকার্যকর করবেন না। প্রয়োজন অনুযায়ী <script> এলিমেন্টের অবস্থান এবং defer ও async মতো অ্যাট্রিবিউটগুলো নিয়ে পরীক্ষা-নিরীক্ষা করুন।
জাভাস্ক্রিপ্ট দিয়ে লেজি লোডিং
লেজি লোডিং ডেটা সংরক্ষণের একটি চমৎকার পদ্ধতি, যা প্রায়শই ছবির ক্ষেত্রে প্রয়োগ করা হয়। তবে, কখনও কখনও লেজি লোডিং ভুলভাবে সেইসব ছবিতে প্রয়োগ করা হয় যেগুলো স্ক্রিনের উপরের অংশে (above the fold) থাকে।
এটি প্রিলোড স্ক্যানারের ক্ষেত্রে রিসোর্স খুঁজে পাওয়ার বিষয়ে সম্ভাব্য সমস্যা তৈরি করে এবং একটি ছবির রেফারেন্স খুঁজে বের করা, ডাউনলোড করা, ডিকোড করা ও উপস্থাপন করার সময়কে অপ্রয়োজনীয়ভাবে বিলম্বিত করতে পারে। উদাহরণস্বরূপ এই ছবির মার্কআপটি দেখা যাক:
<img data-src="/sand-wasp.jpg" alt="Sand Wasp" width="384" height="255">
জাভাস্ক্রিপ্ট-চালিত লেজি লোডারগুলিতে ' data- প্রিফিক্সের ব্যবহার একটি প্রচলিত রীতি। যখন ছবিটি স্ক্রল করে ভিউপোর্টে আসে, তখন লেজি লোডারটি data- প্রিফিক্সটি সরিয়ে দেয়, যার ফলে পূর্ববর্তী উদাহরণে ' data-src হয়ে যায় src '। এই পরিবর্তনটি ব্রাউজারকে রিসোর্সটি ফেচ করতে উৎসাহিত করে।
এই প্যাটার্নটি ততক্ষণ পর্যন্ত সমস্যাজনক নয়, যতক্ষণ না এটি স্টার্টআপের সময় ভিউপোর্টে থাকা ইমেজগুলোর ক্ষেত্রে প্রয়োগ করা হয়। যেহেতু প্রিলোড স্ক্যানারটি একটি src (বা srcset ) অ্যাট্রিবিউটের মতো করে data-src অ্যাট্রিবিউটটি পড়ে না, তাই ইমেজ রেফারেন্সটি আগে থেকে খুঁজে পাওয়া যায় না। আরও খারাপ ব্যাপার হলো, লেজি লোডার জাভাস্ক্রিপ্ট ডাউনলোড, কম্পাইল এবং এক্সিকিউট হওয়ার পর পর্যন্ত ইমেজটি লোড হতে দেরি হয়।

ইমেজের আকারের উপর নির্ভর করে—যা আবার ভিউপোর্টের আকারের উপর নির্ভরশীল হতে পারে—এটি লার্জেস্ট কন্টেন্টফুল পেইন্ট (LCP)- এর জন্য একটি সম্ভাব্য এলিমেন্ট হতে পারে। যখন প্রিলোড স্ক্যানার আগে থেকে অনুমানমূলকভাবে ইমেজ রিসোর্সটি ফেচ করতে পারে না—সম্ভবত সেই মুহূর্তে যখন পেজের স্টাইলশিটগুলো রেন্ডারিং আটকে দেয়—তখন LCP ব্যাহত হয়।
সমাধানটি হলো ছবির মার্কআপ পরিবর্তন করা:
<img src="/sand-wasp.jpg" alt="Sand Wasp" width="384" height="255">
স্টার্টআপের সময় ভিউপোর্টে থাকা ছবিগুলোর জন্য এটিই সর্বোত্তম প্যাটার্ন, কারণ প্রিলোড স্ক্যানারটি ছবির রিসোর্সটি আরও দ্রুত খুঁজে বের করে নিয়ে আসবে।

এই সরলীকৃত উদাহরণে, একটি ধীরগতির সংযোগে LCP-তে ১০০ মিলিসেকেন্ডের উন্নতি দেখা যায়। এটিকে হয়তো খুব বড় উন্নতি বলে মনে নাও হতে পারে, কিন্তু যখন আপনি বিবেচনা করবেন যে এই সমাধানটি একটি দ্রুত মার্কআপ সংশোধন এবং বেশিরভাগ ওয়েব পেজই এই উদাহরণগুলোর চেয়ে অনেক বেশি জটিল, তখন এটি একটি উল্লেখযোগ্য উন্নতি। এর মানে হলো, LCP ক্যান্ডিডেটদেরকে ব্যান্ডউইথের জন্য অন্যান্য অনেক রিসোর্সের সাথে প্রতিযোগিতা করতে হতে পারে, তাই এই ধরনের অপটিমাইজেশনগুলো ক্রমশ গুরুত্বপূর্ণ হয়ে ওঠে।
CSS ব্যাকগ্রাউন্ড ইমেজ
মনে রাখবেন যে ব্রাউজার প্রিলোড স্ক্যানার মার্কআপ স্ক্যান করে। এটি অন্যান্য রিসোর্স টাইপ স্ক্যান করে না, যেমন CSS, যেখানে background-image প্রপার্টি দ্বারা রেফারেন্স করা ছবি ফেচ করার প্রয়োজন হতে পারে।
এইচটিএমএল-এর মতোই, ব্রাউজারগুলো সিএসএস-কে তার নিজস্ব অবজেক্ট মডেলে প্রসেস করে, যা সিএসএসওএম (CSSOM) নামে পরিচিত। সিএসএসওএম তৈরির সময় যদি কোনো বাহ্যিক রিসোর্স আবিষ্কৃত হয়, তবে সেই রিসোর্সগুলো আবিষ্কারের সময়েই অনুরোধ করা হয়, প্রিলোড স্ক্যানারের মাধ্যমে নয়।
ধরা যাক, আপনার পেজের LCP ক্যান্ডিডেট হলো এমন একটি এলিমেন্ট যার একটি CSS background-image প্রপার্টি আছে। রিসোর্সগুলো লোড হওয়ার সময় নিম্নলিখিত ঘটনাগুলো ঘটে:

background-image প্রপার্টিযুক্ত একটি এলিমেন্ট (সারি ৩)। CSS পার্সার ইমেজটি খুঁজে না পাওয়া পর্যন্ত এর অনুরোধ করা ইমেজটি ফেচ করা শুরু হয় না। এক্ষেত্রে, প্রিলোড স্ক্যানারটি অকার্যকর হয়ে যায় না, বরং এটি নিষ্ক্রিয় থাকে। তা সত্ত্বেও, যদি পৃষ্ঠার কোনো LCP ক্যান্ডিডেট একটি background-image CSS প্রপার্টি থেকে আসে, তবে আপনি সেই ছবিটি প্রিলোড করতে চাইবেন:
<!-- 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 ইঙ্গিতটি ছোট, কিন্তু এটি ব্রাউজারকে স্বাভাবিকের চেয়ে দ্রুত ছবিটি খুঁজে পেতে সাহায্য করে:

background-image প্রপার্টিযুক্ত একটি এলিমেন্ট (সারি ৩)। rel=preload হিন্টটি ব্রাউজারকে হিন্টটি ছাড়া অবস্থার চেয়ে প্রায় ২৫০ মিলিসেকেন্ড আগে ছবিটি খুঁজে পেতে সাহায্য করে। rel=preload হিন্টটি ব্যবহার করলে LCP ক্যান্ডিডেটটি দ্রুত খুঁজে পাওয়া যায়, ফলে LCP টাইম কমে আসে। যদিও এই হিন্টটি সমস্যাটি সমাধানে সাহায্য করে, তবে আরও ভালো বিকল্প হতে পারে আপনার ইমেজ LCP ক্যান্ডিডেটটি CSS থেকে লোড করার প্রয়োজন আছে কি না তা মূল্যায়ন করা। একটি <img> ট্যাগ ব্যবহার করলে, আপনি ভিউপোর্টের জন্য উপযুক্ত একটি ইমেজ লোড করার ক্ষেত্রে আরও বেশি নিয়ন্ত্রণ পাবেন এবং একই সাথে প্রিলোড স্ক্যানারকেও এটি খুঁজে বের করার সুযোগ দিতে পারবেন।
অনেক বেশি রিসোর্স ইনলাইন করা
ইনলাইনিং হলো HTML-এর ভিতরে কোনো রিসোর্স স্থাপন করার একটি পদ্ধতি। আপনি <style> এলিমেন্টের মধ্যে স্টাইলশীট, <script> এলিমেন্টের মধ্যে স্ক্রিপ্ট এবং base64 এনকোডিং ব্যবহার করে কার্যত অন্য যেকোনো রিসোর্স ইনলাইন করতে পারেন।
রিসোর্স ডাউনলোড করার চেয়ে ইনলাইন করা দ্রুততর হতে পারে, কারণ এর জন্য আলাদা কোনো অনুরোধ পাঠানো হয় না। এটি সরাসরি ডকুমেন্টের মধ্যেই থাকে এবং তাৎক্ষণিকভাবে লোড হয়। তবে, এর কিছু উল্লেখযোগ্য অসুবিধা রয়েছে:
- আপনি যদি আপনার HTML ক্যাশ না করেন—এবং HTML রেসপন্স ডাইনামিক হলে তা করা সম্ভবও নয়—তাহলে ইনলাইন করা রিসোর্সগুলো কখনোই ক্যাশ হয় না। এটি পারফরম্যান্সকে প্রভাবিত করে, কারণ ইনলাইন করা রিসোর্সগুলো পুনঃব্যবহারযোগ্য নয়।
- এইচটিএমএল ক্যাশ করা গেলেও, ইনলাইন করা রিসোর্সগুলো ডকুমেন্টগুলোর মধ্যে শেয়ার করা হয় না। এর ফলে, এক্সটার্নাল ফাইলের তুলনায় ক্যাশিংয়ের কার্যকারিতা কমে যায়, কারণ এক্সটার্নাল ফাইলগুলোকে একটি সম্পূর্ণ অরিজিন জুড়ে ক্যাশ করে পুনরায় ব্যবহার করা যায়।
- আপনি যদি অতিরিক্ত ইনলাইন করেন, তাহলে প্রি-লোড স্ক্যানারের পক্ষে ডকুমেন্টের পরবর্তী অংশের রিসোর্সগুলো খুঁজে বের করা বিলম্বিত হয়, কারণ সেই অতিরিক্ত ইনলাইন করা কন্টেন্ট ডাউনলোড করতে বেশি সময় লাগে।
এই পৃষ্ঠাটিকে উদাহরণ হিসেবে নিন। নির্দিষ্ট কিছু পরিস্থিতিতে, পৃষ্ঠার শীর্ষে থাকা ছবিটিই হলো LCP ক্যান্ডিডেট, এবং CSS একটি পৃথক ফাইলে থাকে যা একটি <link> এলিমেন্টের মাধ্যমে লোড করা হয়। পৃষ্ঠাটিতে চারটি ওয়েব ফন্টও ব্যবহৃত হয়েছে, যেগুলোকে CSS রিসোর্স থেকে পৃথক ফাইল হিসেবে অনুরোধ করা হয়।

<img> এলিমেন্ট থেকে লোড করা একটি ছবি, কিন্তু প্রিলোড স্ক্যানার এটিকে খুঁজে পায় কারণ পেজটির জন্য প্রয়োজনীয় CSS এবং ফন্টগুলো আলাদা রিসোর্সে লোড হয়, যা প্রিলোড স্ক্যানারের কাজ করতে কোনো বিলম্ব ঘটায় না।এখন কী হবে যদি CSS এবং সমস্ত ফন্টকে base64 রিসোর্স হিসেবে ইনলাইন করা হয়?

<img> এলিমেন্ট থেকে লোড করা একটি ছবি, কিন্তু `<img>` ট্যাগের মধ্যে CSS এবং এর চারটি ফন্ট রিসোর্সের ইনলাইনিং করা হয়েছে। যতক্ষণ না সেই রিসোর্সগুলো সম্পূর্ণরূপে ডাউনলোড হয়, ততক্ষণ পর্যন্ত এটি প্রিলোড স্ক্যানারকে ইমেজটি খুঁজে বের করতে বিলম্বিত করে।এই উদাহরণে ইনলাইনিংয়ের প্রভাব LCP-এর জন্য—এবং সাধারণভাবে পারফরম্যান্সের জন্যও—নেতিবাচক পরিণতি বয়ে আনে। পেজটির যে সংস্করণে কিছুই ইনলাইন করা হয় না, সেটি প্রায় ৩.৫ সেকেন্ডে LCP ছবিটি প্রদর্শন করে। অন্যদিকে, যে পেজটি সবকিছু ইনলাইন করে, সেটি ৭ সেকেন্ডের কিছু বেশি সময়ের আগে LCP ছবিটি প্রদর্শন করে না।
এখানে শুধু প্রিলোড স্ক্যানারের চেয়েও আরও অনেক কিছু জড়িত আছে। ফন্ট ইনলাইন করা খুব ভালো কৌশল নয়, কারণ বাইনারি রিসোর্সের জন্য বেস৬৪ একটি অদক্ষ ফরম্যাট। আরেকটি বিষয় হলো, এক্সটার্নাল ফন্ট রিসোর্সগুলো ততক্ষণ পর্যন্ত ডাউনলোড করা হয় না, যতক্ষণ না CSSOM সেগুলোকে প্রয়োজনীয় বলে নির্ধারণ করে। যখন সেই ফন্টগুলোকে বেস৬৪ হিসেবে ইনলাইন করা হয়, তখন বর্তমান পেজের জন্য সেগুলোর প্রয়োজন হোক বা না হোক, সেগুলো ডাউনলোড হয়ে যায়।
প্রিলোড কি এখানে অবস্থার উন্নতি করতে পারে? অবশ্যই। আপনি LCP ইমেজ প্রিলোড করে LCP-এর সময় কমাতে পারেন , কিন্তু ইনলাইন করা রিসোর্স দিয়ে আপনার সম্ভাব্য আনক্যাশেবল HTML-কে ভারাক্রান্ত করার অন্যান্য নেতিবাচক পারফরম্যান্স পরিণতি রয়েছে। ফার্স্ট কন্টেন্টফুল পেইন্ট (FCP) -ও এই প্যাটার্ন দ্বারা প্রভাবিত হয়। পেজটির যে সংস্করণে কিছুই ইনলাইন করা নেই, সেখানে FCP-এর সময় লাগে প্রায় ২.৭ সেকেন্ড। আর যে সংস্করণে সবকিছু ইনলাইন করা আছে, সেখানে FCP-এর সময় লাগে প্রায় ৫.৮ সেকেন্ড।
এইচটিএমএল-এ কোনো কিছু ইনলাইন করার ব্যাপারে খুব সতর্ক থাকুন, বিশেষ করে বেস৬৪-এনকোডেড রিসোর্সগুলোর ক্ষেত্রে। খুব ছোট রিসোর্স ছাড়া সাধারণত এটি করার পরামর্শ দেওয়া হয় না। যতটা সম্ভব কম ইনলাইন করুন, কারণ অতিরিক্ত ইনলাইন করা মানে আগুন নিয়ে খেলা করা।
ক্লায়েন্ট-সাইড জাভাস্ক্রিপ্ট দিয়ে মার্কআপ রেন্ডার করা
এতে কোনো সন্দেহ নেই যে, জাভাস্ক্রিপ্ট পেজের গতিকে নিশ্চিতভাবে প্রভাবিত করে । ডেভেলপাররা শুধু ইন্টারঅ্যাক্টিভিটি প্রদানের জন্যই এর উপর নির্ভর করে না, বরং সরাসরি কন্টেন্ট সরবরাহের জন্যও এর উপর নির্ভর করার একটি প্রবণতা দেখা গেছে। এটি কিছু ক্ষেত্রে ডেভেলপারদের জন্য উন্নততর অভিজ্ঞতা নিয়ে আসে; কিন্তু ডেভেলপারদের জন্য এই সুবিধাগুলো সবসময় ব্যবহারকারীদের জন্য সুবিধায় রূপান্তরিত হয় না।
একটি প্যাটার্ন যা প্রিলোড স্ক্যানারকে ফাঁকি দিতে পারে তা হলো ক্লায়েন্ট-সাইড জাভাস্ক্রিপ্ট দিয়ে মার্কআপ রেন্ডার করা:

যখন ব্রাউজারে মার্কআপ পেলোডগুলো জাভাস্ক্রিপ্টের মধ্যে থাকে এবং সম্পূর্ণরূপে জাভাস্ক্রিপ্ট দ্বারা রেন্ডার করা হয়, তখন সেই মার্কআপের মধ্যে থাকা যেকোনো রিসোর্স প্রিলোড স্ক্যানারের কাছে কার্যত অদৃশ্য থাকে। এর ফলে গুরুত্বপূর্ণ রিসোর্সগুলো খুঁজে পেতে দেরি হয়, যা নিশ্চিতভাবে LCP-কে প্রভাবিত করে। এই উদাহরণগুলোর ক্ষেত্রে, জাভাস্ক্রিপ্ট প্রদর্শিত হওয়ার প্রয়োজন হয় না এমন সমতুল্য সার্ভার-রেন্ডারড অভিজ্ঞতার তুলনায় LCP ইমেজের জন্য করা অনুরোধটি উল্লেখযোগ্যভাবে বিলম্বিত হয়।
এটি এই প্রবন্ধের মূল বিষয়বস্তু থেকে কিছুটা সরে যাচ্ছে, কিন্তু ক্লায়েন্টে মার্কআপ রেন্ডার করার প্রভাব শুধু প্রিলোড স্ক্যানারকে ফাঁকি দেওয়ার মধ্যেই সীমাবদ্ধ নয়। প্রথমত, এমন কোনো অভিজ্ঞতার জন্য জাভাস্ক্রিপ্ট ব্যবহার করা যেখানে এর প্রয়োজন নেই, তা অপ্রয়োজনীয় প্রসেসিং সময় তৈরি করে যা ইন্টারঅ্যাকশন টু নেক্সট পেইন্ট (INP)-কে প্রভাবিত করতে পারে। সার্ভার থেকে পাঠানো একই পরিমাণ মার্কআপের তুলনায় ক্লায়েন্টে অত্যন্ত বেশি পরিমাণে মার্কআপ রেন্ডার করলে দীর্ঘ সময় লাগার সম্ভাবনা বেশি থাকে। এর কারণ হলো—জাভাস্ক্রিপ্টের অতিরিক্ত প্রসেসিং ছাড়াও—ব্রাউজারগুলো সার্ভার থেকে মার্কআপ স্ট্রিম করে এবং রেন্ডারিংকে এমনভাবে খণ্ড খণ্ড করে ভাগ করে যা দীর্ঘ সময় লাগা কাজগুলোকে সীমিত রাখতে সাহায্য করে। অন্যদিকে, ক্লায়েন্টে রেন্ডার করা মার্কআপকে একটি একক, অখণ্ড কাজ হিসেবে বিবেচনা করা হয়, যা একটি পেজের INP-কে প্রভাবিত করতে পারে।
এই পরিস্থিতির প্রতিকার এই প্রশ্নের উত্তরের উপর নির্ভর করে: এমন কোনো কারণ আছে কি যার জন্য আপনার পেজের মার্কআপ ক্লায়েন্টে রেন্ডার না হয়ে সার্ভার থেকে সরবরাহ করা যাবে না? যদি এর উত্তর "না" হয়, তবে যেখানে সম্ভব সার্ভার-সাইড রেন্ডারিং (SSR) বা স্ট্যাটিক্যালি জেনারেটেড মার্কআপ বিবেচনা করা উচিত, কারণ এটি প্রিলোড স্ক্যানারকে সময়ের আগেই গুরুত্বপূর্ণ রিসোর্সগুলো খুঁজে বের করতে এবং সুযোগ বুঝে ফেচ করতে সাহায্য করবে।
আপনার পেজের মার্কআপের কিছু অংশে কার্যকারিতা যুক্ত করার জন্য যদি জাভাস্ক্রিপ্টের প্রয়োজন হয় , তবে আপনি SSR ব্যবহার করে তা করতে পারেন; হয় ভ্যানিলা জাভাস্ক্রিপ্ট দিয়ে, অথবা হাইড্রেশন ব্যবহার করে উভয় পদ্ধতির সেরা সুবিধা পেতে পারেন।
প্রিলোড স্ক্যানার আপনাকে সাহায্য করুক।
প্রিলোড স্ক্যানার একটি অত্যন্ত কার্যকর ব্রাউজার অপটিমাইজেশন যা স্টার্টআপের সময় পেজগুলোকে দ্রুত লোড হতে সাহায্য করে। যেসব প্যাটার্ন আগে থেকে গুরুত্বপূর্ণ রিসোর্স খুঁজে বের করার ক্ষমতাকে ব্যাহত করে, সেগুলো এড়িয়ে চলার মাধ্যমে আপনি শুধু নিজের জন্য ডেভেলপমেন্টকেই সহজ করছেন না, বরং আরও উন্নত ইউজার এক্সপেরিয়েন্স তৈরি করছেন যা কিছু ওয়েব ভাইটালস সহ বিভিন্ন মেট্রিক্সে আরও ভালো ফলাফল দেবে।
সংক্ষেপে, এই পোস্ট থেকে আপনি নিম্নলিখিত বিষয়গুলো মনে রাখতে চাইবেন:
- ব্রাউজার প্রিলোড স্ক্যানার হলো একটি সেকেন্ডারি এইচটিএমএল পার্সার, যা প্রাইমারি পার্সারটি ব্লক হয়ে গেলে তার আগেই স্ক্যান করে এমন রিসোর্স খুঁজে বের করে যা সে দ্রুত ফেচ করতে পারে।
- প্রাথমিক নেভিগেশন অনুরোধে সার্ভার কর্তৃক প্রদত্ত মার্কআপে যেসব রিসোর্স উপস্থিত থাকে না, সেগুলো প্রিলোড স্ক্যানার দ্বারা আবিষ্কৃত হতে পারে না। প্রিলোড স্ক্যানারকে অকার্যকর করার উপায়গুলোর মধ্যে অন্তর্ভুক্ত থাকতে পারে (তবে এগুলোতেই সীমাবদ্ধ নয়):
- জাভাস্ক্রিপ্ট ব্যবহার করে DOM-এ রিসোর্স যুক্ত করা, তা স্ক্রিপ্ট, ছবি, স্টাইলশিট বা অন্য যেকোনো কিছুই হোক না কেন, যা সার্ভার থেকে আসা প্রাথমিক মার্কআপ পেলোডে রাখাই শ্রেয়।
- জাভাস্ক্রিপ্ট সমাধান ব্যবহার করে অ্যাবাভ-দ্য-ফোল্ড ইমেজ বা আইফ্রেম লেজি লোডিং করা।
- জাভাস্ক্রিপ্ট ব্যবহার করে ক্লায়েন্টে এমন মার্কআপ রেন্ডার করা, যাতে ডকুমেন্ট সাবরিসোর্সের রেফারেন্স থাকতে পারে।
- প্রিলোড স্ক্যানার শুধুমাত্র HTML স্ক্যান করে। এটি অন্যান্য রিসোর্সের—বিশেষ করে CSS-এর—বিষয়বস্তু পরীক্ষা করে না, যেগুলোতে LCP ক্যান্ডিডেটসহ গুরুত্বপূর্ণ অ্যাসেটের রেফারেন্স থাকতে পারে।
যদি কোনো কারণে আপনি এমন কোনো প্যাটার্ন এড়াতে না পারেন যা প্রিলোড স্ক্যানারের লোডিং পারফরম্যান্স দ্রুত করার ক্ষমতাকে নেতিবাচকভাবে প্রভাবিত করে, rel=preload রিসোর্স হিন্টটি ব্যবহার করার কথা বিবেচনা করুন। যদি আপনি rel=preload ব্যবহার করেন , তবে এটি কাঙ্ক্ষিত ফল দিচ্ছে কিনা তা নিশ্চিত করতে ল্যাব টুলসে পরীক্ষা করে দেখুন। সবশেষে, খুব বেশি রিসোর্স প্রিলোড করবেন না, কারণ আপনি যখন সবকিছুকে অগ্রাধিকার দেবেন, তখন কোনো কিছুই অগ্রাধিকার পাবে না।
সম্পদ
- স্ক্রিপ্ট-ইনজেক্টেড 'অ্যাসিঙ্ক স্ক্রিপ্ট' ক্ষতিকর হিসেবে বিবেচিত
- ব্রাউজার প্রি-লোডার কীভাবে পেজ দ্রুত লোড করে
- লোডিং গতি উন্নত করতে গুরুত্বপূর্ণ সম্পদগুলি আগে থেকে লোড করুন।
- পেজের গতি উন্নত করতে আগেভাগেই নেটওয়ার্ক সংযোগ স্থাপন করুন।
- বৃহত্তম বিষয়বস্তুপূর্ণ পেইন্ট অপ্টিমাইজ করা
আনস্প্ল্যাশ থেকে নেওয়া প্রধান ছবিটি মোহাম্মদ রহমানীর তোলা।