নেক্সট পেইন্টের সাথে ইন্টারঅ্যাকশন মেজারিং (আইএনপি), মেজারিং ইন্টারঅ্যাকশন টু নেক্সট পেইন্ট (আইএনপি)

1. ভূমিকা

এটি একটি ইন্টারেক্টিভ কোডল্যাব যা web-vitals লাইব্রেরি ব্যবহার করে ইন্টারঅ্যাকশন টু নেক্সট পেইন্ট (INP) পরিমাপ করতে শেখার জন্য।

পূর্বশর্ত

তুমি কি শিখবে

  • আপনার পৃষ্ঠায় web-vitals লাইব্রেরি কীভাবে যোগ করবেন এবং এর অ্যাট্রিবিউশন ডেটা কীভাবে ব্যবহার করবেন।
  • কোথা থেকে এবং কীভাবে INP উন্নত করা শুরু করবেন তা নির্ণয় করতে অ্যাট্রিবিউশন ডেটা ব্যবহার করুন।

আপনার যা প্রয়োজন হবে

  • GitHub থেকে কোড ক্লোন করে npm কমান্ড চালানোর ক্ষমতা সম্পন্ন একটি কম্পিউটার।
  • একটি টেক্সট এডিটর।
  • সমস্ত মিথস্ক্রিয়া পরিমাপ কাজ করার জন্য Chrome এর একটি সাম্প্রতিক সংস্করণ।

2. সেট আপ করুন

কোডটি নিন এবং রান করুন।

কোডটি web-vitals-codelabs সংগ্রহস্থলে পাওয়া যাবে।

  1. আপনার টার্মিনালে রেপো ক্লোন করুন: git clone https://github.com/GoogleChromeLabs/web-vitals-codelabs.git
  2. ক্লোন করা ডিরেক্টরিতে যান: cd web-vitals-codelabs/measuring-inp
  3. নির্ভরতা ইনস্টল করুন: npm ci .
  4. ওয়েব সার্ভার শুরু করুন: npm run start
  5. আপনার ব্রাউজারে http://localhost:8080/ দেখুন।

পৃষ্ঠাটি ব্যবহার করে দেখুন

এই কোডল্যাবটি INP-এর সম্ভাব্য সমস্যাগুলি অন্বেষণ করতে গ্যাস্ট্রোপডিকন (একটি জনপ্রিয় শামুক অ্যানাটমি রেফারেন্স সাইট) ব্যবহার করে।

গ্যাস্ট্রোপডিকন ডেমো পৃষ্ঠার একটি স্ক্রিনশট

কোন কোন ইন্টারঅ্যাকশন ধীরগতির তা বুঝতে পৃষ্ঠাটির সাথে ইন্টারঅ্যাক্ট করার চেষ্টা করুন।

৩. Chrome DevTools-এ অবস্থান নির্ধারণ করা

More Tools > Developer Tools মেনু থেকে DevTools খুলুন , পৃষ্ঠায় ডান ক্লিক করে Inspect নির্বাচন করে , অথবা একটি কীবোর্ড শর্টকাট ব্যবহার করে।

এই কোডল্যাবে, আমরা পারফরম্যান্স প্যানেল এবং কনসোল উভয়ই ব্যবহার করব। আপনি যেকোনো সময় DevTools-এর উপরের ট্যাবগুলিতে এগুলির মধ্যে স্যুইচ করতে পারেন।

  • INP সমস্যাগুলি প্রায়শই মোবাইল ডিভাইসে ঘটে, তাই মোবাইল ডিসপ্লে ইমুলেশনে স্যুইচ করুন
  • যদি আপনি ডেস্কটপ বা ল্যাপটপে পরীক্ষা করেন, তাহলে পারফরম্যান্স সম্ভবত একটি বাস্তব মোবাইল ডিভাইসের তুলনায় উল্লেখযোগ্যভাবে ভালো হবে। পারফরম্যান্সের আরও বাস্তবসম্মত চেহারার জন্য, পারফরম্যান্স প্যানেলের উপরের ডানদিকে গিয়ারটি টিপুন, তারপর CPU 4x স্লোডাউন নির্বাচন করুন।

অ্যাপের পাশে DevTools পারফরম্যান্স প্যানেলের একটি স্ক্রিনশট, যেখানে 4x CPU স্লোডাউন নির্বাচন করা হয়েছে।

৪. ওয়েব-ভাইটাল ইনস্টল করা

web-vitals হল একটি জাভাস্ক্রিপ্ট লাইব্রেরি যা আপনার ব্যবহারকারীদের অভিজ্ঞতার ওয়েব ভাইটাল মেট্রিক্স পরিমাপ করে। আপনি লাইব্রেরিটি ব্যবহার করে সেই মানগুলি ক্যাপচার করতে পারেন এবং তারপরে পরবর্তী বিশ্লেষণের জন্য একটি বিশ্লেষণের শেষ বিন্দুতে নিয়ে যেতে পারেন, যাতে আমরা কখন এবং কোথায় ধীর ইন্টারঅ্যাকশন ঘটে তা নির্ধারণ করতে পারি।

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

এই কোডল্যাবটি npm থেকে ইনস্টল করবে এবং কোনও নির্দিষ্ট বিল্ড প্রক্রিয়ায় ডুবে যাওয়া এড়াতে সরাসরি স্ক্রিপ্ট লোড করবে।

web-vitals দুটি সংস্করণ আপনি ব্যবহার করতে পারেন:

  • পেজ লোডের সময় কোর ওয়েব ভাইটালসের মেট্রিক মান ট্র্যাক করতে চাইলে "স্ট্যান্ডার্ড" বিল্ড ব্যবহার করা উচিত।
  • "অ্যাট্রিবিউশন" বিল্ড প্রতিটি মেট্রিকে অতিরিক্ত ডিবাগ তথ্য যোগ করে, যাতে নির্ণয় করা যায় কেন একটি মেট্রিক তার মান দিয়ে শেষ হয়।

এই কোডল্যাবে INP পরিমাপের জন্য, আমরা অ্যাট্রিবিউশন বিল্ড চাই।

npm install -D web-vitals web-vitals চালিয়ে প্রকল্পের devDependencies এ ওয়েব-ভিটালস যোগ করুন।

পৃষ্ঠায় web-vitals যোগ করুন:

index.html এর নীচে স্ক্রিপ্টের অ্যাট্রিবিউশন সংস্করণ যোগ করুন এবং ফলাফলগুলি কনসোলে লগ করুন:

<script type="module">
  import {onINP} from './node_modules/web-vitals/dist/web-vitals.attribution.js';

  onINP(console.log);
</script>

চেষ্টা করে দেখো

কনসোলটি খোলা রেখে আবার পৃষ্ঠাটির সাথে ইন্টারঅ্যাক্ট করার চেষ্টা করুন। আপনি পৃষ্ঠার চারপাশে ক্লিক করলে, কিছুই লগ করা হয় না!

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

web-vitals আরও ভার্বোস রিপোর্টিংয়ের জন্য reportAllChanges বিকল্পটি প্রদান করে। সক্রিয় করা হলে, প্রতিটি ইন্টারঅ্যাকশন রিপোর্ট করা হয় না, তবে যখনই কোনও ইন্টারঅ্যাকশন পূর্ববর্তী যেকোনোটির চেয়ে ধীর হয়, তখনই এটি রিপোর্ট করা হয়।

স্ক্রিপ্টে বিকল্পটি যোগ করার চেষ্টা করুন এবং পৃষ্ঠার সাথে আবার ইন্টারঅ্যাক্ট করুন:

<script type="module">
  import {onINP} from './node_modules/web-vitals/dist/web-vitals.attribution.js';

  onINP(console.log, {reportAllChanges: true});
</script>

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

DevTools কনসোলের একটি স্ক্রিনশট যেখানে INP বার্তা সফলভাবে প্রিন্ট করা হয়েছে।

৫. অ্যাট্রিবিউশনে কী থাকে?

চলুন শুরু করা যাক পৃষ্ঠাটির সাথে বেশিরভাগ ব্যবহারকারীর প্রথম ইন্টারঅ্যাকশন দিয়ে, অর্থাৎ কুকি সম্মতি ডায়ালগ দিয়ে।

অনেক পৃষ্ঠায় এমন স্ক্রিপ্ট থাকে যেগুলিতে ব্যবহারকারী যখন কুকি গ্রহণ করে তখন কুকিগুলিকে সিঙ্ক্রোনাসভাবে ট্রিগার করতে হয়, যার ফলে ক্লিকটি ধীর গতিতে ইন্টারঅ্যাকশনে পরিণত হয়। এখানেও তাই ঘটে।

(ডেমো) কুকিজ গ্রহণ করতে হ্যাঁ ক্লিক করুন, এবং DevTools কনসোলে লগ করা INP ডেটা একবার দেখুন।

DevTools কনসোলে লগ করা INP ডেটা অবজেক্ট

এই শীর্ষ-স্তরের তথ্য স্ট্যান্ডার্ড এবং অ্যাট্রিবিউশন ওয়েব-ভিটালস বিল্ড উভয় ক্ষেত্রেই পাওয়া যায়:

{
  name: 'INP',
  value: 344,
  rating: 'needs-improvement',
  entries: [...],
  id: 'v4-1715732159298-8028729544485',
  navigationType: 'reload',
  attribution: {...},
}

ব্যবহারকারী যখন পরবর্তী পেইন্টে ক্লিক করেন তখন থেকে শুরু করে সময়কাল ছিল 344 মিলিসেকেন্ড—একটি "উন্নতি প্রয়োজন" INPentries অ্যারেতে এই ইন্টারঅ্যাকশনের সাথে সম্পর্কিত সমস্ত PerformanceEntry মান রয়েছে—এই ক্ষেত্রে, শুধুমাত্র একটি ক্লিক ইভেন্ট।

তবে এই সময়ে কী ঘটছে তা জানতে, আমরা attribution প্রপার্টিতে সবচেয়ে বেশি আগ্রহী। অ্যাট্রিবিউশন ডেটা তৈরি করতে, web-vitals খুঁজে বের করে যে কোন লং অ্যানিমেশন ফ্রেম (LoAF) ক্লিক ইভেন্টের সাথে ওভারল্যাপ করে। এরপর LoAF সেই ফ্রেমের সময় কতটা সময় ব্যয় করা হয়েছিল, চালানো স্ক্রিপ্ট থেকে শুরু করে requestAnimationFrame কলব্যাক, স্টাইল এবং লেআউটে ব্যয় করা সময় পর্যন্ত বিস্তারিত তথ্য প্রদান করতে পারে।

আরও তথ্য দেখতে attribution প্রপার্টিটি প্রসারিত করুন। ডেটা আরও সমৃদ্ধ।

attribution: {
  interactionTargetElement: Element,
  interactionTarget: '#confirm',
  interactionType: 'pointer',

  inputDelay: 27,
  processingDuration: 295.6,
  presentationDelay: 21.4,

  processedEventEntries: [...],
  longAnimationFrameEntries: [...],
}

প্রথমত, কীসের সাথে ইন্টারঅ্যাক্ট করা হয়েছিল সে সম্পর্কে তথ্য রয়েছে:

  • interactionTargetElement : যে উপাদানটির সাথে ইন্টারঅ্যাক্ট করা হয়েছিল তার একটি লাইভ রেফারেন্স (যদি উপাদানটি DOM থেকে সরানো না হয়)।
  • interactionTarget : পৃষ্ঠার মধ্যে উপাদান খুঁজে বের করার জন্য একটি নির্বাচক।

এরপর, সময়কে উচ্চ-স্তরের পদ্ধতিতে ভাগ করা হয়েছে:

  • inputDelay : ব্যবহারকারী যখন ইন্টারঅ্যাকশন শুরু করেন (যেমন, মাউস ক্লিক করেন) এবং সেই ইন্টারঅ্যাকশনের ইভেন্ট লিসেনার কখন চালানো শুরু করেন তার মধ্যে সময়। এই ক্ষেত্রে, ইনপুট বিলম্ব ছিল মাত্র ২৭ মিলিসেকেন্ড, এমনকি CPU থ্রোটলিং চালু থাকা সত্ত্বেও।
  • processingDuration : ইভেন্ট লিসেনারের রান সম্পূর্ণ হতে যে সময় লাগে। প্রায়শই, পৃষ্ঠাগুলিতে একটি ইভেন্টের জন্য একাধিক লিসেনারের প্রয়োজন হয় (উদাহরণস্বরূপ, pointerdown , pointerup , এবং click )। যদি তারা সবাই একই অ্যানিমেশন ফ্রেমে চলে, তাহলে তারা এই সময়ের মধ্যে একত্রিত হবে। এই ক্ষেত্রে, প্রসেসিং সময়কাল 295.6 মিলিসেকেন্ড লাগে—INP সময়ের বেশিরভাগ অংশ।
  • presentationDelay : ইভেন্ট শ্রোতাদের ইভেন্ট শেষ করার পর থেকে ব্রাউজার পরবর্তী ফ্রেম আঁকা শেষ করার সময় পর্যন্ত সময়। এই ক্ষেত্রে, 21.4 মিলিসেকেন্ড।

এই INP পর্যায়গুলি কী অপ্টিমাইজ করা দরকার তা নির্ণয়ের জন্য একটি গুরুত্বপূর্ণ সংকেত হতে পারে। অপ্টিমাইজ INP নির্দেশিকাতে এই বিষয়ে আরও তথ্য রয়েছে

একটু গভীরে খনন করলে দেখা যাবে, processedEventEntriesপাঁচটি ইভেন্ট রয়েছে, যেখানে শীর্ষ-স্তরের INP entries অ্যারের একক ইভেন্টটি থাকে। পার্থক্য কী?

processedEventEntries: [
  {
    name: 'mouseover',
    entryType: 'event',
    startTime: 1801.6,
    duration: 344,
    processingStart: 1825.3,
    processingEnd: 1825.3,
    cancelable: true
  },
  {
    name: 'mousedown',
    entryType: 'event',
    startTime: 1801.6,
    duration: 344,
    processingStart: 1825.3,
    processingEnd: 1825.3,
    cancelable: true
  },
  {name: 'mousedown', ...},
  {name: 'mouseup', ...},
  {name: 'click', ...},
],

শীর্ষ স্তরের এন্ট্রি হল INP ইভেন্ট, এই ক্ষেত্রে একটি ক্লিক। অ্যাট্রিবিউশন processedEventEntries হল সেই সমস্ত ইভেন্ট যা একই ফ্রেমে প্রক্রিয়া করা হয়েছিল। লক্ষ্য করুন যে এতে কেবল ক্লিক ইভেন্ট নয়, mouseover এবং mousedown এর মতো অন্যান্য ইভেন্টও অন্তর্ভুক্ত রয়েছে। এই অন্যান্য ইভেন্টগুলি সম্পর্কে জানা গুরুত্বপূর্ণ হতে পারে যদি সেগুলিও ধীর হয়, কারণ এগুলি সবই ধীর প্রতিক্রিয়াশীলতায় অবদান রাখে।

অবশেষে, longAnimationFrameEntries অ্যারেটি পাওয়া গেল। এটি একটি একক এন্ট্রি হতে পারে, তবে এমন কিছু ক্ষেত্রে আছে যেখানে একটি ইন্টারঅ্যাকশন একাধিক ফ্রেমে ছড়িয়ে পড়তে পারে। এখানে আমাদের কাছে একটি দীর্ঘ অ্যানিমেশন ফ্রেমের সবচেয়ে সহজ কেস রয়েছে।

longAnimationFrameEntries

LoAF এন্ট্রি সম্প্রসারণ:

longAnimationFrameEntries: [{
  name: 'long-animation-frame',
  startTime: 1823,
  duration: 319,

  renderStart: 2139.5,
  styleAndLayoutStart: 2139.7,
  firstUIEventTimestamp: 1801.6,
  blockingDuration: 268,

  scripts: [{...}]
}],

এখানে বেশ কিছু কার্যকরী মান রয়েছে, যেমন স্টাইলিংয়ে ব্যয় করা সময়ের পরিমাণ ব্যাখ্যা করা। লং অ্যানিমেশন ফ্রেম API নিবন্ধটি এই বৈশিষ্ট্যগুলি সম্পর্কে আরও গভীরভাবে আলোচনা করে । এই মুহূর্তে আমরা মূলত scripts বৈশিষ্ট্যের দিকে আগ্রহী, যেখানে দীর্ঘমেয়াদী ফ্রেমের জন্য দায়ী স্ক্রিপ্টগুলির বিশদ বিবরণ প্রদান করে এমন এন্ট্রি রয়েছে:

scripts: [{
  name: 'script',
  invoker: 'BUTTON#confirm.onclick',
  invokerType: 'event-listener',

  startTime: 1828.6,
  executionStart: 1828.6,
  duration: 294,

  sourceURL: 'http://localhost:8080/third-party/cmp.js',
  sourceFunctionName: '',
  sourceCharPosition: 1144
}]

এই ক্ষেত্রে, আমরা বলতে পারি যে সময়টি মূলত একটি একক event-listener মধ্যে ব্যয় করা হয়েছিল, যা BUTTON#confirm.onclick এ আহ্বান করা হয়েছিল। আমরা স্ক্রিপ্ট সোর্স URL এবং ফাংশনটি যেখানে সংজ্ঞায়িত করা হয়েছিল তার অক্ষর অবস্থানও দেখতে পারি!

ছাড়াইয়া লত্তয়া

এই অ্যাট্রিবিউশন ডেটা থেকে এই মামলা সম্পর্কে কী নির্ধারণ করা যেতে পারে?

  • button#confirm ক্লিক করার মাধ্যমে ( attribution.interactionTarget এবং স্ক্রিপ্ট অ্যাট্রিবিউশন এন্ট্রির invoker প্রোপার্টি থেকে) ইন্টারঅ্যাকশনটি শুরু হয়েছিল।
  • ইভেন্ট লিসেনারের প্রাথমিক সম্পাদনা করতে সময় ব্যয় করা হয়েছে (মোট মেট্রিক value তুলনায় attribution.processingDuration থেকে)।
  • স্লো ইভেন্ট লিসেনার কোডটি third-party/cmp.js ( scripts.sourceURL থেকে) এ সংজ্ঞায়িত একটি ক্লিক লিসেনার থেকে শুরু হয়।

আমাদের কোথায় অপ্টিমাইজ করতে হবে তা জানার জন্য এতটুকুই যথেষ্ট তথ্য!

৬. একাধিক ইভেন্ট শ্রোতা

পৃষ্ঠাটি রিফ্রেশ করুন যাতে DevTools কনসোলটি স্পষ্ট হয় এবং কুকি সম্মতি ইন্টারঅ্যাকশন আর দীর্ঘতম ইন্টারঅ্যাকশন না হয়।

অনুসন্ধান বাক্সে টাইপ করা শুরু করুন। অ্যাট্রিবিউশন ডেটা কী দেখায়? আপনার কী মনে হয় কী ঘটছে?

অ্যাট্রিবিউশন ডেটা

প্রথমত, ডেমো পরীক্ষার একটি উদাহরণের উচ্চ স্তরের স্ক্যান:

{
  name: 'INP',
  value: 1072,
  rating: 'poor',
  attribution: {
    interactionTargetElement: Element,
    interactionTarget: '#search-terms',
    interactionType: 'keyboard',

    inputDelay: 3.3,
    processingDuration: 1060.6,
    presentationDelay: 8.1,

    processedEventEntries: [...],
    longAnimationFrameEntries: [...],
  }
}

input#search-terms এলিমেন্টের সাথে কীবোর্ড ইন্টারঅ্যাকশনের ফলে (CPU থ্রটলিং সক্ষম থাকা অবস্থায়) এটির INP মান খুবই খারাপ। বেশিরভাগ সময়—মোট ১০৭২ মিলিসেকেন্ড INP-এর মধ্যে ১০৬১ মিলিসেকেন্ড—প্রক্রিয়াকরণের সময়কাল ব্যয় হয়েছে।

তবে, scripts এন্ট্রিগুলি আরও আকর্ষণীয়।

লেআউট থ্র্যাশিং

scripts অ্যারের প্রথম এন্ট্রি আমাদের কিছু মূল্যবান প্রসঙ্গ দেয়:

scripts: [{
  name: 'script',
  invoker: 'BUTTON#confirm.onclick',
  invokerType: 'event-listener',

  startTime: 4875.6,
  executionStart: 4875.6,
  duration: 497,
  forcedStyleAndLayoutDuration: 388,

  sourceURL: 'http://localhost:8080/js/index.js',
  sourceFunctionName: 'handleSearch',
  sourceCharPosition: 940
},
...]

এই স্ক্রিপ্ট এক্সিকিউশনের সময় বেশিরভাগ প্রসেসিং সময়কাল ঘটে, যা একটি input লিসেনার (ইনভোকার হল INPUT#search-terms.oninput )। ফাংশনের নাম ( handleSearch ) দেওয়া আছে, যেমন index.js সোর্স ফাইলের ভিতরে অক্ষরের অবস্থান।

তবে, একটি নতুন বৈশিষ্ট্য আছে: forcedStyleAndLayoutDuration । এই স্ক্রিপ্ট ইনভোকেশনের মধ্যে ব্যয় করা সময়টি ছিল যেখানে ব্রাউজারকে পৃষ্ঠাটি রিলেআউট করতে বাধ্য করা হয়েছিল। অন্য কথায়, এই ইভেন্ট লিসেনারটি কার্যকর করতে ব্যয় করা সময়ের 78% - 497 মিলিসেকেন্ডের মধ্যে 388 মিলিসেকেন্ড - আসলে লেআউট থ্র্যাশিংয়ে ব্যয় করা হয়েছিল।

এটি ঠিক করার জন্য সর্বোচ্চ অগ্রাধিকার দেওয়া উচিত।

বারবার শোনা শ্রোতা

পৃথকভাবে, পরবর্তী দুটি স্ক্রিপ্ট এন্ট্রি সম্পর্কে বিশেষভাবে উল্লেখযোগ্য কিছু নেই:

scripts: [...,
{
  name: 'script',
  invoker: '#document.onkeyup',
  invokerType: 'event-listener',

  startTime: 5375.3,
  executionStart: 5375.3,
  duration: 124,

  sourceURL: 'http://localhost:8080/js/index.js',
  sourceFunctionName: '',
  sourceCharPosition: 1526,
},
{
  name: 'script',
  invoker: '#document.onkeyup',
  invokerType: 'event-listener',

  startTime: 5673.9,
  executionStart: 5673.9,
  duration: 95,

  sourceURL: 'http://localhost:8080/js/index.js',
  sourceFunctionName: '',
  sourceCharPosition: 1526
}]

দুটি এন্ট্রিই keyup listeners, একটির পর একটি এক্সিকিউট করে। listeners হলো anonymous functions (অতএব sourceFunctionName প্রোপার্টিতে কিছুই রিপোর্ট করা হয় না), কিন্তু আমাদের এখনও একটি source file এবং character position আছে, তাই আমরা কোডটি কোথায় তা খুঁজে পেতে পারি।

অদ্ভুত ব্যাপার হলো, দুটোই একই উৎস ফাইল এবং চরিত্রের অবস্থান থেকে এসেছে

ব্রাউজারটি একটি অ্যানিমেশন ফ্রেমে একাধিক কী প্রেস প্রক্রিয়াকরণ করতে থাকে, যার ফলে কোনও কিছু আঁকার আগেই এই ইভেন্ট লিসেনারটি দুবার চালু হয়ে যায়!

এই প্রভাব আরও জটিল হতে পারে, যেখানে শ্রোতারা ইভেন্টটি সম্পূর্ণ করতে যত বেশি সময় নেয়, তত বেশি অতিরিক্ত ইনপুট ইভেন্ট আসতে পারে, যা ধীর মিথস্ক্রিয়াকে আরও দীর্ঘায়িত করে।

যেহেতু এটি একটি অনুসন্ধান/স্বয়ংক্রিয়ভাবে সম্পন্ন ইন্টারঅ্যাকশন, তাই ইনপুটটি ডিবাউন্স করা একটি ভাল কৌশল হবে যাতে প্রতি ফ্রেমে সর্বাধিক একটি কীপ্রেস প্রক্রিয়া করা যায়।

৭. ইনপুট বিলম্ব

ইনপুট বিলম্বের সাধারণ কারণ—ব্যবহারকারী যখন ইন্টারঅ্যাক্ট করে তখন থেকে ইভেন্ট লিসেনার যখন ইন্টারঅ্যাকশন প্রক্রিয়াকরণ শুরু করতে পারে সেই সময় পর্যন্ত—হল মূল থ্রেড ব্যস্ত থাকা। এর একাধিক কারণ থাকতে পারে:

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

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

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

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

অনেক পৃষ্ঠায়, ভারী মেইন-থ্রেডের কাজ এত ভালোভাবে করা হবে না, তবে INP অ্যাট্রিবিউশন ডেটাতে এটি কীভাবে শনাক্ত করা যায় তা দেখার জন্য এটি একটি ভালো প্রমাণ।

স্নেইল বাউন্সের সময় শুধুমাত্র সার্চ বক্স ফোকাস করার একটি উদাহরণ এখানে দেওয়া হল:

{
  name: 'INP',
  value: 728,
  rating: 'poor',

  attribution: {
    interactionTargetElement: Element,
    interactionTarget: '#search-terms',
    interactionType: 'pointer',

    inputDelay: 702.3,
    processingDuration: 4.9,
    presentationDelay: 20.8,

    longAnimationFrameEntries: [{
      name: 'long-animation-frame',
      startTime: 2064.8,
      duration: 790,

      renderStart: 2065,
      styleAndLayoutStart: 2854.2,
      firstUIEventTimestamp: 0,
      blockingDuration: 740,

      scripts: [{...}]
    }]
  }
}

পূর্বাভাস অনুসারে, ইভেন্ট লিসেনার্স দ্রুত সম্পন্ন করেছেন—প্রক্রিয়াকরণের সময়কাল ৪.৯ মিলিসেকেন্ড দেখানো হয়েছে, এবং দুর্বল ইন্টারঅ্যাকশনের বেশিরভাগ অংশ ইনপুট বিলম্বে ব্যয় হয়েছে, মোট ৭২৮ মিলিসেকেন্ডের মধ্যে ৭০২.৩ মিলিসেকেন্ড সময় নিয়েছে।

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

দিনটি বাঁচাতে LoAF স্ক্রিপ্ট এন্ট্রিগুলি এখানে রয়েছে:

scripts: [{
  name: 'script',
  invoker: 'SPAN.onanimationiteration',
  invokerType: 'event-listener',

  startTime: 2065,
  executionStart: 2065,
  duration: 788,

  sourceURL: 'http://localhost:8080/js/index.js',
  sourceFunctionName: 'cryptodaphneCoinHandler',
  sourceCharPosition: 1831
}]

যদিও এই ফাংশনটির সাথে ইন্টারঅ্যাকশনের কোনও সম্পর্ক ছিল না, এটি অ্যানিমেশন ফ্রেমের গতি কমিয়ে দেয় এবং তাই এটি ইন্টারঅ্যাকশন ইভেন্টের সাথে যুক্ত LoAF ডেটাতে অন্তর্ভুক্ত থাকে।

এ থেকে আমরা দেখতে পাচ্ছি যে কীভাবে ইন্টারঅ্যাকশন প্রক্রিয়াকরণে বিলম্বকারী ফাংশনটি ট্রিগার করা হয়েছিল (একজন animationiteration লিসেনারের দ্বারা), ঠিক কোন ফাংশনটি দায়ী ছিল এবং আমাদের সোর্স ফাইলগুলিতে এটি কোথায় অবস্থিত ছিল।

৮. উপস্থাপনা বিলম্ব: যখন কোনও আপডেট ঠিকভাবে কাজ করবে না

উপস্থাপনা বিলম্ব ইভেন্ট শ্রোতাদের চালানো শেষ হওয়ার পর থেকে ব্রাউজারটি স্ক্রিনে একটি নতুন ফ্রেম আঁকতে সক্ষম না হওয়া পর্যন্ত সময় পরিমাপ করে, যা ব্যবহারকারীর দৃশ্যমান প্রতিক্রিয়া দেখায়।

INP মান আবার রিসেট করতে পৃষ্ঠাটি রিফ্রেশ করুন, তারপর হ্যামবার্গার মেনু খুলুন। এটি খুললে একটি নির্দিষ্ট সমস্যা দেখা দেয়।

এটা দেখতে কেমন?

{
  name: 'INP',
  value: 376,
  rating: 'needs-improvement',
  delta: 352,

  attribution: {
    interactionTarget: '#sidenav-button>svg',
    interactionType: 'pointer',

    inputDelay: 12.8,
    processingDuration: 14.7,
    presentationDelay: 348.5,

    longAnimationFrameEntries: [{
      name: 'long-animation-frame',
      startTime: 651,
      duration: 365,

      renderStart: 673.2,
      styleAndLayoutStart: 1004.3,
      firstUIEventTimestamp: 138.6,
      blockingDuration: 315,

      scripts: [{...}]
    }]
  }
}

এবার প্রেজেন্টেশন বিলম্বই বেশিরভাগ ধীরগতির ইন্টারঅ্যাকশন তৈরি করে। এর অর্থ হল মূল থ্রেডকে যা ব্লক করছে তা ইভেন্ট লিসেনারের কাজ শেষ হওয়ার পরে ঘটে।

scripts: [{
  entryType: 'script',
  invoker: 'FrameRequestCallback',
  invokerType: 'user-callback',

  startTime: 673.8,
  executionStart: 673.8,
  duration: 330,

  sourceURL: 'http://localhost:8080/js/side-nav.js',
  sourceFunctionName: '',
  sourceCharPosition: 1193,
}]

scripts অ্যারের একক এন্ট্রিটি দেখলে আমরা দেখতে পাই যে FrameRequestCallback থেকে user-callback সময় ব্যয় করা হয়েছে। এবার উপস্থাপনা বিলম্ব একটি requestAnimationFrame কলব্যাকের কারণে হয়েছে।

9. উপসংহার

ক্ষেত্রের তথ্য একত্রিত করা

এটা স্বীকার করা উচিত যে একটি একক পৃষ্ঠা লোড থেকে একটি একক INP অ্যাট্রিবিউশন এন্ট্রি দেখলে এটি সবই সহজ। ফিল্ড ডেটার উপর ভিত্তি করে INP ডিবাগ করার জন্য এই ডেটা কীভাবে একত্রিত করা যেতে পারে? সহায়ক বিবরণের পরিমাণ আসলে এটিকে আরও কঠিন করে তোলে।

উদাহরণস্বরূপ, কোন পৃষ্ঠার উপাদানটি ধীরগতির ইন্টারঅ্যাকশনের একটি সাধারণ উৎস তা জানা অত্যন্ত কার্যকর। তবে, যদি আপনার পৃষ্ঠায় এমন CSS ক্লাসের নাম সংকলিত থাকে যা বিল্ড থেকে বিল্ডে পরিবর্তিত হয়, তাহলে একই উপাদানের web-vitals নির্বাচকগুলি বিল্ডগুলিতে আলাদা হতে পারে।

পরিবর্তে, কোনটি সবচেয়ে কার্যকর এবং কীভাবে ডেটা একত্রিত করা যেতে পারে তা নির্ধারণ করার জন্য আপনাকে আপনার নির্দিষ্ট অ্যাপ্লিকেশনটি সম্পর্কে ভাবতে হবে। উদাহরণস্বরূপ, অ্যাট্রিবিউশন ডেটা ফিরিয়ে আনার আগে, আপনি web-vitals নির্বাচককে আপনার নিজস্ব একটি শনাক্তকারী দিয়ে প্রতিস্থাপন করতে পারেন, যা লক্ষ্যবস্তুটি কোন উপাদানে রয়েছে তার উপর ভিত্তি করে, অথবা লক্ষ্যবস্তুটি যে ARIA ভূমিকা পালন করে তার উপর ভিত্তি করে।

একইভাবে, scripts এন্ট্রিগুলির sourceURL পাথে ফাইল-ভিত্তিক হ্যাশ থাকতে পারে যা তাদের একত্রিত করা কঠিন করে তোলে, তবে আপনি ডেটা ফিরিয়ে আনার আগে আপনার পরিচিত বিল্ড প্রক্রিয়ার উপর ভিত্তি করে হ্যাশগুলি বাদ দিতে পারেন।

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

সর্বত্রই কৃতিত্ব!

LoAF-ভিত্তিক INP অ্যাট্রিবিউশন একটি শক্তিশালী ডিবাগিং সহায়ক। এটি একটি INP চলাকালীন বিশেষভাবে কী ঘটেছিল সে সম্পর্কে গ্রানুলার ডেটা সরবরাহ করে। অনেক ক্ষেত্রে, এটি আপনাকে একটি স্ক্রিপ্টে সঠিক অবস্থান নির্দেশ করতে পারে যেখানে আপনার অপ্টিমাইজেশন প্রচেষ্টা শুরু করা উচিত।

আপনি এখন যেকোনো সাইটে INP অ্যাট্রিবিউশন ডেটা ব্যবহার করতে প্রস্তুত!

আপনার যদি কোনও পৃষ্ঠা সম্পাদনা করার অ্যাক্সেস নাও থাকে, তবুও আপনি DevTools কনসোলে নিম্নলিখিত স্নিপেটটি চালিয়ে এই কোডল্যাব থেকে প্রক্রিয়াটি পুনরায় তৈরি করতে পারেন এবং আপনি কী খুঁজে পেতে পারেন তা দেখতে পারেন:

const script = document.createElement('script');
script.src = 'https://unpkg.com/web-vitals@4/dist/web-vitals.attribution.iife.js';
script.onload = function () {
  webVitals.onINP(console.log, {reportAllChanges: true});
};
document.head.appendChild(script);

আরও জানুন