ন্যাভিগেশন টাইমিং এবং রিসোর্স টাইমিং দিয়ে ক্ষেত্রে লোডিং পারফরম্যান্স কীভাবে মূল্যায়ন করবেন

মাঠে লোডিং পারফরম্যান্স মূল্যায়ন করতে নেভিগেশন এবং রিসোর্স টাইমিং এপিআই ব্যবহারের প্রাথমিক বিষয়গুলো শিখুন।

প্রকাশিত: ৮ অক্টোবর, ২০২১

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

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

মাঠে লোডিং পারফরম্যান্স মূল্যায়ন করতে সাহায্যকারী এপিআই

নেভিগেশন টাইমিং এবং রিসোর্স টাইমিং হলো দুটি সদৃশ API, যাদের মধ্যে যথেষ্ট মিল থাকলেও তারা দুটি স্বতন্ত্র বিষয় পরিমাপ করে:

  • ন্যাভিগেশন টাইমিং এইচটিএমএল ডকুমেন্টের জন্য করা অনুরোধগুলোর (অর্থাৎ, ন্যাভিগেশন অনুরোধগুলোর) গতি পরিমাপ করে।
  • রিসোর্স টাইমিং , CSS, জাভাস্ক্রিপ্ট, ছবি এবং অন্যান্য ধরনের রিসোর্সের মতো ডকুমেন্ট-নির্ভর রিসোর্সগুলোর জন্য করা অনুরোধের গতি পরিমাপ করে।

এই API-গুলো তাদের ডেটা একটি পারফরম্যান্স এন্ট্রি বাফারে প্রকাশ করে, যা ব্রাউজারে জাভাস্ক্রিপ্ট দিয়ে অ্যাক্সেস করা যায়। একটি পারফরম্যান্স বাফার কোয়েরি করার একাধিক উপায় আছে, কিন্তু একটি প্রচলিত উপায় হলো performance.getEntriesByType ব্যবহার করা।

// Get Navigation Timing entries:
performance.getEntriesByType('navigation');

// Get Resource Timing entries:
performance.getEntriesByType('resource');

performance.getEntriesByType একটি স্ট্রিং গ্রহণ করে, যা পারফরম্যান্স এন্ট্রি বাফার থেকে আপনি কোন ধরনের এন্ট্রি পুনরুদ্ধার করতে চান তা বর্ণনা করে। 'navigation' এবং 'resource' যথাক্রমে নেভিগেশন টাইমিং এবং রিসোর্স টাইমিং এপিআই-এর জন্য টাইমিং পুনরুদ্ধার করে।

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

একটি নেটওয়ার্ক অনুরোধের জীবনকাল এবং সময়কাল

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

ক্রোমের ডেভটুলস-এ দেখানো নেটওয়ার্কের সময়। এখানে দেখানো সময়গুলো হলো অনুরোধের সারি, সংযোগ আলোচনা, মূল অনুরোধ এবং রঙিন বার-এ প্রদর্শিত প্রতিক্রিয়ার সময়।
ক্রোম ডেভটুলস-এর নেটওয়ার্ক প্যানেলে একটি নেটওয়ার্ক অনুরোধের দৃশ্যায়ন

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

ডিএনএস অনুসন্ধান

যখন কোনো ব্যবহারকারী একটি ইউআরএল-এ যান, তখন একটি ডোমেইনকে আইপি অ্যাড্রেসে রূপান্তর করার জন্য ডোমেইন নেম সিস্টেম (DNS)-কে কোয়েরি করা হয়। এই প্রক্রিয়ায় বেশ কিছুটা সময় লাগতে পারে—এমনকি মাঠেও এই সময়টা পরিমাপ করার প্রয়োজন হতে পারে। নেভিগেশন টাইমিং এবং রিসোর্স টাইমিং ডিএনএস-সম্পর্কিত দুটি সময়কাল প্রকাশ করে:

  • domainLookupStart হলো সেই মুহূর্ত যখন ডিএনএস অনুসন্ধান শুরু হয়।
  • domainLookupEnd হলো যখন ডিএনএস অনুসন্ধান শেষ হয়।

শেষের মেট্রিক থেকে শুরুর মেট্রিক বিয়োগ করে মোট ডিএনএস লুকআপ সময় গণনা করা যেতে পারে:

// Measuring DNS lookup time
const [pageNav] = performance.getEntriesByType('navigation');
const totalLookupTime = pageNav.domainLookupEnd - pageNav.domainLookupStart;

সংযোগ আলোচনা

লোডিং পারফরম্যান্সের আরেকটি প্রভাবক হলো কানেকশন নেগোসিয়েশন, যা একটি ওয়েব সার্ভারের সাথে সংযোগ স্থাপনের সময় সৃষ্ট লেটেন্সি। যদি HTTPS ব্যবহৃত হয়, তবে এই প্রক্রিয়ায় TLS নেগোসিয়েশনের সময়ও অন্তর্ভুক্ত থাকবে। সংযোগ পর্বে তিনটি সময়কাল থাকে:

  • connectStart হলো সেই মুহূর্ত, যখন ব্রাউজার কোনো ওয়েব সার্ভারের সাথে সংযোগ স্থাপনের জন্য প্রক্রিয়া শুরু করে।
  • secureConnectionStart নির্দেশ করে কখন ক্লায়েন্ট TLS আলোচনা শুরু করে।
  • ওয়েব সার্ভারের সাথে সংযোগ স্থাপিত হলে তাকে connectEnd বলা হয়।

মোট সংযোগের সময় পরিমাপ করা মোট DNS লুকআপ সময় পরিমাপ করার মতোই: এক্ষেত্রে শেষের সময় থেকে শুরুর সময় বিয়োগ করতে হয়। তবে, এখানে একটি অতিরিক্ত secureConnectionStart প্রপার্টি আছে, যার মান 0 হতে পারে যদি HTTPS ব্যবহার করা না হয় অথবা সংযোগটি স্থায়ী (persistent) হয় । আপনি যদি TLS নেগোসিয়েশনের সময় পরিমাপ করতে চান, তবে আপনাকে এই বিষয়টি মনে রাখতে হবে:

// Quantifying total connection time
const [pageNav] = performance.getEntriesByType('navigation');
const connectionTime = pageNav.connectEnd - pageNav.connectStart;
let tlsTime = 0; // <-- Assume 0 to start with

// Was there TLS negotiation?
if (pageNav.secureConnectionStart > 0) {
  // Awesome! Calculate it!
  tlsTime = pageNav.connectEnd - pageNav.secureConnectionStart;
}

একবার ডিএনএস লুকআপ এবং সংযোগ আলোচনা শেষ হয়ে গেলে, ডকুমেন্ট এবং সেগুলোর ওপর নির্ভরশীল রিসোর্সগুলো ফেচ করার সাথে সম্পর্কিত সময়সূচী কার্যকর হয়।

অনুরোধ এবং প্রতিক্রিয়া

লোডিং পারফরম্যান্স দুই ধরনের কারণের দ্বারা প্রভাবিত হয়:

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

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

  • fetchStart নির্দেশ করে কখন ব্রাউজার একটি রিসোর্স (রিসোর্স টাইমিং) অথবা একটি নেভিগেশন অনুরোধের জন্য কোনো ডকুমেন্ট (নেভিগেশন টাইমিং) ফেচ করা শুরু করে। এটি প্রকৃত অনুরোধের আগে ঘটে এবং এই সময়েই ব্রাউজার ক্যাশগুলো (যেমন, HTTP এবং Cache ইনস্ট্যান্স ) পরীক্ষা করে।
  • workerStart নির্দেশ করে কখন একটি সার্ভিস ওয়ার্কারের fetch ইভেন্ট হ্যান্ডলারের মধ্যে কোনো অনুরোধের প্রক্রিয়াকরণ শুরু হয়। যখন কোনো সার্ভিস ওয়ার্কার বর্তমান পৃষ্ঠাটি নিয়ন্ত্রণ করে না, তখন এর মান 0 হবে।
  • requestStart হলো সেই মুহূর্ত যখন ব্রাউজার অনুরোধটি করে।
  • responseStart হলো সেই মুহূর্ত যখন প্রতিক্রিয়ার প্রথম বাইটটি এসে পৌঁছায়।
  • responseEnd হলো যখন রেসপন্সের শেষ বাইটটি এসে পৌঁছায়।

এই সময়গুলো আপনাকে লোডিং পারফরম্যান্সের বিভিন্ন দিক পরিমাপ করতে সাহায্য করে, যেমন সার্ভিস ওয়ার্কারের মধ্যে ক্যাশে লুকআপ এবং ডাউনলোডের সময়:

// Cache seek plus response time of the current document
const [pageNav] = performance.getEntriesByType('navigation');
const fetchTime = pageNav.responseEnd - pageNav.fetchStart;

// Service worker time plus response time
let workerTime = 0;

if (pageNav.workerStart > 0) {
  workerTime = pageNav.responseEnd - pageNav.workerStart;
}

আপনি অনুরোধ এবং প্রতিক্রিয়ার বিলম্বের অন্যান্য দিকগুলোও পরিমাপ করতে পারেন:

const [pageNav] = performance.getEntriesByType('navigation');

// Request time only (excluding redirects, DNS, and connection/TLS time)
const requestTime = pageNav.responseStart - pageNav.requestStart;

// Response time only (download)
const responseTime = pageNav.responseEnd - pageNav.responseStart;

// Request + response time
const requestResponseTime = pageNav.responseEnd - pageNav.requestStart;

অন্যান্য পরিমাপ যা আপনি করতে পারেন

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

  • পেজ রিডাইরেক্ট: রিডাইরেক্ট হলো অতিরিক্ত ল্যাটেন্সির একটি উপেক্ষিত উৎস, বিশেষ করে রিডাইরেক্ট চেইন। বিভিন্ন উপায়ে ল্যাটেন্সি যুক্ত হয়, যেমন HTTP-to-HTTPs হপস, এবং 302/আনক্যাশড 301 রিডাইরেক্ট। রিডাইরেক্ট ল্যাটেন্সি মূল্যায়নে redirectStart , redirectEnd , এবং redirectCount সময়গুলো সহায়ক।
  • ডকুমেন্ট আনলোডিং: যেসব পেজের unload ইভেন্ট হ্যান্ডলারে কোড রান হয়, ব্রাউজারকে পরবর্তী পেজে যাওয়ার আগে অবশ্যই সেই কোডটি এক্সিকিউট করতে হয়। unloadEventStart এবং unloadEventEnd ডকুমেন্ট আনলোডিং পরিমাপ করে।
  • ডকুমেন্ট প্রসেসিং: আপনার ওয়েবসাইট যদি খুব বড় আকারের HTML পেলোড না পাঠায়, তবে ডকুমেন্ট প্রসেসিং-এর সময় তেমন গুরুত্বপূর্ণ নাও হতে পারে। যদি আপনার পরিস্থিতি এমন হয়, তবে domInteractive , domContentLoadedEventStart , domContentLoadedEventEnd এবং domComplete সময়গুলো আপনার জন্য গুরুত্বপূর্ণ হতে পারে।

আপনার কোডে টাইমিং কীভাবে পাবেন

এখন পর্যন্ত দেখানো সমস্ত উদাহরণে performance.getEntriesByType ব্যবহার করা হয়েছে, কিন্তু পারফরম্যান্স এন্ট্রি বাফার কোয়েরি করার আরও অন্যান্য উপায় আছে, যেমন performance.getEntriesByName এবং performance.getEntries । যখন শুধু হালকা বিশ্লেষণের প্রয়োজন হয়, তখন এই পদ্ধতিগুলো ঠিকঠাক কাজ করে। তবে অন্যান্য পরিস্থিতিতে, এগুলো বিপুল সংখ্যক এন্ট্রির উপর পুনরাবৃত্তি করার মাধ্যমে, অথবা নতুন এন্ট্রি খুঁজে বের করার জন্য বারবার পারফরম্যান্স বাফার পোল করার মাধ্যমে মেইন থ্রেডের উপর অতিরিক্ত কাজের চাপ সৃষ্টি করতে পারে।

পারফরম্যান্স এন্ট্রি বাফার থেকে এন্ট্রি সংগ্রহ করার জন্য প্রস্তাবিত পদ্ধতি হলো একটি PerformanceObserver ব্যবহার করা। PerformanceObserver পারফরম্যান্স এন্ট্রিগুলোর জন্য নজর রাখে এবং বাফারে যুক্ত হওয়ার সাথে সাথে সেগুলো সরবরাহ করে।

// Create the performance observer:
const perfObserver = new PerformanceObserver((observedEntries) => {
  // Get all resource entries collected so far:
  const entries = observedEntries.getEntries();

  // Iterate over entries:
  for (let i = 0; i < entries.length; i++) {
    // Do the work!
  }
});

// Run the observer for Navigation Timing entries:
perfObserver.observe({
  type: 'navigation',
  buffered: true
});

// Run the observer for Resource Timing entries:
perfObserver.observe({
  type: 'resource',
  buffered: true
});

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

বাড়িতে কীভাবে ফোন করবেন

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

// Check for navigator.sendBeacon support:
if ('sendBeacon' in navigator) {
  // Caution: If you have lots of performance entries, don't
  // do this. This is an example for illustrative purposes.
  const data = JSON.stringify(performance.getEntries());

  // Send the data!
  navigator.sendBeacon('/analytics', data);
}

এই উদাহরণে, JSON স্ট্রিংটি একটি POST পেলোড হিসেবে আসবে, যা আপনি প্রয়োজন অনুযায়ী ডিকোড, প্রসেস এবং অ্যাপ্লিকেশন ব্যাকএন্ডে সংরক্ষণ করতে পারবেন।

উপসংহার

একবার মেট্রিকস সংগ্রহ করা হয়ে গেলে, সেই ফিল্ড ডেটা কীভাবে বিশ্লেষণ করবেন তা বের করার দায়িত্ব আপনার। ফিল্ড ডেটা বিশ্লেষণ করার সময়, অর্থপূর্ণ সিদ্ধান্তে পৌঁছানো নিশ্চিত করতে কয়েকটি সাধারণ নিয়ম অনুসরণ করতে হয়:

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

এই নির্দেশিকাটি নেভিগেশন বা রিসোর্স টাইমিং-এর উপর একটি সম্পূর্ণ তথ্যসূত্র হিসেবে তৈরি করা হয়নি, বরং এটি একটি সূচনা বিন্দু। এখানে আরও কিছু তথ্যসূত্র দেওয়া হলো যা আপনার জন্য সহায়ক হতে পারে:

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