কিভাবে এবং কেন আমরা পারফরমেন্স ইনসাইট তৈরি করেছি

Chrome 102- এ আপনি আপনার DevTools-এ একটি নতুন পরীক্ষামূলক প্যানেল, পারফরম্যান্স ইনসাইটস দেখতে পাবেন। এই পোস্টে আমরা শুধুমাত্র কেন আমরা একটি নতুন প্যানেলে কাজ করছি তা নয়, আমাদের মুখোমুখি হওয়া প্রযুক্তিগত চ্যালেঞ্জগুলি এবং পথে আমরা নেওয়া সিদ্ধান্তগুলি নিয়েও আলোচনা করব৷

ALT_TEXT_HERE

কেন অন্য প্যানেল নির্মাণ?

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

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

অন্তর্দৃষ্টি প্যানেলে প্রবেশ করুন, যেখানে আপনি এখনও আপনার ট্রেসের একটি টাইমলাইন দেখতে পারেন এবং ডেটা পরিদর্শন করতে পারেন, তবে DevTools যেগুলিকে খননের যোগ্য প্রধান "অন্তর্দৃষ্টি" হিসাবে বিবেচনা করে তার একটি সহজ তালিকাও পান৷ অন্তর্দৃষ্টিগুলি রেন্ডার ব্লক করার অনুরোধ, লেআউট পরিবর্তন এবং কয়েকটি নাম দেওয়ার জন্য দীর্ঘ টাস্কের মতো সমস্যাগুলি সনাক্ত করবে, যেগুলি সবগুলি আপনার ওয়েবসাইটের পৃষ্ঠা লোড কার্যক্ষমতা এবং বিশেষ করে আপনার সাইটের কোর ওয়েব ভাইটাল (CWV) স্কোরকে নেতিবাচকভাবে প্রভাবিত করতে পারে৷ সমস্যাগুলির ফ্ল্যাগিংয়ের পাশাপাশি, পারফরম্যান্স ইনসাইটগুলি আপনাকে আপনার CWV স্কোরগুলি উন্নত করার জন্য কার্যকর পরামর্শ প্রদান করবে এবং আরও সংস্থান এবং ডকুমেন্টেশনের লিঙ্ক প্রদান করবে।

প্যানেলে প্রতিক্রিয়া লিঙ্ক

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

আমরা কীভাবে পারফরম্যান্স ইনসাইট তৈরি করি

বাকি DevTools-এর মতো, আমরা TypeScript- এ পারফরম্যান্স ইনসাইট তৈরি করেছি এবং ব্যবহারকারী ইন্টারফেস তৈরি করতে lit-html দ্বারা সমর্থিত ওয়েব উপাদান ব্যবহার করেছি। যেখানে পারফরম্যান্সের অন্তর্দৃষ্টি আলাদা হয় তা হল প্রাথমিক UI ইন্টারফেস হল একটি HTML canvas উপাদান এবং টাইমলাইন এই ক্যানভাসে আঁকা হয়৷ এই ক্যানভাস পরিচালনা করার ফলে অনেক জটিলতা আসে: শুধুমাত্র সঠিক জায়গায় সঠিক বিবরণ আঁকাই নয়, মাউস ইভেন্টগুলি পরিচালনা করা (উদাহরণস্বরূপ: ব্যবহারকারী ক্যানভাসে কোথায় ক্লিক করেছেন? তারা কি আমাদের আঁকা একটি ইভেন্টে ক্লিক করেছে? ) এবং নিশ্চিত করুন যে আমরা কার্যকরভাবে ক্যানভাস পুনরায় রেন্ডার করি।

একক ক্যানভাসে একাধিক ট্র্যাক

একটি প্রদত্ত ওয়েবসাইটের জন্য, একাধিক "ট্র্যাক" আছে যা আমরা রেন্ডার করতে চাই, প্রতিটি ডেটার একটি ভিন্ন বিভাগের প্রতিনিধিত্ব করে। উদাহরণস্বরূপ, অন্তর্দৃষ্টি প্যানেল ডিফল্টরূপে তিনটি ট্র্যাক দেখাবে:

এবং যেহেতু আমরা প্যানেলে বৈশিষ্ট্যগুলি অবতরণ করতে থাকি, আমরা আশা করি আরও ট্র্যাক যুক্ত হবে৷

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

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

সমগ্র UI-এর জন্য একটি canvas ব্যবহার করার অর্থ হল প্রতিটি ট্র্যাক সঠিক স্থানাঙ্কে রেন্ডার করে এবং অন্য ট্র্যাকে উপচে পড়ে না তা নিশ্চিত করতে আমাদের চিন্তা করতে হবে৷ উদাহরণস্বরূপ, যদি একটি নির্দিষ্ট ট্র্যাক 100px উচ্চ হয়, তাহলে আমরা এটিকে 120px উচ্চের কিছু রেন্ডার করার অনুমতি দিতে পারি না এবং এটির নীচের ট্র্যাকে রক্তপাত করতে পারি। এটি সমাধান করতে আমরা clip ব্যবহার করতে সক্ষম। আমরা প্রতিটি ট্র্যাক রেন্ডার করার আগে, আমরা দৃশ্যমান ট্র্যাক উইন্ডোর প্রতিনিধিত্ব করে একটি আয়তক্ষেত্র আঁকি। এটি নিশ্চিত করে যে এই সীমানার বাইরে আঁকা যেকোনো পাথ ক্যানভাস দ্বারা ক্লিপ করা হবে।

canvasContext.beginPath();
canvasContext.rect(
    trackVisibleWindow.x, trackVisibleWindow.y, trackVisibleWindow.width, trackVisibleWindow.height);
canvasContext.clip();

আমরা চাই না যে প্রতিটি ট্র্যাক তার অবস্থান উল্লম্বভাবে জানুক: প্রতিটি ট্র্যাক নিজেকে এমনভাবে রেন্ডার করা উচিত যেন এটি (0, 0) এ রেন্ডার করছে এবং সামগ্রিকভাবে পরিচালনা করার জন্য আমাদের একটি উচ্চ স্তরের উপাদান (যাকে আমরা TrackManager বলি) রয়েছে ট্র্যাক অবস্থান। এটি translate মাধ্যমে করা যেতে পারে, যা একটি প্রদত্ত (x, y) অবস্থান দ্বারা ক্যানভাসকে অনুবাদ করে। যেমন:

canvasContext.translate(0, 10); // Translate by 10px in the y direction
canvasContext.rect(0, 0, 10, 10); // draw a rectangle at (0, 0) that’s 10px high and wide

অবস্থান হিসাবে rect কোড সেটিং 0, 0 থাকা সত্ত্বেও, প্রয়োগ করা সামগ্রিক অনুবাদের ফলে আয়তক্ষেত্রটি 0, 10 এ রেন্ডার করা হবে। এটি আমাদেরকে একটি ট্র্যাকের ভিত্তিতে কাজ করতে দেয় যেন আমরা (0, 0) এ রেন্ডার করছি এবং আমাদের ট্র্যাক ম্যানেজারকে অনুবাদ করতে দেয় কারণ এটি প্রতিটি ট্র্যাককে পূর্ববর্তী ট্র্যাকের নীচে সঠিকভাবে রেন্ডার করা হয়েছে তা নিশ্চিত করতে প্রতিটি ট্র্যাক রেন্ডার করে৷

ট্র্যাক এবং হাইলাইটের জন্য অফ-স্ক্রিন ক্যানভাস

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

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

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

এটি ঠিক করার জন্য আমরা আমাদের UI কে দুটি অফ-স্ক্রীন ক্যানভাসে বিভক্ত করেছি: "প্রধান" ক্যানভাস, যেখানে ট্র্যাকগুলি রেন্ডার করা হয় এবং "হাইলাইটস" ক্যানভাস, যেখানে হাইলাইটগুলি আঁকা হয়৷ তারপরে আমরা সেই ক্যানভাসগুলিকে একক ক্যানভাসে অনুলিপি করে রেন্ডার করি যা ব্যবহারকারীর কাছে স্ক্রিনে দৃশ্যমান। আমরা একটি ক্যানভাস প্রসঙ্গে drawImage পদ্ধতি ব্যবহার করতে পারি, যা অন্য ক্যানভাসকে এর উৎস হিসেবে নিতে পারে।

এটি করার অর্থ হল একটি হাইলাইট মুছে ফেলার ফলে মূল ক্যানভাসটি পুনরায় আঁকা হবে না: পরিবর্তে আমরা অন-স্ক্রীন ক্যানভাসটি সাফ করতে পারি এবং তারপরে দৃশ্যমান ক্যানভাসে মূল ক্যানভাসটি অনুলিপি করতে পারি ৷ একটি ক্যানভাস অনুলিপি করার কাজ সস্তা, এটি অঙ্কন যা ব্যয়বহুল; তাই হাইলাইটগুলিকে একটি পৃথক ক্যানভাসে সরানোর মাধ্যমে, হাইলাইটগুলি চালু এবং বন্ধ করার সময় আমরা সেই খরচ এড়াই৷

ব্যাপকভাবে পরীক্ষিত ট্রেস পার্সিং

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

ট্রেস ফাইলটি পার্স করুন এবং প্রয়োজনীয় ডেটা বের করুন। ট্র্যাক একটি সেট রেন্ডার.

পার্সিং (পার্ট 1) কে UI কাজ থেকে আলাদা রাখা (পার্ট 2) আমাদের একটি কঠিন পার্সিং সিস্টেম তৈরি করতে সক্ষম করেছে; প্রতিটি ট্রেস হ্যান্ডলারের একটি সিরিজের মাধ্যমে চালিত হয় যা বিভিন্ন উদ্বেগের জন্য দায়ী: একটি LayoutShiftHandler লেআউট শিফ্টের জন্য আমাদের প্রয়োজনীয় সমস্ত তথ্য গণনা করে এবং একটি NetworkRequestsHandler একচেটিয়াভাবে নেটওয়ার্ক অনুরোধগুলি বের করে নেওয়ার কাজ করে। এই স্পষ্ট পার্সিং পদক্ষেপটি যেখানে আমাদের ট্রেসের বিভিন্ন অংশের জন্য দায়ী বিভিন্ন হ্যান্ডলার রয়েছে তাও উপকারী হয়েছে: ট্রেস পার্সিং খুব জটিল হতে পারে, এবং এটি একবারে একটি উদ্বেগের উপর ফোকাস করতে সক্ষম হতে সাহায্য করে।

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

ক্যানভাস UI এর জন্য স্ক্রিনশট পরীক্ষা

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

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

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

উপসংহার

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

পারফরম্যান্স ইনসাইট প্যানেল সম্পর্কে আরও জানতে, পারফরম্যান্স ইনসাইট দেখুন: আপনার ওয়েবসাইটের পারফরম্যান্সে অ্যাকশনেবল ইনসাইট পান

প্রিভিউ চ্যানেল ডাউনলোড করুন

আপনার ডিফল্ট ডেভেলপমেন্ট ব্রাউজার হিসাবে Chrome Canary , Dev , বা Beta ব্যবহার করার কথা বিবেচনা করুন৷ এই প্রিভিউ চ্যানেলগুলি আপনাকে সর্বশেষ DevTools বৈশিষ্ট্যগুলিতে অ্যাক্সেস দেয়, আপনাকে অত্যাধুনিক ওয়েব প্ল্যাটফর্ম APIগুলি পরীক্ষা করতে দেয় এবং আপনার ব্যবহারকারীদের করার আগে আপনার সাইটে সমস্যাগুলি খুঁজে পেতে সহায়তা করে!

Chrome DevTools টিমের সাথে যোগাযোগ করুন

নতুন বৈশিষ্ট্য, আপডেট বা DevTools সম্পর্কিত অন্য কিছু নিয়ে আলোচনা করতে নিম্নলিখিত বিকল্পগুলি ব্যবহার করুন৷

  • crbug.com এ আমাদের কাছে প্রতিক্রিয়া এবং বৈশিষ্ট্যের অনুরোধ জমা দিন।
  • আরও বিকল্প > সাহায্য > DevTools-এ একটি DevTools সমস্যা রিপোর্ট করুন ব্যবহার করে একটি DevTools সমস্যা রিপোর্ট করুন।
  • @ ChromeDevTools-এ টুইট করুন।
  • DevTools YouTube ভিডিও বা DevTools টিপস YouTube ভিডিওগুলিতে নতুন কী আছে সে সম্পর্কে মন্তব্য করুন৷