সারিবদ্ধ ইনপুট ইভেন্ট

ডেভ তাপুস্কা
Dave Tapuska

টিএল; ডিআর

  • ক্রোম 60 ইভেন্ট ফ্রিকোয়েন্সি কমিয়ে জ্যাঙ্ক কমায়, যার ফলে ফ্রেম টাইমিংয়ের ধারাবাহিকতা উন্নত হয়।
  • getCoalescedEvents() পদ্ধতি, Chrome 58-এ প্রবর্তিত ইভেন্ট তথ্যের একই সম্পদ প্রদান করে যা আপনার কাছে ছিল।

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

মসৃণতা এবং কর্মক্ষমতার স্বার্থে, Chrome 60-এ, আমরা একটি পরিবর্তন করছি যার ফলে প্রদত্ত তথ্যের গ্রানুলারিটি বাড়ানোর সময় এই ঘটনাগুলি কম ফ্রিকোয়েন্সিতে ঘটে। অনেকটা যেমন জেলি বিন রিলিজ করা হয়েছিল এবং কোরিওগ্রাফার নিয়ে এসেছিল যা অ্যান্ড্রয়েডে ইনপুট সারিবদ্ধ করে, আমরা সমস্ত প্ল্যাটফর্মে ওয়েবে ফ্রেম সারিবদ্ধ ইনপুট নিয়ে আসছি।

কিন্তু কখনও কখনও আপনার আরও ইভেন্টের প্রয়োজন হয়। সুতরাং, Chrome 58- এ, আমরা getCoalescedEvents() নামক একটি পদ্ধতি প্রয়োগ করেছি, যা আপনার অ্যাপ্লিকেশনটিকে কম ইভেন্ট গ্রহণ করার সময়ও পয়েন্টারের সম্পূর্ণ পথটি পুনরুদ্ধার করতে দেয়।

প্রথমে ইভেন্ট ফ্রিকোয়েন্সি সম্পর্কে কথা বলা যাক।

ইভেন্ট ফ্রিকোয়েন্সি কমানো

আসুন কিছু বেসিকগুলি বুঝতে পারি: টাচ-স্ক্রিন 60-120Hz এ ইনপুট সরবরাহ করে এবং ইঁদুর সাধারণত 100Hz এ ইনপুট সরবরাহ করে (তবে 2000Hz পর্যন্ত যে কোনও জায়গায় হতে পারে)। তবুও একটি মনিটরের সাধারণ রিফ্রেশ রেট হল 60Hz। তাই যে আসলে মানে কি? এর মানে হল যে আমরা আসলে ডিসপ্লে আপডেট করার চেয়ে বেশি হারে ইনপুট পাই। তাহলে আসুন একটি সাধারণ ক্যানভাস পেইন্টিং অ্যাপের জন্য devtools থেকে একটি পারফরম্যান্স টাইমলাইন দেখি।

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

একটি পারফরম্যান্স টাইমলাইন অসঙ্গত ফ্রেম টাইমিং দেখাচ্ছে

তাহলে কেন আমরা অতিরিক্ত কাজ করছি যা কোন ভিজ্যুয়াল আপডেটের কারণ হয় না? আদর্শভাবে, আমরা এমন কোনো কাজ করতে চাই না যা শেষ পর্যন্ত ব্যবহারকারীর উপকারে আসে না। Chrome 60 থেকে শুরু করে, ইনপুট পাইপলাইন ক্রমাগত ইভেন্টগুলি ( wheel , mousewheel , touchmove , pointermove , mousemove ) পাঠাতে দেরি করবে এবং requestAnimationFrame() কলব্যাক হওয়ার ঠিক আগে সেগুলি প্রেরণ করবে৷ নীচের ছবিতে (বৈশিষ্ট্য সক্রিয় করা আছে), আপনি আরও সামঞ্জস্যপূর্ণ ফ্রেম সময় এবং কম সময় প্রক্রিয়াকরণ ইভেন্টগুলি দেখতে পাচ্ছেন।

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

একটি গুরুত্বপূর্ণ নোট যা ওয়েব ডেভেলপারদের সচেতন হওয়া উচিত তা হল যে কোনও বিচ্ছিন্ন ইভেন্ট (যেমন keydown , keyup , mouseup , mousedown , touchstart , touchend ) যে কোনও মুলতুবি ইভেন্টের সাথে সাথেই পাঠানো হবে, আপেক্ষিক ক্রম সংরক্ষণ করে। এই বৈশিষ্ট্যটি সক্ষম করে, অনেক কাজ স্বাভাবিক ইভেন্ট লুপ ফ্লোতে সুসংহত করা হয়, একটি সামঞ্জস্যপূর্ণ ইনপুট ব্যবধান প্রদান করে। এটি ক্রমাগত ইভেন্টগুলিকে scroll এবং resize ইভেন্টগুলির সাথে ইনলাইনে আনে যা ইতিমধ্যেই Chrome এ ইভেন্ট লুপ ফ্লোতে স্ট্রিমলাইন করা হয়েছে৷

তুলনামূলকভাবে সামঞ্জস্যপূর্ণ ফ্রেম টাইমিং দেখানো একটি কর্মক্ষমতা টাইমলাইন।

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

getCoalescedEvents() পদ্ধতি

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

মানক এবং একত্রিত ইভেন্টের তুলনা করা।

একটি একক ইভেন্ট পাওয়ার পরিবর্তে, আপনি ঐতিহাসিক ইভেন্টের অ্যারে অ্যাক্সেস করতে পারেন যা ইভেন্টটি ঘটায়। Android , iOS এবং Windows সকলেরই তাদের নেটিভ SDK-তে একই রকম API রয়েছে এবং আমরা ওয়েবে একই রকম API প্রকাশ করছি৷

সাধারণত একটি অঙ্কন অ্যাপ ইভেন্টের অফসেটগুলি দেখে একটি পয়েন্ট আঁকতে পারে:

window.addEventListener("pointermove", function(event) {
    drawPoint(event.pageX, event.pageY);
});

ইভেন্টের অ্যারে ব্যবহার করতে এই কোডটি সহজেই পরিবর্তন করা যেতে পারে:

window.addEventListener("pointermove", function(event) {
    var events = 'getCoalescedEvents' in event ? event.getCoalescedEvents() : [event];
    for (let e of events) {
    drawPoint(e.pageX, e.pageY);
    }
});

মনে রাখবেন যে একত্রিত ইভেন্টের প্রতিটি সম্পত্তি জনবহুল নয়। যেহেতু সমন্বিত ইভেন্টগুলি সত্যিই প্রেরণ করা হয় না তবে কেবল যাত্রার জন্য রয়েছে, সেগুলি পরীক্ষা করা হয় না। কিছু ক্ষেত্র যেমন currentTarget , এবং eventPhase ডিফল্ট মান থাকবে। stopPropagation() বা preventDefault() এর মতো প্রেরন সম্পর্কিত পদ্ধতিতে কল করা মূল ইভেন্টে কোন প্রভাব ফেলবে না।