ক্রোমে ত্বরিত রেন্ডারিং

লেয়ার মডেল

টম উইল্টজিয়াস
Tom Wiltzius

ভূমিকা

বেশিরভাগ ওয়েব ডেভেলপারদের জন্য একটি ওয়েব পৃষ্ঠার মৌলিক মডেল হল DOM। রেন্ডারিং একটি পৃষ্ঠার এই উপস্থাপনাটিকে পর্দায় একটি ছবিতে পরিণত করার প্রায়শই অস্পষ্ট প্রক্রিয়া। আধুনিক ব্রাউজারগুলি সাম্প্রতিক বছরগুলিতে গ্রাফিক্স কার্ডগুলির সুবিধা নেওয়ার জন্য রেন্ডারিং কাজ করার উপায় পরিবর্তন করেছে: এটি প্রায়শই অস্পষ্টভাবে "হার্ডওয়্যার ত্বরণ" হিসাবে উল্লেখ করা হয়। একটি সাধারণ ওয়েব পৃষ্ঠা সম্পর্কে কথা বলার সময় (যেমন Canvas2D বা WebGL নয়), সেই শব্দটি আসলে কী বোঝায়? এই নিবন্ধটি মৌলিক মডেল ব্যাখ্যা করে যা Chrome-এ ওয়েব সামগ্রীর হার্ডওয়্যার ত্বরিত রেন্ডারিংকে আন্ডারপিন করে।

বড়, চর্বিযুক্ত সতর্কতা

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

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

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

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

DOM থেকে স্ক্রীন পর্যন্ত

স্তরসমূহ প্রবর্তন

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

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

জিপিইউ পরিভাষায় দ্রুত একপাশে: একটি টেক্সচার কি? এটিকে একটি বিটম্যাপ চিত্র হিসাবে ভাবুন যা প্রধান মেমরি (যেমন RAM) থেকে ভিডিও মেমরিতে (যেমন VRAM, আপনার GPU-তে) স্থানান্তরিত হয়েছে। একবার এটি GPU-তে হয়ে গেলে, আপনি এটিকে একটি জাল জ্যামিতিতে ম্যাপ করতে পারেন -- ভিডিও গেম বা CAD প্রোগ্রামগুলিতে, এই কৌশলটি কঙ্কালের 3D মডেল "ত্বক" দিতে ব্যবহৃত হয়। ক্রোম জিপিইউতে ওয়েব পৃষ্ঠার সামগ্রীর অংশগুলি পেতে টেক্সচার ব্যবহার করে। টেক্সচারগুলিকে সত্যিকারের সহজ আয়তক্ষেত্রাকার জালের সাথে প্রয়োগ করে বিভিন্ন অবস্থানে এবং রূপান্তরে সস্তায় ম্যাপ করা যেতে পারে। এইভাবে 3D CSS কাজ করে, এবং এটি দ্রুত স্ক্রোলিং-এর জন্যও দুর্দান্ত -- কিন্তু পরবর্তীতে এই দুটিতে আরও বেশি কিছু।

লেয়ার কনসেপ্ট ব্যাখ্যা করার জন্য কয়েকটি উদাহরণ দেখি।

Chrome-এ স্তরগুলি অধ্যয়ন করার সময় একটি খুব দরকারী টুল হল "রেন্ডারিং" শিরোনামের অধীনে, Dev Tools-এর সেটিংসে (অর্থাৎ সামান্য কগ আইকন) "সংমিশ্রিত স্তর বর্ডারগুলি দেখান" পতাকা৷ এটি খুব সহজভাবে হাইলাইট করে যেখানে স্তরগুলি অন-স্ক্রীনে রয়েছে৷ এটা চালু করা যাক. এই স্ক্রিনশট এবং উদাহরণগুলি এই লেখার সময় সর্বশেষ ক্রোম ক্যানারি, ক্রোম 27 থেকে নেওয়া হয়েছে৷

চিত্র 1: একটি একক-স্তর পৃষ্ঠা

<!doctype html>
<html>
<body>
  <div>I am a strange root.</div>
</body>
</html>
সংমিশ্রিত স্তরের স্ক্রিনশট পৃষ্ঠার ভিত্তি স্তরের চারপাশে রেন্ডার সীমানা
সংমিশ্রিত স্তরের স্ক্রিনশট পৃষ্ঠার ভিত্তি স্তরের চারপাশে রেন্ডার সীমানা

এই পৃষ্ঠাটি শুধুমাত্র একটি স্তর আছে. নীল গ্রিড টাইলগুলিকে প্রতিনিধিত্ব করে, যেটিকে আপনি একটি স্তরের উপ-ইউনিট হিসাবে ভাবতে পারেন যা Chrome একটি সময়ে GPU-তে একটি বড় স্তরের অংশ আপলোড করতে ব্যবহার করে৷ তারা এখানে সত্যিই গুরুত্বপূর্ণ নয়.

চিত্র 2: নিজস্ব স্তরে একটি উপাদান

<!doctype html>
<html>
<body>
  <div style="transform: rotateY(30deg) rotateX(-30deg); width: 200px;">
    I am a strange root.
  </div>
</body>
</html>
ঘোরানো স্তরের রেন্ডার সীমানার স্ক্রিনশট
ঘোরানো স্তরের রেন্ডার সীমানার স্ক্রিনশট

এটিকে ঘোরানো <div> এ একটি 3D CSS প্রপার্টি রেখে, আমরা দেখতে পারি যখন একটি উপাদান তার নিজস্ব স্তর পায় তখন এটি কেমন দেখায়: কমলা বর্ডারটি নোট করুন, যা এই দৃশ্যে একটি স্তরকে রূপরেখা দেয়।

স্তর তৈরির মানদণ্ড

আর কি তার নিজস্ব স্তর পায়? এখানে ক্রোমের হিউরিস্টিকস সময়ের সাথে সাথে বিকশিত হয়েছে এবং অব্যাহত রয়েছে, তবে বর্তমানে নিম্নলিখিত ট্রিগার স্তর তৈরি করা হয়েছে:

  • 3D বা দৃষ্টিকোণ রূপান্তর CSS বৈশিষ্ট্য
  • ত্বরিত ভিডিও ডিকোডিং ব্যবহার করে <video> উপাদান
  • একটি 3D (WebGL) প্রসঙ্গ বা ত্বরিত 2D প্রসঙ্গ সহ <canvas> উপাদান
  • সংমিশ্রিত প্লাগইন (যেমন ফ্ল্যাশ)
  • CSS অ্যানিমেশন সহ উপাদানগুলি তাদের অস্বচ্ছতার জন্য বা অ্যানিমেটেড ট্রান্সফর্ম ব্যবহার করে
  • ত্বরিত CSS ফিল্টার সহ উপাদান
  • উপাদানটির একটি বংশধর রয়েছে যার একটি সংমিশ্রণ স্তর রয়েছে (অন্য কথায় যদি উপাদানটির নিজস্ব স্তরে একটি শিশু উপাদান থাকে)
  • এলিমেন্টের একটি ছোট z-সূচক সহ একটি ভাইবোন রয়েছে যার একটি সংমিশ্রণ স্তর রয়েছে (অন্য কথায় এটি একটি সংমিশ্রিত স্তরের উপরে রেন্ডার করা হয়েছে)

ব্যবহারিক প্রভাব: অ্যানিমেশন

আমরা স্তরগুলিকেও চারপাশে সরাতে পারি, যা তাদের অ্যানিমেশনের জন্য খুব দরকারী করে তোলে।

চিত্র 3: অ্যানিমেটেড স্তর

<!doctype html>
<html>
<head>
  <style>
  div {
    animation-duration: 5s;
    animation-name: slide;
    animation-iteration-count: infinite;
    animation-direction: alternate;
    width: 200px;
    height: 200px;
    margin: 100px;
    background-color: gray;
  }
  @keyframes slide {
    from {
      transform: rotate(0deg);
    }
    to {
      transform: rotate(120deg);
    }
  }
  </style>
</head>
<body>
  <div>I am a strange root.</div>
</body>
</html>

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

উদাহরণস্বরূপ, দেব টুলস টাইমলাইনের এই দৃশ্যটি দেখুন: যখন এই স্তরটি সামনে পিছনে ঘুরছে তখন কোনও পেইন্ট অপারেশন নেই।

অ্যানিমেশনের সময় Dev Tools টাইমলাইনের স্ক্রিনশট
অ্যানিমেশনের সময় Dev Tools টাইমলাইনের স্ক্রিনশট

অবৈধ! পুনরায় রং করা

কিন্তু স্তরের বিষয়বস্তু পরিবর্তন হলে, এটি পুনরায় রং করতে হবে।

চিত্র 4: স্তরগুলি পুনরায় রং করা

<!doctype html>
<html>
<head>
  <style>
  div {
    animation-duration: 5s;
    animation-name: slide;
    animation-iteration-count: infinite;
    animation-direction: alternate;
    width: 200px;
    height: 200px;
    margin: 100px;
    background-color: gray;
  }
  @keyframes slide {
    from {
      transform: rotate(0deg);
    }
    to {
      transform: rotate(120deg);
    }
  }
  </style>
</head>
<body>
  <div id="foo">I am a strange root.</div>
  <input id="paint" type="button" value="repaint">
  <script>
    var w = 200;
    document.getElementById('paint').onclick = function() {
      document.getElementById('foo').style.width = (w++) + 'px';
    }
  </script>
</body>
</html>

প্রতিবার ইনপুট উপাদানটিতে ক্লিক করা হলে ঘূর্ণায়মান উপাদানটি 1px প্রশস্ত হয়। এটি সম্পূর্ণ উপাদানটির রিলেআউট এবং পুনরায় পেইন্টিং ঘটায়, যা এই ক্ষেত্রে একটি সম্পূর্ণ স্তর।

কি আঁকা হচ্ছে তা দেখার একটি ভাল উপায় হল Dev Tools-এ "শো পেইন্ট রেক্টস" টুল দিয়ে, এছাড়াও Dev Tools এর সেটিংসের "রেন্ডারিং" শিরোনামের অধীনে। এটি চালু করার পরে, লক্ষ্য করুন যে বোতামটি ক্লিক করা হলে অ্যানিমেটেড উপাদান এবং বোতাম দুটিই লাল ফ্ল্যাশ করে।

শো পেইন্ট রেক্ট চেকবক্সের স্ক্রিনশট
শো পেইন্ট রেক্ট চেকবক্সের স্ক্রিনশট

পেইন্ট ইভেন্টগুলি দেব টুলস টাইমলাইনেও দেখানো হয়। তীক্ষ্ণ দৃষ্টিসম্পন্ন পাঠকরা লক্ষ্য করতে পারেন যে সেখানে দুটি পেইন্ট ইভেন্ট রয়েছে: একটি স্তরের জন্য, এবং একটি নিজেই বোতামের জন্য, যেটি যখন তার বিষণ্ন অবস্থায়/থেকে পরিবর্তিত হয় তখন পুনরায় রঙ করা হয়।

ডেভ টুলস টাইমলাইনের স্ক্রিনশট একটি স্তর পুনরায় রং করা
ডেভ টুলস টাইমলাইনের স্ক্রিনশট একটি স্তর পুনরায় রং করা

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

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

আপনি কাজ করছেন এমন কিছুর উপর এটি প্রভাব ফেলছে কিনা তা বের করার সর্বোত্তম উপায় হল Dev Tools Timeline এবং Show Paint Rects টুলগুলি ব্যবহার করা যাতে আপনি যখন না করতে চান তখন আপনি পুনরায় রং করছেন কিনা তা দেখতে, তারপর আপনি কোথায় নোংরা করেছেন তা সনাক্ত করার চেষ্টা করুন। DOM ঠিক সেই রিলেআউট/রিপেইন্টের আগে। যদি পেইন্টিং অনিবার্য হয় কিন্তু অযৌক্তিকভাবে দীর্ঘ সময় নিচ্ছে বলে মনে হয়, তাহলে Dev Tools-এ ক্রমাগত পেইন্টিং মোড সম্পর্কে Eberhard Gräther-এর নিবন্ধটি দেখুন।

এটি একসাথে করা: DOM থেকে স্ক্রীন

তাহলে কিভাবে ক্রোম DOM কে স্ক্রীন ইমেজে পরিণত করে? ধারণাগতভাবে, এটি:

  1. DOM নেয় এবং এটিকে স্তরগুলিতে বিভক্ত করে
  2. এই স্তরগুলির প্রতিটিকে স্বাধীনভাবে সফ্টওয়্যার বিটম্যাপে রঙ করে
  3. টেক্সচার হিসাবে তাদের GPU-তে আপলোড করে
  4. চূড়ান্ত স্ক্রীন ইমেজে বিভিন্ন স্তরকে একত্রিত করে।

ক্রোম প্রথমবার একটি ওয়েব পৃষ্ঠার একটি ফ্রেম তৈরি করে এই সমস্ত কিছু ঘটতে হবে৷ কিন্তু তারপরে এটি ভবিষ্যতের ফ্রেমের জন্য কিছু শর্টকাট নিতে পারে:

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

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

এখন এ পর্যন্তই. লেয়ার মডেলের ব্যবহারিক প্রভাব সম্পর্কে আরও কয়েকটি নিবন্ধের জন্য আমাদের সাথে থাকুন।

অতিরিক্ত সম্পদ