ব্রাউজার প্রিলোড স্ক্যানারের সাথে লড়াই করবেন না৷

ব্রাউজার প্রিলোড স্ক্যানার কী, এটি কীভাবে পারফরম্যান্সে সহায়তা করে এবং কীভাবে আপনি এর থেকে দূরে থাকতে পারেন তা খুঁজে বের করুন।

পৃষ্ঠার গতি অপ্টিমাইজ করার একটি উপেক্ষিত দিক হল ব্রাউজার ইন্টারনাল সম্পর্কে কিছুটা জানা। ব্রাউজারগুলি পারফরম্যান্স উন্নত করার জন্য নির্দিষ্ট কিছু অপ্টিমাইজেশান করে যা আমরা বিকাশকারী হিসাবে পারি না-কিন্তু শুধুমাত্র ততক্ষণ পর্যন্ত যদি সেই অপ্টিমাইজেশনগুলি অনিচ্ছাকৃতভাবে ব্যর্থ না হয়৷

বোঝার জন্য একটি অভ্যন্তরীণ ব্রাউজার অপ্টিমাইজেশন হল ব্রাউজার প্রিলোড স্ক্যানার। এই পোস্টটি কভার করবে যে কীভাবে প্রিলোড স্ক্যানার কাজ করে — এবং আরও গুরুত্বপূর্ণভাবে, আপনি কীভাবে এর পথে আসা এড়াতে পারেন।

একটি প্রিলোড স্ক্যানার কি?

প্রতিটি ব্রাউজারে একটি প্রাথমিক HTML পার্সার থাকে যা কাঁচা মার্কআপকে টোকেনাইজ করে এবং এটিকে একটি অবজেক্ট মডেলে প্রসেস করে। এই সব আনন্দের সাথে চলতে থাকে যতক্ষণ না পার্সার একটি ব্লকিং রিসোর্স খুঁজে পায়, যেমন একটি <link> উপাদান দিয়ে লোড করা একটি স্টাইলশীট, অথবা একটি async বা defer অ্যাট্রিবিউট ছাড়াই একটি <script> উপাদান দিয়ে লোড করা স্ক্রিপ্ট।

HTML পার্সার ডায়াগ্রাম।
চিত্র 1: ব্রাউজারের প্রাথমিক HTML পার্সারকে কীভাবে ব্লক করা যায় তার একটি চিত্র। এই ক্ষেত্রে, পার্সার একটি বাহ্যিক CSS ফাইলের জন্য একটি <link> উপাদানে চলে, যা ব্রাউজারকে বাকি ডকুমেন্ট পার্স করতে বা এমনকি এটির যেকোনও রেন্ডারিং থেকে ব্লক করে- যতক্ষণ না CSS ডাউনলোড এবং পার্স করা হয়।

CSS ফাইলের ক্ষেত্রে, পার্সিং এবং রেন্ডারিং উভয়ই অবরুদ্ধ করা হয় যাতে একটি ফ্ল্যাশ অফ আনস্টাইলড কন্টেন্ট (FOUC) প্রতিরোধ করা হয়, যেটি হল যখন একটি পৃষ্ঠার স্টাইল না করা সংস্করণে শৈলী প্রয়োগ করার আগে সংক্ষিপ্তভাবে দেখা যায়।

web.dev হোম পেজ একটি স্টাইলবিহীন অবস্থায় (বামে) এবং স্টাইল করা অবস্থায় (ডানে)।
চিত্র 2: FOUC-এর একটি সিমুলেটেড উদাহরণ। বাঁদিকে স্টাইল ছাড়া web.dev-এর প্রথম পৃষ্ঠা। ডানদিকে শৈলী প্রয়োগ করা একই পৃষ্ঠা। স্টাইলশীট ডাউনলোড এবং প্রক্রিয়াকরণের সময় ব্রাউজার রেন্ডারিং ব্লক না করলে ফ্ল্যাশে আনস্টাইল না করা অবস্থা ঘটতে পারে।

ব্রাউজারটি পৃষ্ঠাটির পার্সিং এবং রেন্ডারিং ব্লক করে যখন এটি একটি defer বা async অ্যাট্রিবিউট ছাড়াই <script> উপাদানগুলির মুখোমুখি হয়।

এর কারণ হল ব্রাউজার নিশ্চিতভাবে জানতে পারে না যে কোনো প্রদত্ত স্ক্রিপ্ট DOM-কে পরিবর্তন করবে যখন প্রাথমিক HTML পার্সার এখনও তার কাজ করছে। এই কারণেই নথির শেষে আপনার জাভাস্ক্রিপ্ট লোড করা একটি সাধারণ অভ্যাস হয়েছে যাতে অবরুদ্ধ পার্সিং এবং রেন্ডারিংয়ের প্রভাবগুলি প্রান্তিক হয়ে যায়।

ব্রাউজার পার্সিং এবং রেন্ডারিং উভয়ই কেন ব্লক করবে তার জন্য এইগুলি ভাল কারণ। তবুও, এই গুরুত্বপূর্ণ পদক্ষেপগুলির যে কোনও একটিকে অবরুদ্ধ করা অবাঞ্ছিত, কারণ তারা অন্যান্য গুরুত্বপূর্ণ সংস্থানগুলি আবিষ্কারে বিলম্ব করে অনুষ্ঠানটি ধরে রাখতে পারে৷ সৌভাগ্যক্রমে, ব্রাউজারগুলি প্রিলোড স্ক্যানার নামে একটি সেকেন্ডারি HTML পার্সারের মাধ্যমে এই সমস্যাগুলি প্রশমিত করার জন্য যথাসাধ্য চেষ্টা করে৷

প্রাথমিক HTML পার্সার (বাম) এবং প্রিলোড স্ক্যানার (ডান) উভয়ের একটি ডায়াগ্রাম, যা সেকেন্ডারি HTML পার্সার।
চিত্র 3: প্রিলোড স্ক্যানার প্রাথমিক HTML পার্সারের সাথে অনুমানমূলকভাবে সম্পদ লোড করার জন্য সমান্তরালভাবে কীভাবে কাজ করে তা চিত্রিত করা একটি চিত্র। এখানে, প্রাথমিক এইচটিএমএল পার্সার ব্লক করা হয়েছে কারণ এটি <body> এলিমেন্টে ইমেজ মার্কআপ প্রসেসিং শুরু করার আগে CSS লোড এবং প্রসেস করে, কিন্তু প্রিলোড স্ক্যানার সেই ইমেজ রিসোর্সটি খুঁজে পেতে কাঁচা মার্কআপে এগিয়ে দেখতে পারে এবং এটি লোড করা শুরু করার আগে প্রাথমিক HTML পার্সার আনব্লক করা হয়েছে।

একটি প্রিলোড স্ক্যানারের ভূমিকা অনুমানমূলক , যার অর্থ প্রাথমিক এইচটিএমএল পার্সার অন্যথায় সেগুলি আবিষ্কার করার আগে সুবিধাবাদীভাবে আনার জন্য সংস্থানগুলি সন্ধান করার জন্য এটি কাঁচা মার্কআপ পরীক্ষা করে।

প্রিলোড স্ক্যানার কখন কাজ করছে তা কীভাবে বলবেন

প্রিলোড স্ক্যানারটি অবরুদ্ধ রেন্ডারিং এবং পার্সিংয়ের কারণে বিদ্যমান। যদি এই দুটি কর্মক্ষমতা সমস্যা বিদ্যমান না থাকে, তাহলে প্রিলোড স্ক্যানার খুব দরকারী হবে না। প্রিলোড স্ক্যানার থেকে একটি ওয়েব পৃষ্ঠা উপকৃত হয় কিনা তা খুঁজে বের করার চাবিকাঠি এই ব্লকিং ঘটনার উপর নির্ভর করে। এটি করার জন্য, আপনি প্রিলোড স্ক্যানার কোথায় কাজ করছে তা খুঁজে বের করার জন্য অনুরোধের জন্য একটি কৃত্রিম বিলম্ব প্রবর্তন করতে পারেন।

একটি উদাহরণ হিসাবে একটি স্টাইলশীট সহ মৌলিক পাঠ্য এবং চিত্রগুলির এই পৃষ্ঠাটি নিন। যেহেতু CSS ফাইলগুলি রেন্ডারিং এবং পার্সিং উভয়ই ব্লক করে, আপনি একটি প্রক্সি পরিষেবার মাধ্যমে স্টাইলশীটের জন্য দুই সেকেন্ডের কৃত্রিম বিলম্ব প্রবর্তন করেন। এই বিলম্ব নেটওয়ার্ক জলপ্রপাত যেখানে প্রিলোড স্ক্যানার কাজ করছে সেখানে দেখা সহজ করে তোলে।

WebPageTest নেটওয়ার্ক জলপ্রপাত চার্ট স্টাইলশীটে আরোপিত 2 সেকেন্ডের কৃত্রিম বিলম্বকে চিত্রিত করে।
চিত্র 4: একটি সিমুলেটেড 3G সংযোগের মাধ্যমে একটি মোবাইল ডিভাইসে Chrome এ চালানো একটি ওয়েব পৃষ্ঠার একটি WebPageTest নেটওয়ার্ক জলপ্রপাত চার্ট ৷ যদিও স্টাইলশীটটি লোড হতে শুরু করার আগে প্রক্সির মাধ্যমে কৃত্রিমভাবে দুই সেকেন্ড বিলম্বিত হয়, মার্কআপ পেলোডে পরে থাকা চিত্রটি প্রিলোড স্ক্যানার দ্বারা আবিষ্কৃত হয়।

আপনি জলপ্রপাতটিতে দেখতে পাচ্ছেন, প্রিলোড স্ক্যানার রেন্ডারিং এবং ডকুমেন্ট পার্সিং ব্লক থাকা অবস্থায়ও <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 ফাইল লোড করে, আপনি একটি সাবঅপ্টিমাল ফলাফল পাবেন:

এই WebPageTest চার্ট দেখায় যে একটি স্ক্রিপ্ট ইনজেকশন করা হলে প্রিলোড স্ক্যান পরাজিত হয়।
চিত্র 5: একটি সিমুলেটেড 3G সংযোগের মাধ্যমে একটি মোবাইল ডিভাইসে Chrome এ চালানো একটি ওয়েব পৃষ্ঠার একটি WebPageTest নেটওয়ার্ক জলপ্রপাত চার্ট৷ পৃষ্ঠাটিতে একটি একক স্টাইলশীট এবং একটি ইনজেক্টেড async স্ক্রিপ্ট রয়েছে৷ প্রিলোড স্ক্যানার রেন্ডার ব্লকিং পর্বের সময় স্ক্রিপ্টটি আবিষ্কার করতে পারে না, কারণ এটি ক্লায়েন্টে ইনজেকশন করা হয়।

আসুন এখানে কী ঘটেছিল তা ভেঙে দেওয়া যাক:

  1. 0 সেকেন্ডে, প্রধান নথি অনুরোধ করা হয়.
  2. 1.4 সেকেন্ডে, নেভিগেশন অনুরোধের প্রথম বাইট আসে।
  3. 2.0 সেকেন্ডে, CSS এবং ছবি অনুরোধ করা হয়।
  4. কারণ পার্সার স্টাইলশীট লোড করার সময় অবরুদ্ধ করা হয়েছে এবং ইনলাইন জাভাস্ক্রিপ্ট যা async স্ক্রিপ্টটি ইনজেক্ট করে সেই স্টাইলশীটের পরে 2.6 সেকেন্ডে আসে, স্ক্রিপ্ট যে কার্যকারিতা প্রদান করে তা যত তাড়াতাড়ি সম্ভব উপলব্ধ নয়।

এটি সাবঅপ্টিমাল কারণ স্ক্রিপ্টের জন্য অনুরোধ শুধুমাত্র স্টাইলশীট ডাউনলোড করা শেষ হলেই ঘটে। এটি যত তাড়াতাড়ি সম্ভব স্ক্রিপ্ট চালানো থেকে দেরি করে। বিপরীতে, কারণ সার্ভার-প্রদত্ত মার্কআপে <img> উপাদানটি আবিষ্কারযোগ্য, এটি প্রিলোড স্ক্যানার দ্বারা আবিষ্কৃত হয়।

তাহলে, কি হবে যদি আপনি ডম-এ স্ক্রিপ্ট ইনজেকশনের বিপরীতে async অ্যাট্রিবিউট সহ একটি নিয়মিত <script> ট্যাগ ব্যবহার করেন?

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

এই ফলাফল:

একটি WebPageTest নেটওয়ার্ক জলপ্রপাত চিত্রিত করে যে কীভাবে HTML স্ক্রিপ্ট উপাদান ব্যবহার করে লোড করা একটি অ্যাসিঙ্ক স্ক্রিপ্ট এখনও ব্রাউজার প্রিলোড স্ক্যানার দ্বারা আবিষ্কারযোগ্য, যদিও একটি স্টাইলশীট ডাউনলোড এবং প্রক্রিয়াকরণের সময় ব্রাউজারের প্রাথমিক HTML পার্সার ব্লক করা হয়।
চিত্র 6: একটি সিমুলেটেড 3G সংযোগের মাধ্যমে একটি মোবাইল ডিভাইসে Chrome এ চালানো একটি ওয়েব পৃষ্ঠার একটি WebPageTest নেটওয়ার্ক জলপ্রপাত চার্ট৷ পৃষ্ঠাটিতে একটি একক স্টাইলশীট এবং একটি একক async <script> উপাদান রয়েছে। প্রিলোড স্ক্যানার রেন্ডার ব্লকিং পর্বের সময় স্ক্রিপ্টটি আবিষ্কার করে এবং এটিকে একই সাথে CSS-এর সাথে লোড করে।

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

একটি ওয়েবপেজটেস্ট জলপ্রপাত দেখায় যে কীভাবে rel=preload রিসোর্স ইঙ্গিতটি একটি async ইনজেক্টেড স্ক্রিপ্টের আবিষ্কারকে উন্নীত করার জন্য ব্যবহার করা হয়—যদিও এমনভাবে যাতে অনাকাঙ্ক্ষিত পার্শ্বপ্রতিক্রিয়া থাকতে পারে।
চিত্র 7: একটি সিমুলেটেড 3G সংযোগের মাধ্যমে একটি মোবাইল ডিভাইসে Chrome এ চালানো একটি ওয়েব পৃষ্ঠার একটি WebPageTest নেটওয়ার্ক জলপ্রপাত চার্ট৷ পৃষ্ঠাটিতে একটি একক স্টাইলশীট এবং একটি ইনজেক্ট করা async স্ক্রিপ্ট রয়েছে, তবে async স্ক্রিপ্টটি আগে থেকে লোড করা হয়েছে যাতে এটি দ্রুত খুঁজে পাওয়া যায়।

প্রিলোড করা সমস্যাটি এখানে "সমাধান" করে, কিন্তু এটি একটি নতুন সমস্যা প্রবর্তন করে: প্রথম দুটি ডেমোতে async স্ক্রিপ্ট - <head> এ লোড হওয়া সত্ত্বেও - "নিম্ন" অগ্রাধিকারে লোড করা হয়, যেখানে স্টাইলশীটটি "সর্বোচ্চ" এ লোড হয় অগ্রাধিকার শেষ ডেমোতে যেখানে 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: একটি সিমুলেটেড 3G সংযোগের মাধ্যমে একটি মোবাইল ডিভাইসে Chrome এ চালানো একটি ওয়েব পৃষ্ঠার একটি WebPageTest নেটওয়ার্ক জলপ্রপাত চার্ট৷ ইমেজ রিসোর্সটি অপ্রয়োজনীয়ভাবে অলস-লোড হয়, যদিও এটি স্টার্টআপের সময় ভিউপোর্টে দৃশ্যমান হয়। এটি প্রিলোড স্ক্যানারকে পরাজিত করে এবং একটি অপ্রয়োজনীয় বিলম্ব ঘটায়।

চিত্রের আকারের উপর নির্ভর করে - যা ভিউপোর্টের আকারের উপর নির্ভর করতে পারে - এটি সবচেয়ে বড় বিষয়বস্তুর পেইন্ট (LCP) এর জন্য একটি প্রার্থী উপাদান হতে পারে। যখন প্রিলোড স্ক্যানার অনুমানমূলকভাবে সময়ের আগে ইমেজ রিসোর্স আনতে পারে না-সম্ভবত সেই সময়ে যেখানে পৃষ্ঠার স্টাইলশীট(গুলি) রেন্ডারিং ব্লক করা হয়-LCP ক্ষতিগ্রস্ত হয়।

সমাধান হল ইমেজ মার্কআপ পরিবর্তন করা:

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

এটি স্টার্টআপের সময় ভিউপোর্টে থাকা চিত্রগুলির জন্য সর্বোত্তম প্যাটার্ন, কারণ প্রিলোড স্ক্যানারটি আরও দ্রুত চিত্রের সংস্থান আবিষ্কার করবে এবং আনবে৷

একটি WebPageTest নেটওয়ার্ক জলপ্রপাত চার্ট স্টার্টআপের সময় ভিউপোর্টে একটি চিত্রের জন্য একটি লোডিং দৃশ্যকল্প চিত্রিত করে৷ চিত্রটি অলসভাবে লোড হয় না, যার অর্থ এটি লোড করার জন্য স্ক্রিপ্টের উপর নির্ভরশীল নয়, যার অর্থ প্রিলোড স্ক্যানার এটিকে তাড়াতাড়ি আবিষ্কার করতে পারে৷
চিত্র 9: একটি সিমুলেটেড 3G সংযোগের মাধ্যমে একটি মোবাইল ডিভাইসে Chrome এ চালানো একটি ওয়েব পৃষ্ঠার একটি WebPageTest নেটওয়ার্ক জলপ্রপাত চার্ট৷ প্রিলোড স্ক্যানার সিএসএস এবং জাভাস্ক্রিপ্ট লোড হওয়া শুরু করার আগে ইমেজ রিসোর্সটি আবিষ্কার করে, যা ব্রাউজারকে এটি লোড করা শুরু করে।

এই সরলীকৃত উদাহরণের ফলাফল হল একটি ধীর সংযোগে LCP-এ 100-মিলিসেকেন্ড উন্নতি৷ এটি একটি বিশাল উন্নতি বলে মনে নাও হতে পারে, কিন্তু আপনি যখন বিবেচনা করেন যে সমাধানটি একটি দ্রুত মার্কআপ ফিক্স, এবং বেশিরভাগ ওয়েব পৃষ্ঠাগুলি এই উদাহরণগুলির সেটের চেয়ে জটিল। এর মানে হল যে LCP প্রার্থীদের অন্যান্য অনেক সংস্থানগুলির সাথে ব্যান্ডউইথের জন্য লড়াই করতে হতে পারে, তাই এই ধরনের অপ্টিমাইজেশন ক্রমবর্ধমান গুরুত্বপূর্ণ হয়ে ওঠে।

CSS ব্যাকগ্রাউন্ড ইমেজ

মনে রাখবেন যে ব্রাউজার প্রিলোড স্ক্যানার মার্কআপ স্ক্যান করে। এটি অন্যান্য রিসোর্স প্রকার স্ক্যান করে না, যেমন CSS যাতে background-image প্রপার্টি দ্বারা রেফারেন্স করা ছবিগুলির জন্য ফেচ অন্তর্ভুক্ত থাকতে পারে।

HTML-এর মতো, ব্রাউজারগুলি CSS এর নিজস্ব অবজেক্ট মডেলে প্রক্রিয়া করে, যা CSSOM নামে পরিচিত। যদি CSSOM তৈরির সময় বাহ্যিক সংস্থানগুলি আবিষ্কৃত হয়, সেই সংস্থানগুলি আবিষ্কারের সময় অনুরোধ করা হয়, এবং প্রিলোড স্ক্যানার দ্বারা নয়।

ধরা যাক আপনার পৃষ্ঠার LCP প্রার্থী হল একটি CSS background-image প্রপার্টি সহ একটি উপাদান। রিসোর্স লোড হওয়ার সাথে সাথে নিম্নলিখিতটি ঘটে:

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

একটি WebPageTest নেটওয়ার্ক জলপ্রপাত চার্ট একটি CSS ব্যাকগ্রাউন্ড ইমেজ দেখাচ্ছে (যা LCP প্রার্থী) একটি rel=preload ইঙ্গিত ব্যবহারের কারণে অনেক তাড়াতাড়ি লোড হচ্ছে। LCP সময় প্রায় 250 মিলিসেকেন্ড দ্বারা উন্নত হয়।
চিত্র 11: একটি সিমুলেটেড 3G সংযোগের মাধ্যমে একটি মোবাইল ডিভাইসে Chrome এ চালানো একটি ওয়েব পৃষ্ঠার একটি WebPageTest নেটওয়ার্ক জলপ্রপাত চার্ট৷ পৃষ্ঠার LCP প্রার্থী হল একটি উপাদান যার একটি CSS background-image প্রপার্টি (সারি 3)। rel=preload ইঙ্গিত ব্রাউজারকে ইঙ্গিত ছাড়াই প্রায় 250 মিলিসেকেন্ড আগে ইমেজ আবিষ্কার করতে সাহায্য করে।

rel=preload ইঙ্গিত দিয়ে, LCP প্রার্থীকে শীঘ্রই খুঁজে পাওয়া যায়, LCP সময় কমিয়ে। যদিও সেই ইঙ্গিতটি এই সমস্যার সমাধান করতে সাহায্য করে, তবে আপনার ছবি LCP প্রার্থীকে CSS থেকে লোড করতে হবে কিনা তা মূল্যায়ন করা আরও ভাল বিকল্প হতে পারে। একটি <img> ট্যাগের সাহায্যে, প্রিলোড স্ক্যানারকে এটি আবিষ্কার করার অনুমতি দেওয়ার সময় ভিউপোর্টের জন্য উপযুক্ত একটি চিত্র লোড করার উপর আপনার আরও নিয়ন্ত্রণ থাকবে।

অনেক রিসোর্স ইনলাইন করা হচ্ছে

ইনলাইনিং এমন একটি অনুশীলন যা HTML এর ভিতরে একটি সংস্থান রাখে। আপনি বেস64 এনকোডিং ব্যবহার করে <style> উপাদানে স্টাইলশীট, <script> উপাদানে স্ক্রিপ্ট এবং কার্যত অন্য কোনো সংস্থান ইনলাইন করতে পারেন।

ইনলাইন রিসোর্স ডাউনলোড করার চেয়ে দ্রুত হতে পারে কারণ রিসোর্সের জন্য আলাদা অনুরোধ জারি করা হয় না। এটি নথিতে ঠিক আছে, এবং তাৎক্ষণিকভাবে লোড হয়। যাইহোক, উল্লেখযোগ্য অসুবিধা আছে:

  • আপনি যদি আপনার এইচটিএমএল ক্যাশে না করে থাকেন—এবং এইচটিএমএল প্রতিক্রিয়া গতিশীল হলে আপনি তা করতে পারবেন না—ইনলাইনড রিসোর্সগুলি কখনই ক্যাশে করা হয় না৷ এটি কার্যক্ষমতাকে প্রভাবিত করে কারণ ইনলাইনযুক্ত সংস্থানগুলি পুনরায় ব্যবহারযোগ্য নয়।
  • এমনকি যদি আপনি HTML ক্যাশে করতে পারেন, ইনলাইনযুক্ত সংস্থানগুলি নথিগুলির মধ্যে ভাগ করা হয় না৷ এটি বহিরাগত ফাইলগুলির তুলনায় ক্যাশিং দক্ষতা হ্রাস করে যা ক্যাশে করা যায় এবং সম্পূর্ণ মূল জুড়ে পুনরায় ব্যবহার করা যায়।
  • আপনি যদি খুব বেশি ইনলাইন করেন, তাহলে আপনি প্রিলোড স্ক্যানারটিকে পরবর্তীতে ডকুমেন্টে রিসোর্স আবিষ্কার করতে বিলম্ব করেন, কারণ সেই অতিরিক্ত, ইনলাইনযুক্ত, সামগ্রী ডাউনলোড করতে বেশি সময় লাগে।

একটি উদাহরণ হিসাবে এই পৃষ্ঠা নিন. নির্দিষ্ট পরিস্থিতিতে LCP প্রার্থী হল পৃষ্ঠার শীর্ষে থাকা ছবি এবং CSS একটি <link> উপাদান দ্বারা লোড করা একটি পৃথক ফাইলে থাকে। পৃষ্ঠাটি চারটি ওয়েব ফন্ট ব্যবহার করে যা CSS সংস্থান থেকে পৃথক ফাইল হিসাবে অনুরোধ করা হয়।

পৃষ্ঠার একটি ওয়েবপেজটেস্ট নেটওয়ার্ক জলপ্রপাত চার্ট যেখানে একটি বহিরাগত CSS ফাইলের সাথে চারটি ফন্ট উল্লেখ করা হয়েছে৷ LCP প্রার্থীর ছবি যথাসময়ে প্রিলোড স্ক্যানার দ্বারা আবিষ্কৃত হয়।
চিত্র 12: একটি সিমুলেটেড 3G সংযোগের মাধ্যমে একটি মোবাইল ডিভাইসে Chrome এ চালানো একটি ওয়েব পৃষ্ঠার একটি WebPageTest নেটওয়ার্ক জলপ্রপাত চার্ট৷ পৃষ্ঠার LCP প্রার্থী হল একটি <img> উপাদান থেকে লোড করা একটি ছবি, কিন্তু প্রিলোড স্ক্যানার দ্বারা এটি আবিষ্কৃত হয়েছে কারণ CSS এবং ফন্টগুলি পৃথক সংস্থানগুলিতে পৃষ্ঠা লোড করার জন্য প্রয়োজনীয়, যা প্রিলোড স্ক্যানারকে তার কাজ করতে দেরি করে না।

এখন কি হবে যদি CSS এবং সমস্ত ফন্ট বেস64 রিসোর্স হিসাবে ইনলাইন করা হয়?

পৃষ্ঠার একটি ওয়েবপেজটেস্ট নেটওয়ার্ক জলপ্রপাত চার্ট যেখানে একটি বহিরাগত CSS ফাইলের সাথে চারটি ফন্ট উল্লেখ করা হয়েছে৷ প্রিলোড স্ক্যানার LCP চিত্রটি আবিষ্কার করতে উল্লেখযোগ্যভাবে বিলম্বিত হয়েছে।
চিত্র 13: একটি সিমুলেটেড 3G সংযোগের মাধ্যমে একটি মোবাইল ডিভাইসে Chrome এ চালানো একটি ওয়েব পৃষ্ঠার একটি WebPageTest নেটওয়ার্ক জলপ্রপাত চার্ট৷ পৃষ্ঠার LCP প্রার্থী হল একটি <img> উপাদান থেকে লোড করা একটি চিত্র, কিন্তু CSS এর ইনলাইনিং এবং এর চারটি ফন্ট সংস্থান ` ` প্রিলোড স্ক্যানারকে ছবিটি আবিষ্কার করতে বিলম্ব করে যতক্ষণ না ঐ সম্পদগুলি সম্পূর্ণরূপে ডাউনলোড করা হয়।

ইনলাইনিংয়ের প্রভাব এই উদাহরণে LCP-এর জন্য এবং সাধারণভাবে কর্মক্ষমতার জন্য নেতিবাচক ফলাফল দেয়। পৃষ্ঠার সংস্করণ যা কিছু ইনলাইন করে না তা প্রায় 3.5 সেকেন্ডের মধ্যে LCP চিত্রটি পেইন্ট করে। যে পৃষ্ঠাটি সবকিছু ইনলাইন করে তা 7 সেকেন্ডের বেশি না হওয়া পর্যন্ত LCP চিত্রটি আঁকে না।

এখানে শুধু প্রিলোড স্ক্যানার ছাড়া আরও অনেক কিছু আছে। ফন্ট ইনলাইন করা একটি দুর্দান্ত কৌশল নয় কারণ বেস64 বাইনারি সংস্থানগুলির জন্য একটি অদক্ষ বিন্যাস। খেলার আরেকটি কারণ হল যে বহিরাগত ফন্ট সংস্থানগুলি ডাউনলোড করা হয় না যদি না সেগুলি CSSOM দ্বারা প্রয়োজনীয় নির্ধারণ করা হয়। যখন এই ফন্টগুলি বেস64 হিসাবে ইনলাইন করা হয়, তখন সেগুলি বর্তমান পৃষ্ঠার জন্য প্রয়োজন হোক বা না হোক ডাউনলোড করা হয়৷

একটি প্রিলোড জিনিস এখানে উন্নতি করতে পারে? নিশ্চিত। আপনি এলসিপি ইমেজ প্রিলোড করতে পারেন এবং এলসিপি সময় কমাতে পারেন, কিন্তু ইনলাইনড রিসোর্স দিয়ে আপনার সম্ভাব্য ক্যাশেযোগ্য এইচটিএমএল ব্লোটিং করার অন্যান্য নেতিবাচক কর্মক্ষমতার পরিণতি রয়েছে। ফার্স্ট কনটেন্টফুল পেইন্ট (FCP) এই প্যাটার্ন দ্বারা প্রভাবিত হয়। পৃষ্ঠার সংস্করণে যেখানে কিছুই ইনলাইন নেই, FCP প্রায় 2.7 সেকেন্ড। সংস্করণে যেখানে সবকিছু ইনলাইন করা আছে, FCP প্রায় 5.8 সেকেন্ড।

এইচটিএমএল, বিশেষ করে বেস 64-এনকোডেড রিসোর্সে ইনলাইন করার বিষয়ে খুব সতর্ক থাকুন। সাধারণভাবে এটি খুব ছোট সংস্থান ছাড়া বাঞ্ছনীয় নয়। ইনলাইন যতটা সম্ভব কম, কারণ খুব বেশি ইনলাইন করা আগুন নিয়ে খেলা করছে।

ক্লায়েন্ট-সাইড জাভাস্ক্রিপ্টের সাথে রেন্ডারিং মার্কআপ

এতে কোন সন্দেহ নেই: জাভাস্ক্রিপ্ট অবশ্যই পৃষ্ঠার গতিকে প্রভাবিত করে । বিকাশকারীরা কেবল ইন্টারঅ্যাক্টিভিটি সরবরাহ করতে এটির উপর নির্ভর করে না, তবে সামগ্রী সরবরাহ করার জন্য এটির উপর নির্ভর করার প্রবণতাও রয়েছে। এটি কিছু উপায়ে একটি উন্নত বিকাশকারী অভিজ্ঞতার দিকে পরিচালিত করে; কিন্তু বিকাশকারীদের জন্য সুবিধাগুলি সর্বদা ব্যবহারকারীদের জন্য সুবিধাগুলিতে অনুবাদ করে না।

একটি প্যাটার্ন যা প্রিলোড স্ক্যানারকে পরাস্ত করতে পারে তা হল ক্লায়েন্ট-সাইড জাভাস্ক্রিপ্টের সাথে মার্কআপ রেন্ডার করা:

একটি WebPageTest নেটওয়ার্ক জলপ্রপাত জাভাস্ক্রিপ্টে ক্লায়েন্টে সম্পূর্ণরূপে রেন্ডার করা ছবি এবং পাঠ্য সহ একটি মৌলিক পৃষ্ঠা দেখায়৷ যেহেতু মার্কআপ জাভাস্ক্রিপ্টের মধ্যে রয়েছে, প্রিলোড স্ক্যানার কোনও সংস্থান সনাক্ত করতে পারে না। জাভাস্ক্রিপ্ট ফ্রেমওয়ার্কের জন্য প্রয়োজনীয় অতিরিক্ত নেটওয়ার্ক এবং প্রক্রিয়াকরণ সময়ের কারণে সমস্ত সংস্থান অতিরিক্তভাবে বিলম্বিত হয়।
চিত্র 14: একটি সিমুলেটেড 3G সংযোগের মাধ্যমে একটি মোবাইল ডিভাইসে Chrome-এ চালানো একটি ক্লায়েন্ট-রেন্ডার করা ওয়েব পৃষ্ঠার একটি WebPageTest নেটওয়ার্ক জলপ্রপাত চার্ট৷ যেহেতু বিষয়বস্তু জাভাস্ক্রিপ্টে রয়েছে এবং রেন্ডার করার জন্য একটি ফ্রেমওয়ার্কের উপর নির্ভর করে, ক্লায়েন্ট-রেন্ডার করা মার্কআপে ইমেজ রিসোর্সটি প্রিলোড স্ক্যানার থেকে লুকানো থাকে। সমতুল্য সার্ভার-রেন্ডার করা অভিজ্ঞতা চিত্র 9 এ চিত্রিত করা হয়েছে।

যখন মার্কআপ পেলোডগুলি ব্রাউজারে জাভাস্ক্রিপ্টের মধ্যে থাকে এবং সম্পূর্ণরূপে রেন্ডার করা হয়, তখন সেই মার্কআপের যেকোনো সংস্থান কার্যকরভাবে প্রিলোড স্ক্যানারের কাছে অদৃশ্য থাকে৷ এটি গুরুত্বপূর্ণ সংস্থানগুলির আবিষ্কারকে বিলম্বিত করে, যা অবশ্যই এলসিপিকে প্রভাবিত করে। এই উদাহরণগুলির ক্ষেত্রে, সমতুল্য সার্ভার-রেন্ডার করা অভিজ্ঞতার সাথে তুলনা করলে LCP ছবির জন্য অনুরোধ উল্লেখযোগ্যভাবে বিলম্বিত হয় যার জন্য জাভাস্ক্রিপ্টের প্রয়োজন হয় না।

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

এই পরিস্থিতির প্রতিকার এই প্রশ্নের উত্তরের উপর নির্ভর করে: ক্লায়েন্টে রেন্ডার করার বিপরীতে আপনার পৃষ্ঠার মার্কআপ সার্ভার দ্বারা সরবরাহ না করার কোন কারণ আছে কি? যদি এর উত্তর "না" হয়, সার্ভার-সাইড রেন্ডারিং (SSR) বা স্ট্যাটিকালি জেনারেটেড মার্কআপ যেখানে সম্ভব বিবেচনা করা উচিত, কারণ এটি প্রিলোড স্ক্যানারকে সময়ের আগে গুরুত্বপূর্ণ সংস্থানগুলি আবিষ্কার করতে এবং সুবিধাবাদীভাবে আনতে সাহায্য করবে৷

আপনার পৃষ্ঠার মার্কআপের কিছু অংশে কার্যকারিতা সংযুক্ত করার জন্য যদি আপনার পৃষ্ঠার JavaScript প্রয়োজন হয় , তাহলে আপনি SSR-এর সাথে ভ্যানিলা জাভাস্ক্রিপ্ট বা হাইড্রেশনের মাধ্যমে উভয় জগতের সেরাটা পেতে পারেন।

প্রিলোড স্ক্যানার আপনাকে সাহায্য করুন

প্রিলোড স্ক্যানার হল একটি অত্যন্ত কার্যকরী ব্রাউজার অপ্টিমাইজেশান যা স্টার্টআপের সময় পৃষ্ঠাগুলিকে দ্রুত লোড করতে সাহায্য করে৷ নিদর্শনগুলি এড়িয়ে যা সময়ের আগে গুরুত্বপূর্ণ সংস্থানগুলি আবিষ্কার করার ক্ষমতাকে হারায়, আপনি কেবল নিজের জন্য বিকাশকে সহজ করে তুলছেন না, আপনি আরও ভাল ব্যবহারকারীর অভিজ্ঞতা তৈরি করছেন যা কিছু ওয়েব ভিটাল সহ অনেক মেট্রিক্সে আরও ভাল ফলাফল দেবে৷

সংক্ষেপে, এখানে নিম্নলিখিত জিনিসগুলি আপনি এই পোস্ট থেকে সরিয়ে নিতে চান:

  • ব্রাউজার প্রিলোড স্ক্যানার হল একটি সেকেন্ডারি এইচটিএমএল পার্সার যা প্রাইমারিটির আগে স্ক্যান করে যদি সুবিধাবাদীভাবে রিসোর্স আবিষ্কার করতে ব্লক করা হয় তাহলে এটি তাড়াতাড়ি আনতে পারে।
  • প্রারম্ভিক নেভিগেশন অনুরোধে সার্ভার দ্বারা প্রদত্ত মার্কআপে উপস্থিত নয় এমন সংস্থানগুলি প্রিলোড স্ক্যানার দ্বারা আবিষ্কার করা যাবে না৷ প্রিলোড স্ক্যানার যেভাবে পরাজিত হতে পারে তা অন্তর্ভুক্ত থাকতে পারে (কিন্তু এতে সীমাবদ্ধ নয়):
    • জাভাস্ক্রিপ্টের সাহায্যে DOM-এ রিসোর্স ইনজেকশন করা, সেগুলি স্ক্রিপ্ট, ছবি, স্টাইলশীট বা অন্য কিছু যা সার্ভার থেকে প্রাথমিক মার্কআপ পেলোডে ভালো হবে।
    • একটি জাভাস্ক্রিপ্ট সমাধান ব্যবহার করে ভাঁজের উপরের ছবি বা আইফ্রেমগুলি অলস লোড করা।
    • ক্লায়েন্টে রেন্ডারিং মার্কআপ যাতে জাভাস্ক্রিপ্ট ব্যবহার করে ডকুমেন্ট সাবরিসোর্সের রেফারেন্স থাকতে পারে।
  • প্রিলোড স্ক্যানার শুধুমাত্র HTML স্ক্যান করে। এটি অন্যান্য সম্পদের বিষয়বস্তু পরীক্ষা করে না-বিশেষ করে CSS-এতে LCP প্রার্থী সহ গুরুত্বপূর্ণ সম্পদের উল্লেখ থাকতে পারে।

যদি, যে কোনো কারণেই, আপনি এমন একটি প্যাটার্ন এড়াতে না পারেন যা নেতিবাচকভাবে লোডিং কর্মক্ষমতা বাড়াতে প্রিলোড স্ক্যানারের ক্ষমতাকে প্রভাবিত করে, rel=preload রিসোর্স ইঙ্গিতটি বিবেচনা করুন। আপনি যদি rel=preload ব্যবহার করেন , ল্যাব টুলে পরীক্ষা করে নিশ্চিত করুন যে এটি আপনাকে পছন্দসই প্রভাব দিচ্ছে। পরিশেষে, খুব বেশি রিসোর্স প্রিলোড করবেন না, কারণ আপনি যখন সবকিছুকে প্রাধান্য দেবেন, কিছুই হবে না।

সম্পদ

আনস্প্ল্যাশ থেকে হিরো ইমেজ, মোহাম্মদ রহমানির