React Native এ useMemo হুক কম্পোনেন্ট রি-রেন্ডারের মধ্যে গণনার ফলাফল মেমোইজ করে, ব্যয়বহুল অপারেশনের পুনরাবৃত্তি রোধ করে। useCallback এর বিপরীতে, যা একটি ফাংশন মেমোইজ করে, useMemo ফেরত দেওয়া মান সংরক্ষণ করে এবং শুধুমাত্র নির্দিষ্ট নির্ভরতা পরিবর্তিত হলে পুনরায় গণনা করে। React Docs, 2024 অনুসারে, মেমোইজেশন বিশেষভাবে বড় অ্যারে এবং জটিল ডেটা রূপান্তর সহ গণনার জন্য কার্যকর। React Native এ, প্রতিটি অপ্রয়োজনীয় রি-রেন্ডার JavaScript এবং নেটিভ থ্রেডের মধ্যে ব্রিজ সংযোগে অতিরিক্ত লোড তৈরি করে, তাই useMemo এর সঠিক ব্যবহার সরাসরি অ্যানিমেশনের মসৃণতা এবং ইন্টারফেসের প্রতিক্রিয়া গতিকে প্রভাবিত করে।
মূল বিষয়
useMemo — React স্ট্যান্ডার্ড লাইব্রেরির একটি হুক, যা অতিরিক্ত প্যাকেজ ছাড়াই React Native এ উপলব্ধ। এটি পাস করা ফাংশনের দ্বারা ফেরত দেওয়া মান মেমোইজ করে এবং পরবর্তী রি-রেন্ডারে এই মান পুনরায় ব্যবহার করে যতক্ষণ না অ্যারেতে নির্দিষ্ট নির্ভরতাগুলি পরিবর্তিত হয়।
হুকের নাম memoization থেকে এসেছে — একটি অপ্টিমাইজেশন কৌশল যেখানে একটি ব্যয়বহুল ফাংশনের ফলাফল ক্যাশে সংরক্ষণ করা হয়। একই আর্গুমেন্ট সহ পরবর্তী কলগুলিতে, পুনরায় গণনার পরিবর্তে ক্যাশ করা মান ফেরত দেওয়া হয়।
React Native এর প্রেক্ষাপটে, আর্কিটেকচারাল বৈশিষ্ট্যের কারণে মেমোইজেশন বিশেষভাবে গুরুত্বপূর্ণ। প্রতিটি কম্পোনেন্ট রি-রেন্ডার JavaScript — নেটিভ ব্রিজ এর মাধ্যমে ডেটা পাঠায়, যা সময় নেয়। যদি একটি কম্পোনেন্টে ব্যয়বহুল গণনা থাকে (তালিকা ফিল্টারিং, সাজানো, ফরম্যাটিং), প্রতিটি রি-রেন্ডার সেগুলি পুনরাবৃত্তি করবে, JS থ্রেড ব্লক করবে এবং ফ্রেম ড্রপের কারণ হবে।
React Native Performance Docs, 2024 অনুসারে, বাধা প্রায়শই নেটিভ কম্পোনেন্টের রেন্ডারিং নয়, বরং রি-রেন্ডারের মধ্যে JavaScript লজিকের নির্বাহ। useMemo এই সমস্যারই সমাধান করে।
useMemo একটি ফাংশন এবং একটি নির্ভরতা অ্যারে নেয়, একটি মেমোইজড মান ফেরত দেয়। React পূর্ববর্তী মান এবং নির্ভরতা অ্যারে সংরক্ষণ করে। প্রতিটি রি-রেন্ডারে, React Object.is ব্যবহার করে বর্তমান নির্ভরতাগুলির পূর্ববর্তীগুলির সাথে তুলনা করে। যদি কমপক্ষে একটি নির্ভরতা পরিবর্তিত হয়, ফাংশনটি আবার নির্বাহিত হয় এবং ফলাফল সংরক্ষিত হয়।
useMemo এর সিগনেচার ওয়েব এবং React Native এ সম্পূর্ণ অভিন্ন। প্রথম আর্গুমেন্ট হল প্যারামিটারবিহীন একটি ফাংশন যা মেমোইজ করা মান ফেরত দেয়। দ্বিতীয়টি নির্ভরতা অ্যারে, যার পরিবর্তনে মান পুনরায় গণনা করা হবে।
import React, { useMemo } from 'react';
const sortedList = useMemo(() => {
return items.sort((a, b) => a.name.localeCompare(b.name));
}, [items]);
এই উদাহরণে, sortedList শুধুমাত্র তখন পুনরায় গণনা করা হয় যখন items অ্যারের রেফারেন্স পরিবর্তিত হয়। যদি অ্যারের বিষয়বস্তু পরিবর্তিত হয় কিন্তু রেফারেন্স একই থাকে (মিউটেশন), useMemo পরিবর্তনগুলি সনাক্ত করবে না — এটি একটি গুরুত্বপূর্ণ সীমাবদ্ধতা।
React নির্ভরতা তুলনার জন্য Object.is অ্যালগরিদম ব্যবহার করে, যা কঠোর সমতা === এর মতো কাজ করে কিন্তু NaN সঠিকভাবে হ্যান্ডেল করে (+0 এবং -0 ভিন্ন হিসাবে গণ্য হয়)। এর অর্থ হল প্রিমিটিভ টাইপের (স্ট্রিং, সংখ্যা, বুলিয়ান) জন্য তুলনা মান দ্বারা কাজ করে, যখন অবজেক্ট এবং অ্যারের জন্য — রেফারেন্স দ্বারা।
// Object.is({'a': 1}, {'a': 1}) -> false (different refs)
// Object.is(42, 42) -> true (primitive by value)
// Object.is(NaN, NaN) -> true (correct handling of NaN)
এই মেকানিজম বোঝা গুরুত্বপূর্ণ: যদি আপনি প্রতি রি-রেন্ডারে নির্ভরতায় একটি নতুন অবজেক্ট পাস করেন, মেমোইজেশন অকেজো হবে কারণ নির্ভরতাগুলি প্রতিবার পরিবর্তিত বলে গণ্য হবে।
useMemo তিনটি পরিস্থিতিতে যুক্তিযুক্ত: ব্যয়বহুল গণনা, চাইল্ড কম্পোনেন্টে স্থিতিশীল props পাস করা, এবং অবজেক্টের রেফারেন্সিয়াল আইডেন্টিটি সংরক্ষণ করা। React Native এ, মোবাইল অ্যাপ্লিকেশনের আর্কিটেকচারের কারণে তিনটি পরিস্থিতিই নিয়মিত ঘটে।
যদি একটি কম্পোনেন্ট বড় ডেটা অ্যারে (ফিল্টারিং, সাজানো, গ্রুপিং) বা সংস্থান-নিবিড় গাণিতিক অপারেশন প্রক্রিয়া করে, useMemo প্রতিটি রি-রেন্ডারে এই গণনাগুলির পুনরাবৃত্তি রোধ করে। মোবাইল অ্যাপ্লিকেশনে, একটি সাধারণ উদাহরণ হল তালিকায় প্রদর্শনের আগে API থেকে ডেটা ফরম্যাট করা।
যখন একটি চাইল্ড কম্পোনেন্ট React.memo এ মোড়ানো থাকে, এটি শুধুমাত্র তার props পরিবর্তিত হলে পুনরায় রেন্ডার করে। যদি প্যারেন্টের ভিতরে useMemo ছাড়া একটি prop অবজেক্ট তৈরি করা হয়, প্যারেন্টের প্রতিটি রি-রেন্ডারে একটি নতুন রেফারেন্স তৈরি হবে, এবং চাইল্ড কম্পোনেন্ট অপ্রয়োজনীয়ভাবে রি-রেন্ডার করবে, যা React.memo এর সুবিধা বাতিল করবে।
React Native এ, স্টাইল প্রায়ই props এর উপর নির্ভর করে — উদাহরণস্বরূপ, একটি এলিমেন্টের প্রস্থ স্ক্রিন আকার এর ভিত্তিতে গণনা করা হয়। useMemo শুধুমাত্র ইনপুট প্যারামিটার পরিবর্তিত হলে এই ধরনের ডায়নামিক স্টাইল গণনা করার অনুমতি দেয়।
useMemo কোন সার্বজনীন অপ্টিমাইজেশন সরঞ্জাম নয়। বেশ কয়েকটি পরিস্থিতিতে এটি কোন সুবিধা দেয় না এবং নির্ভরতা সংরক্ষণ ও তুলনার ওভারহেডের কারণে পারফরম্যান্স খারাপও করতে পারে। React Native এ, যেখানে মেমোরির প্রতিটি বাইট গুরুত্বপূর্ণ, প্রভাব না মেপে useMemo অন্ধভাবে প্রয়োগ করা একটি অ্যান্টি-প্যাটার্ন।
হুকটি তিনটি প্রধান ক্ষেত্রে কোন সুবিধা দেয় না। প্রথমত, যদি গণনা তুচ্ছ হয় (সরল যোগ, স্ট্রিং সংযোজন), useMemo এর খরচ নিজেই গণনার খরচকে ছাড়িয়ে যায়। দ্বিতীয়ত, যদি নির্ভরতাগুলি প্রতি রেন্ডারে পরিবর্তিত হয় — ফাংশনটি তবুও নির্বাহিত হবে, এবং মেমোইজেশন কেবল অতিরিক্ত কাজ যোগ করে। তৃতীয়ত, যদি কম্পোনেন্ট খুব কমই রেন্ডার হয়, ক্যাশ সংরক্ষণের ওভারহেড ন্যায্য নয়।
Kent C. Dodds, 2023 অনুসারে, useMemo যোগ করার আগে, React DevTools Profiler বা React Native এ অন্তর্নির্মিত Performance Monitor ব্যবহার করে সমস্যাটি পরিমাপ করা উচিত। যদি একটি কম্পোনেন্ট রি-রেন্ডার 1 ms এর কম সময় নেয়, মেমোইজেশন প্রয়োজন নেই।
useMemo এবং useCallback — React এর দুটি মেমোইজেশন হুক যা প্রায়ই বিভ্রান্তিকর। পার্থক্য হল তারা কী সংরক্ষণ করে: useMemo একটি ফাংশন নির্বাহের ফলাফল (যেকোনো মান) ফেরত দেয়, যখন useCallback ফাংশনটি নিজেই ফেরত দেয়। উভয়ই নির্ভরতা অ্যারে নেয়, কিন্তু সিনট্যাক্স ভিন্ন।
| বৈশিষ্ট্য | useMemo | useCallback |
|---|---|---|
| ফেরত দেয় | ফাংশন নির্বাহের ফলাফল | ফাংশনের রেফারেন্স |
| প্রথম আর্গুমেন্ট | মান ফেরত দেয় এমন ফাংশন | মেমোইজ করার ফাংশন |
| সাধারণ ব্যবহার | গণনা ক্যাশ করা | চাইল্ড কম্পোনেন্টের জন্য স্থিতিশীল কলব্যাক |
| সমতুল্যতা | useMemo(() => fn, deps) | useCallback(fn, deps) === useMemo(() => fn, deps) |
অনুশীলনে, useCallback হল useMemo এর উপর সিনট্যাকটিক সুগার যখন আপনি একটি ফাংশন মেমোইজ করতে চান। React Native এ, উভয় হুক সমানভাবে ব্যবহৃত হয়: useMemo — ডেটার জন্য (ফরম্যাটেড টেক্সট, গণনা করা স্টাইল), useCallback — ইভেন্ট হ্যান্ডলারের জন্য (onPress, onChangeText)।
React Native অ্যাপ্লিকেশনে useMemo ব্যবহারের দুটি বাস্তব পরিস্থিতি দেখি। প্রথমটি হল অনুসন্ধান কোয়েরি দ্বারা পরিচিতি তালিকা ফিল্টার করা, দ্বিতীয়টি হল স্ক্রিন আকারের ভিত্তিতে ডায়নামিক স্টাইল গণনা করা।
এই উদাহরণে, useMemo একটি বড় পরিচিতি তালিকা এর প্রতিটি রি-রেন্ডারে বারবার ফিল্টারিং রোধ করে যদি অনুসন্ধান কোয়েরি বা উৎস ডেটা কোনটিই পরিবর্তিত না হয়।
const ContactList = ({ contacts, searchQuery }) => {
const filteredContacts = useMemo(() => {
if (!searchQuery.trim()) return contacts;
const query = searchQuery.toLowerCase();
return contacts.filter((c) =>
c.name.toLowerCase().includes(query) ||
c.phone.includes(query)
);
}, [contacts, searchQuery]);
return (
<FlatList
data={filteredContacts}
renderItem={renderContact}
keyExtractor={(item) => item.id}
/>
);
};
useMemo ছাড়া, ফিল্টারিং প্রতি রেন্ডারে নির্বাহিত হবে, যার মধ্যে অ্যানিমেশন বা কম্পোনেন্টের অন্যান্য অংশে অবস্থা পরিবর্তনের কারণে সৃষ্ট রেন্ডারও অন্তর্ভুক্ত। useMemo এর সাথে, ফিল্টারিং শুধুমাত্র তখন চলে যখন contacts বা searchQuery পরিবর্তিত হয়।
React Native এ, স্টাইল প্রায়ই স্ক্রিন মাত্রা বা কম্পোনেন্ট props এর উপর নির্ভর করে। useMemo এই ধরনের স্টাইল অবজেক্ট একবার গণনা করতে এবং নির্ভরতা পরিবর্তিত না হওয়া পর্যন্ত পুনরায় ব্যবহার করার অনুমতি দেয়।
const Card = ({ title, isSelected }) => {
const cardStyle = useMemo(() => ({
backgroundColor: isSelected ? '#e3f2fd' : '#ffffff',
borderWidth: isSelected ? 2 : 1,
padding: 16,
}), [isSelected]);
return (
<View style={cardStyle}>
<Text>{title}</Text>
</View>
);
};
এই পদ্ধতি নিশ্চিত করে যে cardStyle অবজেক্ট স্থিতিশীল (একই রেফারেন্স) থাকে যতক্ষণ না isSelected পরিবর্তিত হয়। যদি Card React.memo এ মোড়ানো থাকে, এই প্যাটার্ন চাইল্ড এলিমেন্টের অপ্রয়োজনীয় রি-রেন্ডার রোধ করে।
সচরাচর জিজ্ঞাসা
useMemo একটি মেমোইজড মান ফেরত দেয় — প্রথম আর্গুমেন্ট হিসেবে পাস করা ফাংশনের নির্বাহের ফলাফল। পরবর্তী রি-রেন্ডারে, React ক্যাশ করা মান ফেরত দেয় যদি নির্ভরতাগুলি পরিবর্তিত না হয়।
useMemo ফাংশন নির্বাহের ফলাফল ফেরত দেয় (যেকোনো মান: সংখ্যা, অবজেক্ট, JSX), যখন useCallback নিজেই ফাংশন ফেরত দেয়। মনে রাখবেন useCallback(fn, deps) useMemo(() => fn, deps) এর সমতুল্য।
useMemo তুচ্ছ গণনার (যোগ, সংযোজন), বিরল রি-রেন্ডার, প্রতি রেন্ডারে পরিবর্তনশীল নির্ভরতা এবং প্রিমিটিভ টাইপের জন্য অকেজো। useMemo যোগ করার আগে সর্বদা পারফরম্যান্স পরিমাপ করুন।
হ্যাঁ, যদি অপ্রয়োজনীয়ভাবে ব্যবহার করা হয়। React পূর্ববর্তী মান মেমোরিতে সংরক্ষণ করে এবং প্রতি রেন্ডারে নির্ভরতা তুলনা করে। সরল গণনার জন্য, এই অপারেশনগুলির ওভারহেড মেমোইজেশনের সুবিধাকে ছাড়িয়ে যায়।
কম্পোনেন্ট রেন্ডার সময় মাপতে React DevTools Profiler ব্যবহার করুন। React Native এ, ডেভেলপার মেনুর মাধ্যমে পারফরম্যান্স মনিটরও উপলব্ধ। যদি রি-রেন্ডার 1 ms এর কম সময় নেয় — useMemo প্রয়োজন নেই।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন