রিঅ্যাক্ট-উইন্ডো দিয়ে বড় তালিকা ভার্চুয়ালাইজ করুন

সুপার বড় টেবিল এবং তালিকাগুলি উল্লেখযোগ্যভাবে আপনার সাইটের কর্মক্ষমতা কমিয়ে দিতে পারে। ভার্চুয়ালাইজেশন সাহায্য করতে পারে!

react-window হল একটি লাইব্রেরি যা বড় তালিকাগুলিকে দক্ষতার সাথে রেন্ডার করার অনুমতি দেয়।

এখানে একটি তালিকার একটি উদাহরণ রয়েছে যেখানে 1000টি সারি রয়েছে react-window এর সাথে রেন্ডার করা হচ্ছে। যত দ্রুত সম্ভব স্ক্রোল করার চেষ্টা করুন।

কেন এই দরকারী?

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

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

ভার্চুয়ালাইজড তালিকায় বিষয়বস্তুর উইন্ডো
একটি ভার্চুয়ালাইজড তালিকায় সামগ্রীর "উইন্ডো" সরানো হচ্ছে

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

প্রতিক্রিয়া জানালা

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

কখন নির্দিষ্ট আকারের তালিকা ব্যবহার করবেন

আপনার যদি সমান আকারের আইটেমগুলির একটি দীর্ঘ, এক-মাত্রিক তালিকা থাকে তবে FixedSizeList উপাদানটি ব্যবহার করুন।

import React from 'react';
import { FixedSizeList } from 'react-window';

const items = [...] // some list of items

const Row = ({ index, style }) => (
  <div style={style}>
     {/* define the row component using items[index] */}
  </div>
);

const ListComponent = () => (
  <FixedSizeList
    height={500}
    width={500}
    itemSize={120}
    itemCount={items.length}
  >
    {Row}
  </FixedSizeList>
);

export default ListComponent;
  • FixedSizeList উপাদান তালিকার মধ্যে আইটেমগুলির আকার নিয়ন্ত্রণ করতে একটি height , width এবং itemSize প্রপ গ্রহণ করে।
  • একটি ফাংশন যা সারিগুলিকে রেন্ডার করে একটি শিশু হিসাবে FixedSizeList এ পাস করা হয়। নির্দিষ্ট আইটেম সম্পর্কে বিশদ তথ্য index যুক্তি দিয়ে অ্যাক্সেস করা যেতে পারে ( items[index] )।
  • একটি style প্যারামিটারও সারি রেন্ডারিং পদ্ধতিতে পাস করা হয় যা অবশ্যই সারি উপাদানের সাথে সংযুক্ত থাকতে হবে। তালিকার আইটেমগুলি সম্পূর্ণরূপে তাদের উচ্চতা এবং প্রস্থের মানগুলির সাথে ইনলাইনে বরাদ্দ করা হয় এবং style পরামিতি এটির জন্য দায়ী৷

এই নিবন্ধে আগে দেখানো ত্রুটি উদাহরণ একটি FixedSizeList উপাদানের একটি উদাহরণ দেখায়।

পরিবর্তনশীল আকারের তালিকা কখন ব্যবহার করবেন

বিভিন্ন আকারের আইটেমগুলির একটি তালিকা রেন্ডার করতে VariableSizeList উপাদান ব্যবহার করুন। এই উপাদানটি একটি নির্দিষ্ট আকারের তালিকার মতো একইভাবে কাজ করে, তবে পরিবর্তে একটি নির্দিষ্ট মানের পরিবর্তে itemSize প্রপের জন্য একটি ফাংশন আশা করে।

import React from 'react';
import { VariableSizeList } from 'react-window';

const items = [...] // some list of items

const Row = ({ index, style }) => (
  <div style={style}>
     {/* define the row component using items[index] */}
  </div>
);

const getItemSize = index => {
  // return a size for items[index]
}

const ListComponent = () => (
  <VariableSizeList
    height={500}
    width={500}
    itemCount={items.length}
    itemSize={getItemSize}
  >
    {Row}
  </VariableSizeList>
);

export default ListComponent;

নিম্নলিখিত এম্বেড এই উপাদানটির একটি উদাহরণ দেখায়।

আইটেম সাইজ ফাংশনটি itemSize প্রপে পাস করা এই উদাহরণে সারি উচ্চতাকে এলোমেলো করে। তবে একটি বাস্তব প্রয়োগে, প্রতিটি আইটেমের মাপ সংজ্ঞায়িত করে প্রকৃত যুক্তি থাকা উচিত। আদর্শভাবে, এই মাপগুলি ডেটার উপর ভিত্তি করে গণনা করা উচিত বা একটি API থেকে প্রাপ্ত করা উচিত।

গ্রিড

react-window বহুমাত্রিক তালিকা বা গ্রিড ভার্চুয়ালাইজ করার জন্য সমর্থন প্রদান করে। এই প্রসঙ্গে, ব্যবহারকারী অনুভূমিকভাবে এবং উল্লম্বভাবে স্ক্রোল করার সাথে সাথে দৃশ্যমান সামগ্রীর "উইন্ডো" পরিবর্তিত হয়।

ভার্চুয়ালাইজড গ্রিডে বিষয়বস্তুর সরানো উইন্ডো দ্বি-মাত্রিক
ভার্চুয়ালাইজড গ্রিডে সামগ্রীর "উইন্ডো" সরানো দ্বিমাত্রিক

একইভাবে, নির্দিষ্ট তালিকা আইটেমগুলির আকার পরিবর্তিত হতে পারে কিনা তার উপর নির্ভর করে FixedSizeGrid এবং VariableSizeGrid উভয় উপাদানই ব্যবহার করা যেতে পারে।

  • FixedSizeGrid এর জন্য, API প্রায় একই কিন্তু উচ্চতা, প্রস্থ এবং আইটেম সংখ্যা উভয় কলাম এবং সারিগুলির জন্য উপস্থাপন করা প্রয়োজন।
  • VariableSizeGrid এর জন্য, কলামের প্রস্থ এবং সারি উচ্চতা উভয়ই তাদের নিজ নিজ প্রপসে মানের পরিবর্তে ফাংশন পাস করে পরিবর্তন করা যেতে পারে।

ভার্চুয়ালাইজড গ্রিডের উদাহরণ দেখতে ডকুমেন্টেশনটি দেখুন।

স্ক্রলে অলস লোড হচ্ছে

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

নিম্নলিখিত চিত্রটি এটিকে সংক্ষিপ্ত করতে সাহায্য করতে পারে:

একটি নিয়মিত এবং ভার্চুয়ালাইজড তালিকার মধ্যে স্ক্রল করার মধ্যে পার্থক্য
একটি নিয়মিত এবং ভার্চুয়ালাইজড তালিকার মধ্যে স্ক্রল করার মধ্যে পার্থক্য

এই সমস্যাটি সমাধানের সর্বোত্তম পন্থা হল একটি পৃষ্ঠায় উপাদানগুলির একটি ছোট "উইন্ডো" বজায় রাখতে react-window মতো একটি লাইব্রেরি ব্যবহার করা, কিন্তু ব্যবহারকারীর স্ক্রোল করার সাথে সাথে নতুন এন্ট্রিগুলিকে অলসভাবে লোড করা। একটি পৃথক প্যাকেজ, react-window-infinite-loader , এটি react-window দিয়ে সম্ভব করে তোলে।

নিম্নলিখিত কোডটি বিবেচনা করুন যা একটি অভিভাবক App উপাদানে পরিচালিত রাষ্ট্রের উদাহরণ দেখায়।

import React, { Component } from 'react';

import ListComponent from './ListComponent';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      items: [], // instantiate initial list here
      moreItemsLoading: false,
      hasNextPage: true
    };

    this.loadMore = this.loadMore.bind(this);
  }

  loadMore() {
   // method to fetch newer entries for the list
  }

  render() {
    const { items, moreItemsLoading, hasNextPage } = this.state;

    return (
      <ListComponent
        items={items}
        moreItemsLoading={moreItemsLoading}
        loadMore={this.loadMore}
        hasNextPage={hasNextPage}
      />
    );
  }
}

export default App;

একটি loadMore পদ্ধতি একটি চাইল্ড ListComponent পাস করা হয় যাতে অসীম লোডার তালিকা থাকে। এটি গুরুত্বপূর্ণ কারণ ব্যবহারকারী একটি নির্দিষ্ট বিন্দু অতিক্রম করার পরে আরও আইটেম লোড করার জন্য অসীম লোডারকে একটি কলব্যাক ফায়ার করতে হবে।

তালিকাটি রেন্ডার করে এমন ListComponent দেখতে কেমন হতে পারে তা এখানে:

import React from 'react';
import { FixedSizeList } from 'react-window';
import InfiniteLoader from "react-window-infinite-loader";

const ListComponent = ({ items, moreItemsLoading, loadMore, hasNextPage }) => {
  const Row = ({ index, style }) => (
     {/* define the row component using items[index] */}
  );

  const itemCount = hasNextPage ? items.length + 1 : items.length;

  return (
    <InfiniteLoader
      isItemLoaded={index => index < items.length}
      itemCount={itemCount}
      loadMoreItems={loadMore}
    >
      {({ onItemsRendered, ref }) => (
        <FixedSizeList
          height={500}
          width={500}
          itemCount={itemCount}
          itemSize={120}
          onItemsRendered={onItemsRendered}
          ref={ref}
        >
          {Row}
        </FixedSizeList>
      )}
  </InfiniteLoader>
  )
};

export default ListComponent;

এখানে, FixedSizeList উপাদানটি InfiniteLoader এর মধ্যে মোড়ানো হয়। লোডারকে নির্ধারিত প্রপগুলি হল:

  • isItemLoaded : একটি নির্দিষ্ট আইটেম লোড হয়েছে কিনা তা পরীক্ষা করে এমন পদ্ধতি
  • itemCount : তালিকায় আইটেমের সংখ্যা (বা প্রত্যাশিত)
  • loadMoreItems : কলব্যাক যা একটি প্রতিশ্রুতি প্রদান করে যা তালিকার জন্য অতিরিক্ত ডেটার সমাধান করে

একটি রেন্ডার প্রপ একটি ফাংশন ফেরত দিতে ব্যবহৃত হয় যা তালিকা উপাদানটি রেন্ডার করার জন্য ব্যবহার করে। onItemsRendered এবং ref বৈশিষ্ট্য উভয়ই এমন বৈশিষ্ট্য যা পাস করতে হবে।

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

তালিকাটি নীচে স্ক্রোল করা একই রকম মনে হতে পারে, তবে প্রতিবার আপনি যখন তালিকার শেষের কাছাকাছি স্ক্রোল করবেন তখন একটি র্যান্ডম ব্যবহারকারী API থেকে 10 জন ব্যবহারকারীকে পুনরুদ্ধার করার জন্য একটি অনুরোধ করা হয়েছে। এক সময়ে ফলাফলের শুধুমাত্র একটি "উইন্ডো" রেন্ডার করার সময় এটি করা হয়।

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

উদাহরণ স্বরূপ:

const Row = ({ index, style }) => {
  const itemLoading = index === items.length;

  if (itemLoading) {
      // return loading state
  } else {
      // return item
  }
};

ওভারস্ক্যানিং

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

ভার্চুয়ালাইজড তালিকার ব্যবহারকারীর অভিজ্ঞতা উন্নত করতে, react-window আপনাকে overscanCount প্রপার্টি দিয়ে আইটেম ওভারস্ক্যান করতে দেয়। এটি আপনাকে দৃশ্যমান "উইন্ডো" এর বাইরে কতগুলি আইটেম সর্বদা রেন্ডার করতে হবে তা নির্ধারণ করতে দেয়৷

<FixedSizeList
  //...
  overscanCount={4}
>
  {...}
</FixedSizeList>

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

FixedSizeGrid এবং VariableSizeGrid এর জন্য, ওভারস্ক্যান করার জন্য যথাক্রমে কলাম এবং সারির সংখ্যা নিয়ন্ত্রণ করতে overscanColumnsCount এবং overscanRowsCount বৈশিষ্ট্যগুলি ব্যবহার করুন।

উপসংহার

আপনার অ্যাপ্লিকেশনে তালিকা এবং টেবিল ভার্চুয়ালাইজ করা শুরু করার বিষয়ে আপনি যদি অনিশ্চিত হন তবে এই পদক্ষেপগুলি অনুসরণ করুন:

  1. রেন্ডারিং এবং স্ক্রলিং কর্মক্ষমতা পরিমাপ. এই নিবন্ধটি দেখায় যে কীভাবে Chrome DevTools-এ FPS মিটার ব্যবহার করে একটি তালিকায় আইটেমগুলি কতটা দক্ষতার সাথে রেন্ডার করা হয় তা অন্বেষণ করতে ব্যবহার করা যেতে পারে।
  2. পারফরম্যান্সকে প্রভাবিত করে এমন কোনো দীর্ঘ তালিকা বা গ্রিডের জন্য react-window অন্তর্ভুক্ত করুন।
  3. react-window কিছু বৈশিষ্ট্য সমর্থিত না থাকলে, আপনি যদি নিজে এই কার্যকারিতা যোগ করতে না পারেন তাহলে react-virtualized ব্যবহার করার কথা বিবেচনা করুন।
  4. আপনার ভার্চুয়ালাইজ করা তালিকাটি react-window-infinite-loader দিয়ে মুড়ে দিন যদি আপনি ব্যবহারকারীর স্ক্রোল করার সময় আইটেমগুলি অলসভাবে লোড করতে চান।
  5. আপনার তালিকার জন্য overscanCount প্রপার্টি ব্যবহার করুন এবং আপনার গ্রিডের জন্য overscanColumnsCount এবং overscanRowsCount প্রপার্টি ব্যবহার করুন যাতে খালি কন্টেন্ট ফ্ল্যাশ না হয়। খুব বেশি এন্ট্রি ওভারস্ক্যান করবেন না কারণ এটি কর্মক্ষমতাকে নেতিবাচকভাবে প্রভাবিত করবে।