paint-brush
প্রতিক্রিয়ায় স্মৃতিচারণ: শক্তিশালী হাতিয়ার বা লুকানো পিটফল?দ্বারা@socialdiscoverygroup
971 পড়া
971 পড়া

প্রতিক্রিয়ায় স্মৃতিচারণ: শক্তিশালী হাতিয়ার বা লুকানো পিটফল?

দ্বারা Social Discovery Group15m2024/07/01
Read on Terminal Reader

অতিদীর্ঘ; পড়তে

রিঅ্যাক্ট এপ্লিকেশন ডেভেলপমেন্টের একটি বিস্তৃত পদ্ধতি হল মুখস্থ করার সাথে সবকিছু কভার করা। সোশ্যাল ডিসকভারি গ্রুপ টিম আবিষ্কার করেছে যে কীভাবে রিঅ্যাক্ট অ্যাপে মেমোাইজেশনের অত্যধিক ব্যবহার পারফরম্যান্সের সমস্যা হতে পারে। কোথায় এটি ব্যর্থ হয় এবং কীভাবে আপনার বিকাশে এই লুকানো ফাঁদগুলি এড়ানো যায় তা শিখুন।
featured image - প্রতিক্রিয়ায় স্মৃতিচারণ: শক্তিশালী হাতিয়ার বা লুকানো পিটফল?
Social Discovery Group HackerNoon profile picture
0-item


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


Memoization কি?

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


 const cache = { } function calculate (a) { if (Object.hasOwn(cache, a)) { return cache[a] } cache[a] = a * a return cache[a] }


Memoization কর্মক্ষমতা উন্নতি, সম্পদ সঞ্চয়, এবং ফলাফল ক্যাশিং সহ বিভিন্ন সুবিধা প্রদান করে। যাইহোক, নতুন প্রপস না আসা পর্যন্ত রিঅ্যাক্টের মেমোাইজেশন কাজ করে, যার অর্থ শুধুমাত্র শেষ কলের ফলাফল সংরক্ষিত হয়।


 const prev = { value: null, result: null } function calculate(a) { if (prev.value === a) { return prev.result } prev.value = a prev.result = a * a return prev.result }


রিঅ্যাক্টে মেমোাইজেশন টুল

রিঅ্যাক্ট লাইব্রেরি আমাদের মেমোাইজেশনের জন্য বেশ কিছু টুল সরবরাহ করে। এগুলি হল HOC React.memo, হুকগুলি ব্যবহার করেCallback, useMemo এবং useEvent, সেইসাথে React.PureComponent এবং ক্লাস কম্পোনেন্টগুলির জীবনচক্র পদ্ধতি, shouldComponentUpdate৷ আসুন প্রথম তিনটি মেমোাইজেশন টুল পরীক্ষা করি এবং প্রতিক্রিয়াতে তাদের উদ্দেশ্য এবং ব্যবহার অন্বেষণ করি।


প্রতিক্রিয়া.মেমো

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


 const Button = memo((props) => { return ( <button onClick={props.onClick}> {props.title} </button> ) }, (prevProps, props) => { return props.title === prevProps.title })


React.useCallback

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


 const callback = useCallback(() => { // do something }, [a, b, c])


React.useMemo

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


 const value = useMemo(() => { return [1, 2, 3, 4, 5].filter(it => it % 2 === 0) }, [])


একটি প্রকল্পের সম্পূর্ণ স্মৃতিচারণ

প্রতিক্রিয়া বিকাশ দলগুলিতে, একটি বিস্তৃত অনুশীলন হল ব্যাপক স্মৃতিকরণ। এই পদ্ধতির মধ্যে সাধারণত অন্তর্ভুক্ত থাকে:

  • React.memo-এ সমস্ত উপাদান মোড়ানো
  • অন্যান্য উপাদানে পাস করা সমস্ত ফাংশনের জন্য useCallback ব্যবহার করা
  • ইউজমেমো সহ ক্যাশিং গণনা এবং রেফারেন্স প্রকার


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


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


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

  2. দ্বিতীয় পয়েন্ট হল যখন আমরা প্রপসে রেফারেন্স টাইপ পাস করি। এটা মনে রাখা এবং বোঝা গুরুত্বপূর্ণ যে রিঅ্যাক্টে কোন জাদু নেই – এটি একটি জাভাস্ক্রিপ্ট লাইব্রেরি যা জাভাস্ক্রিপ্টের নিয়ম অনুযায়ী কাজ করে। প্রপসের রেফারেন্স প্রকারগুলি (ফাংশন, অবজেক্ট, অ্যারে) বিপজ্জনক।


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


 const a = { c: 1 } const b = { c: 1 } a === b // false First call: MemoComponent(a) Second call: MemoComponent(b) const MemoComponent = memo(({object}) => { return <div /> }, (prevProps, props) => (prevProps.object === props.object)) // false


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


যদি আমরা কম্পোনেন্টের পরবর্তী কলে একই বস্তু বলে মনে করি তবে এটি আসলে একটি ভিন্ন (যেহেতু এটির রেফারেন্স ভিন্ন), অগভীর তুলনা যা প্রতিক্রিয়া ব্যবহার করে তা এই বস্তুগুলিকে আলাদা হিসাবে স্বীকৃতি দেবে। এটি মেমোতে মোড়ানো কম্পোনেন্টের রি-রেন্ডারকে ট্রিগার করবে, এইভাবে সেই উপাদানটির মেমোাইজেশন ভেঙে যাবে।


মেমোাইজ করা উপাদানগুলির সাথে নিরাপদ অপারেশন নিশ্চিত করতে, মেমো, ইউজ কলব্যাক এবং ইউজ মেমোর সংমিশ্রণ ব্যবহার করা গুরুত্বপূর্ণ। এইভাবে, সমস্ত রেফারেন্স প্রকারের ধ্রুবক রেফারেন্স থাকবে।

টিমওয়ার্ক: মেমো, ইউজ কলব্যাক, ইউজ মেমো

আসুন মেমো ভাঙ্গা যাক, আমরা করব?

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


মেমোাইজেশন ইনলাইন

চলুন একটি ক্লাসিক ভুল দিয়ে শুরু করা যাক, যেখানে প্যারেন্ট কম্পোনেন্টের প্রতিটি পরবর্তী রেন্ডারে, মেমোকৃত কম্পোনেন্ট মেমোকম্পোনেন্ট ক্রমাগত রি-রেন্ডার হবে কারণ প্যারামে পাস করা বস্তুর রেফারেন্স সবসময় নতুন হবে।


 const Parent = () => { return ( <MemoComponent params={[1, 2 ,3]} /> ) }


এই সমস্যা সমাধানের জন্য, পূর্বে উল্লিখিত useMemo হুক ব্যবহার করা যথেষ্ট। এখন, আমাদের বস্তুর রেফারেন্স সবসময় ধ্রুবক থাকবে।


 const Parent = () => { const params = useMemo(() => { return [1, 2 ,3] ), []) return ( <MemoComponent params={params} /> ) }


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


 const params = [1, 2 ,3] const Parent = () => { return ( <MemoComponent params={params} /> ) }


এই উদাহরণে একটি অনুরূপ পরিস্থিতি memoization ছাড়া একটি ফাংশন পাস করা হয়. এই ক্ষেত্রে, পূর্ববর্তী উদাহরণের মত, মেমো কম্পোনেন্টের মেমোাইজেশনটি একটি ফাংশন পাস করার মাধ্যমে ভেঙে দেওয়া হবে যার প্রতিটি রেন্ডারে প্যারেন্ট কম্পোনেন্টের একটি নতুন রেফারেন্স থাকবে। ফলস্বরূপ, MemoComponent নতুনভাবে রেন্ডার করবে যেন এটি মুখস্ত করা হয়নি।


 const Parent = () => { return ( <MemoComponent onClick={() => {}} /> ) }


এখানে, আমরা প্যারেন্ট কম্পোনেন্টের রেন্ডারের মধ্যে পাস করা ফাংশনের রেফারেন্স সংরক্ষণ করতে useCallback হুক ব্যবহার করতে পারি।


 const Parent = () => { const handleClick = useCallback(() => console.log('click') }, []) return ( <MemoComponent onClick={handleClick} /> ) }


নোট নেওয়া হয়েছে।

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


 function someFunction() { // expensive calculations (?) ... return () => {} } .............................. const Parent = () => { const cachedFunction = useCallback(someFunction(), []) return ( <MemoComponent onClick={cachedFunction} /> ) }


প্রপস ছড়াচ্ছে

পরবর্তী সাধারণ পরিস্থিতি হল প্রপস ছড়ানো। কল্পনা করুন আপনার উপাদানগুলির একটি চেইন আছে। এই চেইনের কিছু উপাদানের জন্য সম্ভাব্য অপ্রয়োজনীয়, InitialComponent থেকে পাস করা ডেটা প্রপ কতদূর যেতে পারে তা আপনি কতবার বিবেচনা করেন? এই উদাহরণে, এই প্রপটি চাইল্ডমেমো কম্পোনেন্টে মেমোাইজেশন ভেঙে দেবে কারণ, Initial Component-এর প্রতিটি রেন্ডারে, এর মান সবসময় পরিবর্তিত হবে। একটি বাস্তব প্রকল্পে, যেখানে মেমোাইজ করা উপাদানগুলির চেইন দীর্ঘ হতে পারে, সমস্ত মেমোইজেশন ভেঙে যাবে কারণ ক্রমাগত পরিবর্তনশীল মানগুলির সাথে অপ্রয়োজনীয় প্রপগুলি তাদের কাছে পাঠানো হয়:


 const Child = () => {} const ChildMemo = React.memo(Child) const Component = (props) => { return <ChildMemo {...props} /> } const InitialComponent = (props) => { // The only component that has state and can trigger a re-render return ( <Component {...props} data={Math.random()} /> ) }


নিজেকে রক্ষা করার জন্য, নিশ্চিত করুন যে শুধুমাত্র প্রয়োজনীয় মানগুলি মেমোাইজ করা উপাদানে পাস করা হয়েছে। ঐটার পরিবর্তে:


 const Component = (props) => { return <ChildMemo {...props} /> }


ব্যবহার করুন (শুধুমাত্র প্রয়োজনীয় প্রপস পাস করুন):


 const Component = (props) => { return ( <ChildMemo firstProp={prop.firstProp} secondProp={props.secondProp} /> ) )


মেমো এবং শিশু

আসুন নিম্নলিখিত উদাহরণ বিবেচনা করা যাক। একটি পরিচিত পরিস্থিতি হল যখন আমরা একটি উপাদান লিখি যা JSX কে শিশু হিসাবে গ্রহণ করে।


 const ChildMemo = React.memo(Child) const Component = () => { return ( <ChildMemo> <div>Text</div> </ChildMemo> ) }


প্রথম নজরে, এটি নিরীহ বলে মনে হয়, কিন্তু বাস্তবে, এটি নয়। আসুন কোডটি ঘনিষ্ঠভাবে দেখে নেওয়া যাক যেখানে আমরা একটি মেমোাইজড উপাদানে শিশুদের হিসাবে JSX পাস করি। এই সিনট্যাক্সটি 'শিশু' নামের একটি প্রপ হিসাবে এই 'div' পাস করার জন্য সিনট্যাকটিক চিনি ছাড়া আর কিছুই নয়।


শিশুরা অন্য কোনো প্রপ থেকে আলাদা নয় যা আমরা একটি উপাদানে পাস করি। আমাদের ক্ষেত্রে, আমরা JSX পাস করছি, এবং JSX, এর পরিবর্তে, `createElement` পদ্ধতির জন্য সিনট্যাকটিক চিনি, তাই মূলত, আমরা `div` টাইপ সহ একটি নিয়মিত অবজেক্ট পাস করছি। এবং এখানে, একটি memoized উপাদানের জন্য স্বাভাবিক নিয়ম প্রযোজ্য: যদি একটি নন-মেমোাইজ করা বস্তু প্রপসে পাস করা হয়, তাহলে উপাদানটি পুনরায় রেন্ডার করা হবে যখন এর প্যারেন্ট রেন্ডার করা হবে, কারণ প্রতিবার এই বস্তুর রেফারেন্স নতুন হবে।



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


 const Component = () => { const childrenContent = useMemo( () => <div>Text</div>, [], ) return ( <ChildMemo> {childrenContent} </ChildMemo> ) }


প্যারেন্টমেমো এবং চাইল্ডমেমো

এর একটি আরো আকর্ষণীয় উদাহরণ বিবেচনা করা যাক।


 const ParentMemo = React.memo(Parent) const ChildMemo = React.memo(Child) const App = () => { return ( <ParentMemo> <ChildMemo /> </ParentMemo> ) }


প্রথম নজরে, এটি নিরীহ বলে মনে হচ্ছে: আমাদের দুটি উপাদান রয়েছে, উভয়ই মুখস্থ। যাইহোক, এই উদাহরণে, প্যারেন্টমেমো এমন আচরণ করবে যেন এটি মেমোতে মোড়ানো নেই কারণ এর বাচ্চারা, চাইল্ডমেমো, মুখস্থ নয়। চাইল্ডমেমো কম্পোনেন্টের ফলাফল হবে JSX, এবং JSX হল React.createElement-এর জন্য সিনট্যাকটিক সুগার, যা একটি অবজেক্ট রিটার্ন করে। সুতরাং, React.createElement পদ্ধতি কার্যকর হওয়ার পরে, ParentMemo এবং ChildMemo নিয়মিত জাভাস্ক্রিপ্ট অবজেক্টে পরিণত হবে, এবং এই অবজেক্টগুলি কোনোভাবেই মেমোাইজ করা হয় না।

প্যারেন্টমেমো

চাইল্ড মেমো

{`` type: {`` ...`` $$typeof: Symbol(react.memo),`` type: {`` name: "Parent"`` }`` },`` ...``}

{`` type: {`` ...`` $$typeof: Symbol(react.memo),`` type: {`` name: "Child"`` }`` },`` ...``}


ফলস্বরূপ, আমরা একটি নন-মেমোাইজ করা বস্তুকে প্রপস-এ পাস করি, যার ফলে প্যারেন্ট কম্পোনেন্টের মেমোাইজেশন ভেঙ্গে যায়।


 const ParentMemo = React.memo(Parent) const ChildMemo = React.memo(Child) const App = () => { return ( <ParentMemo children={<ChildMemo />} /> ) }


এই সমস্যাটির সমাধান করার জন্য, পাস করা শিশুটিকে মুখস্থ করাই যথেষ্ট, এটি নিশ্চিত করে যে অভিভাবক অ্যাপ কম্পোনেন্টের রেন্ডারের সময় এটির রেফারেন্স স্থির থাকে।


 const App = () => { const child = useMemo(() => { return <ChildMemo /> }, []); return ( <ParentMemo> {child} </ParentMemo> ) }


কাস্টম হুক থেকে অ আদিম

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


 const Parent = () => { const { submit } = useForm() return <ComponentMemo onChange={submit} /> };


আমরা কি কোড থেকে বুঝতে পারি যে মেমোাইজড কম্পোনেন্ট কম্পোনেন্টমেমোতে প্রপ হিসাবে সাবমিট পদ্ধতি পাস করা নিরাপদ কিনা? অবশ্যই না। এবং সবচেয়ে খারাপ ক্ষেত্রে, কাস্টম হুকের বাস্তবায়ন এইরকম দেখতে পারে:


 const Parent = () => { const { submit } = useForm() return <ComponentMemo onChange={submit} /> }; const useForm = () => { const submit = () => {} return { submit } }


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


 const Parent = () => { const { submit } = useForm() return <ComponentMemo onChange={submit} /> }; const useForm = () => { const submit = useCallback(() => {}, []) return { submit } }


যখন আপনি memoization সঙ্গে সবকিছু আবরণ, এমনকি যখন memoization অতিরিক্ত?

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


 export function App() { const [state, setState] = useState('') const handleChange = (e) => { setState(e.target.value) } return ( <Form> <Input value={state} onChange={handleChange}/> </Form> ) } export const Input = memo((props) => (<input {...props} />))


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


 const activeQuestionNumber = useMemo(() => { return activeQuestionIndex + 1 }, [activeQuestionIndex]) const userAnswerImage = useMemo(() => { return `/i/call/quiz/${quizQuestionAnswer.userAnswer}.png` }, [quizQuestionAnswer.userAnswer])


দুটি সংখ্যা যোগ করা বা স্ট্রিং সংযুক্ত করার কাজটি কতটা সহজ তা বিবেচনা করে এবং এই উদাহরণগুলিতে আমরা আউটপুট হিসাবে আদিম পাই, এটা স্পষ্ট যে এখানে useMemo ব্যবহার করার কোন মানে হয় না। এখানে অনুরূপ উদাহরণ.


 const cta = useMemo(() => { return activeOverlayName === 'photos' ? 'gallery' : 'profile' }, [activeOverlayName]) const attendeeId = useMemo(() => { return userId === senderId ? recipientId : senderId }, [userId, recipientId, senderId])


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


উপসংহার

  1. অপ্টিমাইজেশান - সবসময় উপকারী নয়। *পারফরম্যান্স অপ্টিমাইজেশন বিনামূল্যে নয়, এবং এই অপ্টিমাইজেশানগুলির খরচ সর্বদা এগুলি থেকে আপনি যে সুবিধাগুলি লাভ করবেন তার সাথে সামঞ্জস্যপূর্ণ নাও হতে পারে৷
    *
  2. অপ্টিমাইজেশনের ফলাফল পরিমাপ করুন। *আপনি পরিমাপ না করলে, আপনার অপ্টিমাইজেশানগুলি কিছু উন্নতি করেছে কি না তা আপনি জানতে পারবেন না। এবং সবচেয়ে গুরুত্বপূর্ণভাবে, পরিমাপ ছাড়া, তারা জিনিসগুলিকে আরও খারাপ করেছে কিনা তা আপনি জানতে পারবেন না।
    *
  3. মুখস্থ করার কার্যকারিতা পরিমাপ করুন। *সম্পূর্ণ মেমোাইজেশন ব্যবহার করবেন কি না তা শুধুমাত্র আপনার নির্দিষ্ট ক্ষেত্রে এটি কীভাবে কাজ করে তা পরিমাপ করে বোঝা যাবে। কম্পিউটেশন ক্যাশিং বা মেমোাইজ করার সময় মেমোাইজেশন ফ্রি নয়, এবং এটি আপনার অ্যাপ্লিকেশনটি প্রথমবারের জন্য কত দ্রুত শুরু হয় এবং ব্যবহারকারীরা কত দ্রুত এটি ব্যবহার শুরু করতে পারে তা প্রভাবিত করতে পারে। উদাহরণস্বরূপ, আপনি যদি কিছু জটিল গণনা মুখস্থ করতে চান যার ফলাফল একটি বোতাম টিপলে সার্ভারে পাঠানোর প্রয়োজন হয়, আপনার অ্যাপ্লিকেশন শুরু হওয়ার পরে আপনার কি এটি মুখস্থ করা উচিত? হয়তো না, কারণ এমন একটি সুযোগ আছে যে ব্যবহারকারী কখনই সেই বোতাম টিপবেন না, এবং সেই জটিল গণনাটি সম্পূর্ণরূপে অপ্রয়োজনীয় হতে পারে।
    *
  4. আগে ভাবুন, তারপর মুখস্থ করুন। *কোন কম্পোনেন্টে মেমোইজিং প্রপস পাস করা শুধুমাত্র তখনই বোঝা যায় যদি এটি 'মেমো'-এ মোড়ানো হয়, অথবা যদি প্রাপ্ত প্রপগুলি হুকের নির্ভরতায় ব্যবহার করা হয়, এবং এছাড়াও যদি এই প্রপগুলি অন্যান্য মেমোাইজ করা উপাদানগুলিতে পাস করা হয়।
    *
  5. জাভাস্ক্রিপ্টের মূল নীতিগুলি মনে রাখবেন। রিঅ্যাক্ট বা অন্য কোন লাইব্রেরি এবং ফ্রেমওয়ার্কের সাথে কাজ করার সময়, এটি ভুলে যাওয়া গুরুত্বপূর্ণ নয় যে এই সবগুলি জাভাস্ক্রিপ্টে প্রয়োগ করা হয় এবং এই ভাষার নিয়ম অনুযায়ী কাজ করে।


পরিমাপের জন্য কি সরঞ্জাম ব্যবহার করা যেতে পারে?

আমরা আপনার অ্যাপ্লিকেশন কোডের কার্যকারিতা পরিমাপের জন্য এই সরঞ্জামগুলির মধ্যে অন্তত 4টি সুপারিশ করতে পারি।


প্রতিক্রিয়া.প্রোফাইলার

সঙ্গে প্রতিক্রিয়া.প্রোফাইলার , আপনি প্রাথমিক এবং পরবর্তী রেন্ডারের সময় সম্পর্কে তথ্য পেতে আপনার প্রয়োজনীয় নির্দিষ্ট উপাদান বা সম্পূর্ণ অ্যাপ্লিকেশনটি মোড়ানো করতে পারেন। আপনিও বুঝতে পারবেন সঠিক কোন ফেজে মেট্রিক নেওয়া হয়েছে।


প্রতিক্রিয়া বিকাশকারী সরঞ্জাম

প্রতিক্রিয়া বিকাশকারী সরঞ্জাম একটি ব্রাউজার এক্সটেনশন যা আপনাকে উপাদান অনুক্রম পরিদর্শন করতে, রাজ্য এবং প্রপসের পরিবর্তনগুলি ট্র্যাক করতে এবং অ্যাপ্লিকেশনটির কার্যকারিতা বিশ্লেষণ করতে দেয়৷


প্রতিক্রিয়া রেন্ডার ট্র্যাকার

আরেকটি আকর্ষণীয় টুল হল প্রতিক্রিয়া রেন্ডার ট্র্যাকার , যা সম্ভাব্য অপ্রয়োজনীয় রি-রেন্ডার সনাক্ত করতে সাহায্য করে যখন নন-মেমোইজড উপাদানগুলির প্রপগুলি পরিবর্তন বা অনুরূপগুলির সাথে পরিবর্তিত হয় না।


স্টোরিবুক-অ্যাডন-পারফরম্যান্স অ্যাডন সহ স্টোরিবুক।

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



** লিখেছেন সের্গেই লেভকোভিচ, সোশ্যাল ডিসকভারি গ্রুপের সিনিয়র সফটওয়্যার ইঞ্জিনিয়ার