Memoization هي تقنية تحسين ، تشبه التخزين المؤقت. إنه يعمل عن طريق تخزين النتائج السابقة لاستدعاء الوظيفة واستخدام تلك النتائج في المرة التالية التي يتم فيها تشغيل الوظيفة. إنه مفيد بشكل خاص في التطبيقات ذات العمليات الحسابية الثقيلة التي تكرر استدعاءات الوظائف على نفس المعلمات.

يمكنك استخدام memoization في JavaScript عادي وأيضًا في React ، بعدة طرق مختلفة.

Memoization في JavaScript

لحفظ وظيفة في JavaScript ، تحتاج إلى تخزين نتائج هذه الوظيفة في ذاكرة تخزين مؤقت. يمكن أن تكون ذاكرة التخزين المؤقت كائنًا باستخدام الوسائط كمفاتيح والنتائج كقيم.

عند استدعاء هذه الوظيفة ، فإنها تتحقق أولاً مما إذا كانت النتيجة موجودة في ذاكرة التخزين المؤقت قبل التشغيل. إذا كان الأمر كذلك ، فإنه يقوم بإرجاع النتائج المخزنة مؤقتًا. خلاف ذلك ، يتم تنفيذه.

ضع في اعتبارك هذه الوظيفة:

وظيفةميدان(الأسطوانات) {
إرجاع الأسطوانات * الأسطوانات
}

تأخذ الدالة وسيطة وتعيد مربعها.

لتشغيل الوظيفة ، قم بتسميتها برقم مثل هذا:

ميدان(5) // 25

باستخدام 5 كوسيطة ، سيتم تشغيل المربع () بسرعة كبيرة. ومع ذلك ، إذا كنت تريد حساب مربع 70000 ، فسيكون هناك تأخير ملحوظ. ليس كثيرا ولكن مع ذلك تأخير. الآن ، إذا اتصلت بالوظيفة عدة مرات واجتازت 70000 ، فستواجه تأخيرًا في كل مكالمة.

instagram viewer

يمكنك القضاء على هذا التأخير باستخدام الذاكرة.

مقدار ثابت memoizedSquare = () => {
يترك مخبأ = {};
إرجاع (عدد) => {
إذا (الأسطوانات في مخبأ) {
console.log ('إعادة استخدام القيمة المخزنة مؤقتًا');
إرجاع مخبأ[الأسطوانات];
} آخر {
console.log ('نتيجة الحساب');
يترك النتيجة = الأسطوانات * الأسطوانات ؛

// مخبأ ال الجديدنتيجةالقيمةإلى عن علىالتاليزمن
مخبأ[الأسطوانات] = نتيجة;
إرجاع نتيجة؛
}
}
}

في هذا المثال ، تتحقق الوظيفة مما إذا كانت قد احتسبت النتيجة من قبل ، عن طريق التحقق مما إذا كانت موجودة في كائن ذاكرة التخزين المؤقت. إذا كان يحتوي على إرجاع القيمة المحسوبة بالفعل.

عندما تتلقى الوظيفة رقمًا جديدًا ، فإنها تحسب قيمة جديدة وتخزن النتائج في ذاكرة التخزين المؤقت قبل أن تعود.

مرة أخرى ، هذا المثال بسيط جدًا ، لكنه يشرح كيفية عمل الحفظ على تحسين أداء البرنامج.

يجب عليك فقط حفظ الوظائف الصرفة. ترجع هذه الدالات نفس النتيجة عندما تمرر نفس الوسيطات في. إذا كنت تستخدم الذاكرة على وظائف غير نقية ، فلن تقوم بتحسين الأداء ولكن ستزيد من النفقات العامة. ذلك لأنك تختار السرعة على الذاكرة في كل مرة تحفظ فيها إحدى الوظائف.

Memoization في React

إذا كنت تبحث عن تحسين مكونات React ، فإن React توفر خاصية الذاكرة من خلال الخطاف useMemo () ، React.memo ، و useCallBack ().

باستخدام useMemo ()

useMemo () هو ملف رد فعل هوك يقبل دالة ومجموعة تبعية.

مقدار ثابت memoizedValue = useMemo (() => computeExpensiveValue (أ ، ب) ، [أ ، ب]) ؛

يحفظ القيمة التي تم إرجاعها من تلك الوظيفة. تملي القيم الموجودة في مصفوفة التبعية وقت تنفيذ الوظيفة. فقط عندما يتغيرون يتم تنفيذ الوظيفة مرة أخرى.

على سبيل المثال ، يحتوي مكون التطبيق التالي على قيمة ذاكرة تسمى النتيجة.

يستورد {useMemo} من "تتفاعل"
وظيفةتطبيق(القيمة) {
مقدار ثابت مربع = (القيمة) => {
إرجاع القيمة * القيمة
}
مقدار ثابت النتيجة = useMemo (
() => مربع (القيمة) ،
[ القيمة ]
);
إرجاع (
<شعبة>{نتيجة (5)}</div>
)
}

يستدعي مكون التطبيق square () في كل تصيير. سينخفض ​​الأداء إذا تم عرض مكون التطبيق عدة مرات بسبب رد الفعل الدعائم التغيير أو تحديث الحالة ، خاصةً إذا كانت وظيفة المربع () باهظة الثمن.

ومع ذلك ، نظرًا لأن useMemo () يخزن القيم التي تم إرجاعها مؤقتًا ، لا يتم تنفيذ وظيفة التربيع في كل إعادة تصيير ما لم تتغير الوسيطات في مصفوفة التبعية.

باستخدام React.memo ()

React.memo () هو مكون ذو رتبة أعلى يقبل مكون React ودالة كوسيطات. تحدد الوظيفة متى يجب تحديث المكون.

الوظيفة اختيارية وإذا لم يتم توفيرها ، تقوم React.memo بإجراء مقارنة سطحية للخصائص الحالية للمكون بدعاماتها السابقة. إذا كانت الدعائم مختلفة ، فسيتم تشغيل التحديث. إذا كانت الخاصيات هي نفسها ، فإنها تتخطى إعادة التصيير وتعيد استخدام القيم المحفوظة في الذاكرة.

تقبل الوظيفة الاختيارية الخاصيّات السابقة والعناصر التالية كوسائط. يمكنك بعد ذلك مقارنة هذه الخاصيات بشكل صريح لتقرير ما إذا كنت تريد تحديث المكون أم لا.

تتفاعل.مذكرة(مكون, [areEqual (prevProps، nextProps)])

دعونا نلقي نظرة على مثال بدون وسيطة الوظيفة الاختيارية أولاً. يوجد أدناه مكون يسمى التعليقات يقبل الاسم ودعائم البريد الإلكتروني.

وظيفةتعليقات ({الاسم ، التعليق ، الإعجابات}) {
إرجاع (
<شعبة>
<ص>{اسم}</ ص>
<ص>{تعليق}</ ص>
<ص>{الإعجابات}</ ص>
</div>
)
}

سيكون لمكوِّن التعليقات المحفوظة في ذاكرة React.memo ملفوفًا حوله كما يلي:

مقدار ثابت MemoizedComment = React.memo (تعليق)

يمكنك تسميته بعد ذلك مثل أي مكون React آخر.

<MemoizedComment اسم ="ماري" تعليق ="Memoization رائع" الإعجابات = 1 />

إذا كنت تريد إجراء مقارنة props بنفسك ، فمرر الوظيفة التالية إلى React.memo كمتغير ثانٍ.

يستورد تتفاعل من "تتفاعل"
وظيفةcheck تعليق(prevProps، nextProps) {
إرجاع prevProps.name nextProps.name
&& prevProps.comment nextProps.comment
&& prevProps.likes nextProps.likes. تسجيلات الإعجاب
}

مقدار ثابت MemoizedComment = React.memo (التعليقات ، checkCommentProps)

إذا أعاد checkProfileProps صحيحًا ، فلن يتم تحديث المكون. خلاف ذلك ، يتم إعادة تقديمه.

تكون الوظيفة المخصصة مفيدة عندما تريد تخصيص إعادة التصيير. على سبيل المثال ، يمكنك استخدامه لتحديث مكون التعليقات فقط عندما يتغير عدد الإعجابات.

على عكس الخطاف useMemo () الذي يحفظ القيمة المرجعة للدالة فقط ، فإن React.memo يحفظ الوظيفة بأكملها.

استخدم React.memo فقط للمكونات النقية. أيضًا ، لتقليل تكاليف المقارنة ، احفظ فقط المكونات التي تتغير دعائمها كثيرًا.

باستخدام useCallBack ()

يمكنك استخدام الخطاف useCallBack () للحفظ مكونات الوظيفة.

مقدار ثابت memoizedCallback = useCallback (
() => {
افعل شيئًا (أ ، ب) ؛
},
[أ ، ب],
);

يتم تحديث الوظيفة فقط عندما تتغير القيم في مصفوفة التبعية. يعمل الخطاف مثل رد نداء useMemo () ، لكنه يحفظ مكون الوظيفة بين عمليات العرض بدلاً من حفظ القيم.

ضع في اعتبارك المثال التالي لوظيفة memoized التي تستدعي API.

يستورد {useCallback، useEffect} من "تتفاعل"؛
مقدار ثابت المكون = () => {
مقدار ثابت getData = useCallback (() => {
console.log ('استدعاء API');
}, []);
useEffect (() => {
احصل على البيانات()؛
}, [احصل على البيانات]);
};

سيتم استدعاء دالة getData () التي تسمى في useEffect مرة أخرى فقط عندما تتغير قيمة getData.

هل يجب عليك Memoize؟

في هذا البرنامج التعليمي ، تعلمت ما هو التذكر ، وفوائده ، وكيفية تنفيذه في JavaScript و React. ومع ذلك ، يجب أن تعلم أن React سريع بالفعل. في معظم الحالات ، يضيف حفظ المكونات أو القيم تكاليف المقارنة ولا يؤدي إلى تحسين الأداء. لهذا السبب ، احفظ فقط المكونات باهظة الثمن.

قدمت React 18 أيضًا خطافات جديدة مثل useId و useTransition و useInsertionEffect. يمكنك استخدامها لتحسين أداء وتجربة المستخدم لتطبيقات React.