الفرق بين المراجعتين لصفحة: «ReactNative/ram bundles inline requires»

من موسوعة حسوب
لا ملخص تعديل
طلا ملخص تعديل
 
(1 مراجعات متوسطة بواسطة نفس المستخدم غير معروضة)
سطر 1: سطر 1:
== حُزم وحدات RAM والمتطلبات المُضمَّنة Inline Requires ==
<noinclude>{{DISPLAYTITLE:حزم وحدات الوصول العشوائي والطلبيات المضمنة في React Native}}</noinclude>
إن كان لديك تطبيق كبير، فقد ترغب في التفكير في تنسيق حزمة وحدات الوصول العشوائي (Random Access Modules اختصارًا RAM)، واستخدام المتطلبات المضمَّنة inline requires. هذا مفيد للتطبيقات التي تحتوي على عدد كبير من الشاشات التي قد لا تُفتَح أبدًا أثناء استخدام التطبيق المعتاد، ويكون ذلك مفيدًا للتطبيقات التي تحتوي على كميات كبيرة من الشيفرة التي لا تحتاج إليها لفترة من الوقت بعد بدء التشغيل. قد يشتمل التطبيق مثلًا على شاشات فحص أداء معقدة أو ميزات أقل استخدامًا، ولكن معظم الجلسات تتضمن فقط زيارة شاشة التطبيق الرئيسية للحصول على التحديثات. يمكننا تحسين تحميل الحزمة باستخدام وحدة RAM وطلب هذه الميزات والشاشات لتكون مضمَّنة مسبقًا (عند استخدامها بالفعل).
إن كان لديك تطبيق كبير، فقد ترغب في التفكير في تنسيق حزمة وحدات الوصول العشوائي RAM Bundle (اختصارًا إلى Random Access Modules)، واستخدام الطلبيات المضمَّنة inline requires. هذا مفيد للتطبيقات التي تحتوي على عدد كبير من الشاشات التي قد لا تُفتَح أبدًا أثناء استخدام التطبيق المعتاد، ويكون ذلك مفيدًا للتطبيقات التي تحتوي على كميات كبيرة من الشيفرة التي لا تحتاج إليها لفترة من الوقت بعد بدء التشغيل. قد يشتمل التطبيق مثلًا على شاشات فحص أداء معقدة أو ميزات أقل استخدامًا، ولكن معظم الجلسات تتضمن فقط زيارة شاشة التطبيق الرئيسية للحصول على التحديثات. يمكننا تحسين تحميل الحزمة باستخدام وحدة RAM وطلب هذه الميزات والشاشات لتكون مضمَّنة مسبقًا (عند استخدامها بالفعل).


=== تحميل شيفرة JavaScript ===
== تحميل شيفرة JavaScript ==
يجب تحميل شيفرة JS في الذاكرة وتحليلها، قبل أن يتمكن react-native من تنفيذها. إذا حمَّلت حزمة bundle بحجم 50 ميجابايت مع الحزمة المعيارية، فيجب تحميلها كلها وتحليلها قبل تنفيذ أي منها. يتمثل التحسين الكامن وراء حزم RAM في أنه يمكنك فقط تحميل جزء من الـ 50 ميجابايت الذي تحتاجه بالفعل عند بدء التشغيل، وتحميل المزيد من الحزمة تدريجيًا حسب الحاجة إلى هذه الأجزاء.
يجب تحميل شيفرة JS في الذاكرة وتحليلها، قبل أن يتمكن react-native من تنفيذها. إذا حمَّلت حزمة bundle بحجم 50 ميجابايت مع الحزمة المعيارية، فيجب تحميلها كلها وتحليلها قبل تنفيذ أي منها. يتمثل التحسين الكامن وراء حزم RAM في أنه يمكنك فقط تحميل جزء من الـ 50 ميجابايت الذي تحتاجه بالفعل عند بدء التشغيل، وتحميل المزيد من الحزمة تدريجيًا حسب الحاجة إلى هذه الأجزاء.


=== المتطلبات المضمَّنة ===
== الطلبيات المضمنة ==
تؤخّر المتطلبات المضمَّنة طلب وحدة أو ملف حتى تكون هناك حاجة فعلية لهذا الملف كما في المثال الأساسي التالي:
تؤخّر الطلبيات المضمَّنة طلب وحدة أو ملف حتى تكون هناك حاجة فعلية لهذا الملف كما في المثال الأساسي التالي:


==== VeryExpensive.js ====
=== VeryExpensive.js ===
<syntaxhighlight lang="javascript">
<syntaxhighlight lang="javascript">
import React, { Component } from 'react';
import React, { Component } from 'react';
سطر 25: سطر 25:
</syntaxhighlight>
</syntaxhighlight>


==== Optimized.js ====
=== Optimized.js ===
<syntaxhighlight lang="javascript">
<syntaxhighlight lang="javascript">
import React, { Component } from 'react';
import React, { Component } from 'react';
سطر 56: سطر 56:
   }
   }
}
}
</syntaxhighlight>يمكن أن تؤدي المتطلبات المضمَّنة إلى تحسينات وقت بدء التشغيل حتى بدون تنسيق RAM، لأن الشيفرة الموجودة في VeryExpensive.js ستُنفَّذ فقط بمجرد أن تكون مطلوبةً لأول مرة.
</syntaxhighlight>يمكن أن تؤدي الطلبيات المضمَّنة إلى تحسينات وقت بدء التشغيل حتى بدون تنسيق RAM، لأن الشيفرة الموجودة في VeryExpensive.js ستُنفَّذ فقط بمجرد أن تكون مطلوبةً لأول مرة.


=== تفعيل التنسيق RAM ===
== تفعيل التنسيق RAM ==
سينشئ تنسيق RAM على نظام iOS ملفًا مفهرسًا واحدًا بحيث يحمّل react native وحدةً منه فقط في كل مرة، بينما سينشئ على نظام Android مجموعة من الملفات لكل وحدة افتراضيًا. يمكنك إجبار نظام Android على إنشاء ملف واحد كنظام iOS، ولكن استخدام ملفات متعددة يمكن أن يكون أكثر فاعلية ويتطلب ذاكرة أقل.
سينشئ تنسيق RAM على نظام iOS ملفًا مفهرسًا واحدًا بحيث يحمّل react native وحدةً منه فقط في كل مرة، بينما سينشئ على نظام Android مجموعة من الملفات لكل وحدة افتراضيًا. يمكنك إجبار نظام Android على إنشاء ملف واحد كنظام iOS، ولكن استخدام ملفات متعددة يمكن أن يكون أكثر فاعلية ويتطلب ذاكرة أقل.


سطر 67: سطر 67:
export NODE_BINARY=node
export NODE_BINARY=node
../node_modules/react-native/scripts/react-native-xcode.sh
../node_modules/react-native/scripts/react-native-xcode.sh
</syntaxhighlight>يمكنك تفعيل تنسيق RAM على نظام Android من خلال تعديل الملف <code>android/app/build.gradle</code> خاصتك. أضِف أو عدّل الكتلة <code>project.ext.react</code> قبل السطر
</syntaxhighlight>يمكنك تفعيل تنسيق RAM على نظام Android من خلال تعديل الملف <code>android/app/build.gradle</code> خاصتك. أضِف أو عدّل الكتلة <code>project.ext.react</code> قبل السطر <code>apply from: "../../node_modules/react-native/react.gradle"‎</code>:<syntaxhighlight lang="javascript">
 
<code>apply from: "../../node_modules/react-native/react.gradle"‎</code>:<syntaxhighlight lang="javascript">
project.ext.react = [
project.ext.react = [
   bundleCommand: "ram-bundle",
   bundleCommand: "ram-bundle",
سطر 78: سطر 76:
   extraPackagerArgs: ["--indexed-ram-bundle"]
   extraPackagerArgs: ["--indexed-ram-bundle"]
]
]
</syntaxhighlight><blockquote>'''ملاحظة''': إن استخدمت [https://github.com/facebook/hermes محرّك Hermes JS]، فليس هناك داع أن يكون لديك ميزة RAM مفعَّلة. يضمن الاستدعاء <code>mmap</code> عدم تحميل الملف بأكمله عند تحميل الشيفرة الثنائية في Hermes . قد يؤدي استخدام Hermes مع حزم RAM إلى حدوث مشاكل، لأن هاتين الآليتين غير متوافقتين مع بعضهما البعض.</blockquote>
</syntaxhighlight><blockquote>'''ملاحظة''': إن استخدمت [https://github.com/facebook/hermes محرّك Hermes JS]، فليس هناك داع أن يكون لديك ميزة RAM مفعَّلة. يضمن الاستدعاء <code>mmap</code> عدم تحميل الملف بأكمله عند تحميل الشيفرة الثنائية في Hermes. قد يؤدي استخدام Hermes مع حزم RAM إلى حدوث مشاكل، لأن هاتين الآليتين غير متوافقتين مع بعضهما البعض.</blockquote>


=== إعداد التحميل المسبق والمتطلبات المضمَّنة ===
== إعداد التحميل المسبق والطلبيات المضمَّنة ==
هناك عبء الآن لاستدعاء المتطلب <code>require</code> بعد أن أصبح لدينا حزمة RAM، إذ يحتاج <code>require</code> الآن إرسال رسالة عبر الجسر عندما يواجه وحدةً غير محمَّلة بعد. سيؤثر ذلك على بدء التشغيل التأثير الأكبر، لأنه المكان الذي يُجرَى به أكبر عدد من استدعاءات المتطلبات أثناء تحميل التطبيق للوحدة الأولية.  يمكننا لحسن الحظ إعداد جزء من الوحدات بحيث تُحمَّل مسبقًا، ولكنك ستحتاج إلى تنفيذ بعض أشكال المتطلبات المضمَّنة.
هناك عبء الآن لاستدعاء المتطلب <code>require</code> بعد أن أصبح لدينا حزمة RAM، إذ يحتاج <code>require</code> الآن إرسال رسالة عبر الجسر عندما يواجه وحدةً غير محمَّلة بعد. سيؤثر ذلك على بدء التشغيل التأثير الأكبر، لأنه المكان الذي يُجرَى به أكبر عدد من استدعاءات الطلبيات أثناء تحميل التطبيق للوحدة الأولية.  يمكننا لحسن الحظ إعداد جزء من الوحدات بحيث تُحمَّل مسبقًا، ولكنك ستحتاج إلى تنفيذ بعض أشكال الطلبيات المضمَّنة.


=== التحقيق Investigating في الوحدات المُحمَّلة ===
== التحقيق Investigating في الوحدات المُحمَّلة ==
يمكنك إضافة ما يلي بعد عمليات الاستيراد الأولية في ملف الجذر (index.(ios|android).js) الخاص بك:<syntaxhighlight lang="javascript">
يمكنك إضافة ما يلي بعد عمليات الاستيراد الأولية في ملف الجذر (index.(ios|android).js) الخاص بك:<syntaxhighlight lang="javascript">
const modules = require.getModules();
const modules = require.getModules();
سطر 110: سطر 108:
   )};`
   )};`
);
);
</syntaxhighlight>يمكنك عند تشغيل تطبيقك البحث في وحدة التحكم ومعرفة عدد الوحدات المحمَّلة وعدد الوحدات المنتظرة، وقد ترغب في قراءة أسماء الوحدات. لاحظ استدعاء المتطلبات المضمَّنة في المرة الأولى التي يُشار فيها إلى عمليات الاستيراد. قد تحتاج إلى التحقيق وإعادة البناء للتأكد من تحميل الوحدات التي تريدها فقط عند بدء التشغيل. لاحظ أنه يمكنك تغيير كائن Systrace لمتطلب للمساعدة في تصحيح أخطاء المتطلبات التي قد تسبب مشاكلًا.<syntaxhighlight lang="javascript">
</syntaxhighlight>يمكنك عند تشغيل تطبيقك البحث في وحدة التحكم ومعرفة عدد الوحدات المحمَّلة وعدد الوحدات المنتظرة، وقد ترغب في قراءة أسماء الوحدات. لاحظ استدعاء الطلبيات المضمَّنة في المرة الأولى التي يُشار فيها إلى عمليات الاستيراد. قد تحتاج إلى التحقيق وإعادة البناء للتأكد من تحميل الوحدات التي تريدها فقط عند بدء التشغيل. لاحظ أنه يمكنك تغيير كائن Systrace لمتطلب للمساعدة في تصحيح أخطاء الطلبيات التي قد تسبب مشاكلًا.<syntaxhighlight lang="javascript">
require.Systrace.beginEvent = (message) => {
require.Systrace.beginEvent = (message) => {
   if (message.includes(problematicModule)) {
   if (message.includes(problematicModule)) {
سطر 118: سطر 116:
</syntaxhighlight>كل تطبيق مختلفٌ عن الآخر، ولكن قد يكون تحميل الوحدات التي تحتاجها للشاشة الأولى فقط أمرًا منطقيًا. ضع ناتج اسم الوحدة المحمَّلة في ملف اسمه <code>packager/modulePaths.js</code> عندما يكون الوقت مناسبًا لك.
</syntaxhighlight>كل تطبيق مختلفٌ عن الآخر، ولكن قد يكون تحميل الوحدات التي تحتاجها للشاشة الأولى فقط أمرًا منطقيًا. ضع ناتج اسم الوحدة المحمَّلة في ملف اسمه <code>packager/modulePaths.js</code> عندما يكون الوقت مناسبًا لك.


=== تحديث الملف metro.config.js ===
== تحديث الملف metro.config.js ==
 
نحتاج الآن إلى تحديث الملف <code>metro.config.js</code> في جذر المشروع لاستخدام ملف <code>modulePaths.js</code> المُنشَأ حديثًا:<syntaxhighlight lang="javascript">
نحتاج الآن إلى تحديث الملف <code>metro.config.js</code> في جذر المشروع لاستخدام ملف <code>modulePaths.js</code> المُنشَأ حديثًا:<syntaxhighlight lang="javascript">
const modulePaths = require('./packager/modulePaths');
const modulePaths = require('./packager/modulePaths');
سطر 146: سطر 145:


module.exports = config;
module.exports = config;
</syntaxhighlight>تشير المدخلة preloadedModules في config إلى الوحدات التي يجب تمييزها على أنها محمَّلة مسبقًا عند إنشاء حزمة RAM. تُحمَّل هذه الوحدات على الفور  عند تحميل الحزمة، قبل تنفيذ أي متطلب. تشير المدخلة <code>blockList</code> إلى أن هذه الوحدات غير مطلوبة ضمنيًا، ولكن بما أنها محمَّلة مسبقًا، فلا يوجد تحسين في الأداء من استخدام متطلب مضمَّن. تقضي شيفرة JavaScript المنشَأة وقتًا إضافيًا في حل المتطلبات المضمنة في كل مرة يشار فيها إلى عمليات الاستيراد.
</syntaxhighlight>تشير المدخلة preloadedModules في config إلى الوحدات التي يجب تمييزها على أنها محمَّلة مسبقًا عند إنشاء حزمة RAM. تُحمَّل هذه الوحدات على الفور  عند تحميل الحزمة، قبل تنفيذ أي متطلب. تشير المدخلة <code>blockList</code> إلى أن هذه الوحدات غير مطلوبة ضمنيًا، ولكن بما أنها محمَّلة مسبقًا، فلا يوجد تحسين في الأداء من استخدام متطلب مضمَّن. تقضي شيفرة JavaScript المنشَأة وقتًا إضافيًا في حل الطلبيات المضمنة في كل مرة يشار فيها إلى عمليات الاستيراد.


=== اختبار التحسينات وقياسها ===
== اختبار التحسينات وقياسها ==
يجب أن تكون الآن جاهزًا لإنشاء تطبيقك باستخدام تنسيق RAM والمتطلبات المضمنة. تأكّد من قياس أوقات قبل بدء التشغيل وبعده.
يجب أن تكون الآن جاهزًا لإنشاء تطبيقك باستخدام تنسيق RAM والطلبيات المضمنة. تأكّد من قياس أوقات قبل بدء التشغيل وبعده.


== مصادر ==
== مصادر ==


* [https://reactnative.dev/docs/ram-bundles-inline-requires صفحة RAM Bundles and Inline Requires في توثيق React Native الرسمي.]
* [https://reactnative.dev/docs/ram-bundles-inline-requires صفحة RAM Bundles and Inline Requires في توثيق React Native الرسمي.]
[[تصنيف:ReactNative]]
[[تصنيف:React Native Docs]]

المراجعة الحالية بتاريخ 13:44، 9 أكتوبر 2021

إن كان لديك تطبيق كبير، فقد ترغب في التفكير في تنسيق حزمة وحدات الوصول العشوائي RAM Bundle (اختصارًا إلى Random Access Modules)، واستخدام الطلبيات المضمَّنة inline requires. هذا مفيد للتطبيقات التي تحتوي على عدد كبير من الشاشات التي قد لا تُفتَح أبدًا أثناء استخدام التطبيق المعتاد، ويكون ذلك مفيدًا للتطبيقات التي تحتوي على كميات كبيرة من الشيفرة التي لا تحتاج إليها لفترة من الوقت بعد بدء التشغيل. قد يشتمل التطبيق مثلًا على شاشات فحص أداء معقدة أو ميزات أقل استخدامًا، ولكن معظم الجلسات تتضمن فقط زيارة شاشة التطبيق الرئيسية للحصول على التحديثات. يمكننا تحسين تحميل الحزمة باستخدام وحدة RAM وطلب هذه الميزات والشاشات لتكون مضمَّنة مسبقًا (عند استخدامها بالفعل).

تحميل شيفرة JavaScript

يجب تحميل شيفرة JS في الذاكرة وتحليلها، قبل أن يتمكن react-native من تنفيذها. إذا حمَّلت حزمة bundle بحجم 50 ميجابايت مع الحزمة المعيارية، فيجب تحميلها كلها وتحليلها قبل تنفيذ أي منها. يتمثل التحسين الكامن وراء حزم RAM في أنه يمكنك فقط تحميل جزء من الـ 50 ميجابايت الذي تحتاجه بالفعل عند بدء التشغيل، وتحميل المزيد من الحزمة تدريجيًا حسب الحاجة إلى هذه الأجزاء.

الطلبيات المضمنة

تؤخّر الطلبيات المضمَّنة طلب وحدة أو ملف حتى تكون هناك حاجة فعلية لهذا الملف كما في المثال الأساسي التالي:

VeryExpensive.js

import React, { Component } from 'react';
import { Text } from 'react-native';
// ... استيراد بعض الوحدات باهظة الثمن

// قد ترغب في تسجيل الدخول على مستوى الملف للتحقق من وقت حدوث ذلك
console.log('VeryExpensive component loaded');

export default class VeryExpensive extends Component {
  // الكثير والكثير من الشيفرة
  render() {
    return <Text>Very Expensive Component</Text>;
  }
}

Optimized.js

import React, { Component } from 'react';
import { TouchableOpacity, View, Text } from 'react-native';

let VeryExpensive = null;

export default class Optimized extends Component {
  state = { needsExpensive: false };

  didPress = () => {
    if (VeryExpensive == null) {
      VeryExpensive = require('./VeryExpensive').default;
    }

    this.setState(() => ({
      needsExpensive: true
    }));
  };

  render() {
    return (
      <View style={{ marginTop: 20 }}>
        <TouchableOpacity onPress={this.didPress}>
          <Text>Load</Text>
        </TouchableOpacity>
        {this.state.needsExpensive ? <VeryExpensive /> : null}
      </View>
    );
  }
}

يمكن أن تؤدي الطلبيات المضمَّنة إلى تحسينات وقت بدء التشغيل حتى بدون تنسيق RAM، لأن الشيفرة الموجودة في VeryExpensive.js ستُنفَّذ فقط بمجرد أن تكون مطلوبةً لأول مرة.

تفعيل التنسيق RAM

سينشئ تنسيق RAM على نظام iOS ملفًا مفهرسًا واحدًا بحيث يحمّل react native وحدةً منه فقط في كل مرة، بينما سينشئ على نظام Android مجموعة من الملفات لكل وحدة افتراضيًا. يمكنك إجبار نظام Android على إنشاء ملف واحد كنظام iOS، ولكن استخدام ملفات متعددة يمكن أن يكون أكثر فاعلية ويتطلب ذاكرة أقل.

يمكنك تفعيل تنسيق RAM في Xcode عن طريق تعديل مرحلة البناء "Bundle React Native code and images". أضف السطر

export BUNDLE_COMMAND="ram-bundle"‎ قبل ‎../node_modules/react-native/scripts/react-native-xcode.sh:

export BUNDLE_COMMAND="ram-bundle"
export NODE_BINARY=node
../node_modules/react-native/scripts/react-native-xcode.sh

يمكنك تفعيل تنسيق RAM على نظام Android من خلال تعديل الملف android/app/build.gradle خاصتك. أضِف أو عدّل الكتلة project.ext.react قبل السطر apply from: "../../node_modules/react-native/react.gradle"‎:

project.ext.react = [
  bundleCommand: "ram-bundle",
]

استخدم الأسطر التالية على نظام Android إن أردت استخدام ملف مفهرس واحد:

project.ext.react = [
  bundleCommand: "ram-bundle",
  extraPackagerArgs: ["--indexed-ram-bundle"]
]

ملاحظة: إن استخدمت محرّك Hermes JS، فليس هناك داع أن يكون لديك ميزة RAM مفعَّلة. يضمن الاستدعاء mmap عدم تحميل الملف بأكمله عند تحميل الشيفرة الثنائية في Hermes. قد يؤدي استخدام Hermes مع حزم RAM إلى حدوث مشاكل، لأن هاتين الآليتين غير متوافقتين مع بعضهما البعض.

إعداد التحميل المسبق والطلبيات المضمَّنة

هناك عبء الآن لاستدعاء المتطلب require بعد أن أصبح لدينا حزمة RAM، إذ يحتاج require الآن إرسال رسالة عبر الجسر عندما يواجه وحدةً غير محمَّلة بعد. سيؤثر ذلك على بدء التشغيل التأثير الأكبر، لأنه المكان الذي يُجرَى به أكبر عدد من استدعاءات الطلبيات أثناء تحميل التطبيق للوحدة الأولية. يمكننا لحسن الحظ إعداد جزء من الوحدات بحيث تُحمَّل مسبقًا، ولكنك ستحتاج إلى تنفيذ بعض أشكال الطلبيات المضمَّنة.

التحقيق Investigating في الوحدات المُحمَّلة

يمكنك إضافة ما يلي بعد عمليات الاستيراد الأولية في ملف الجذر (index.(ios|android).js) الخاص بك:

const modules = require.getModules();
const moduleIds = Object.keys(modules);
const loadedModuleNames = moduleIds
  .filter((moduleId) => modules[moduleId].isInitialized)
  .map((moduleId) => modules[moduleId].verboseName);
const waitingModuleNames = moduleIds
  .filter((moduleId) => !modules[moduleId].isInitialized)
  .map((moduleId) => modules[moduleId].verboseName);

// تأكّد من أن الوحدات التي تتوقع انتظارها أنها تنتظر بالفعل
console.log(
  'loaded:',
  loadedModuleNames.length,
  'waiting:',
  waitingModuleNames.length
);

// ‫احصل على هذا النص وضعه في ملف اسمه packager/modulePaths.js‫
console.log(
  `module.exports = ${JSON.stringify(
    loadedModuleNames.sort(),
    null,
    2
  )};`
);

يمكنك عند تشغيل تطبيقك البحث في وحدة التحكم ومعرفة عدد الوحدات المحمَّلة وعدد الوحدات المنتظرة، وقد ترغب في قراءة أسماء الوحدات. لاحظ استدعاء الطلبيات المضمَّنة في المرة الأولى التي يُشار فيها إلى عمليات الاستيراد. قد تحتاج إلى التحقيق وإعادة البناء للتأكد من تحميل الوحدات التي تريدها فقط عند بدء التشغيل. لاحظ أنه يمكنك تغيير كائن Systrace لمتطلب للمساعدة في تصحيح أخطاء الطلبيات التي قد تسبب مشاكلًا.

require.Systrace.beginEvent = (message) => {
  if (message.includes(problematicModule)) {
    throw new Error();
  }
};

كل تطبيق مختلفٌ عن الآخر، ولكن قد يكون تحميل الوحدات التي تحتاجها للشاشة الأولى فقط أمرًا منطقيًا. ضع ناتج اسم الوحدة المحمَّلة في ملف اسمه packager/modulePaths.js عندما يكون الوقت مناسبًا لك.

تحديث الملف metro.config.js

نحتاج الآن إلى تحديث الملف metro.config.js في جذر المشروع لاستخدام ملف modulePaths.js المُنشَأ حديثًا:

const modulePaths = require('./packager/modulePaths');
const resolve = require('path').resolve;
const fs = require('fs');

// حدّث السطر التالي إذا كان المجلد الجذر لتطبيقك في مكان آخر
const ROOT_FOLDER = resolve(__dirname, '..');

const config = {
  transformer: {
    getTransformOptions: () => {
      const moduleMap = {};
      modulePaths.forEach((path) => {
        if (fs.existsSync(path)) {
          moduleMap[resolve(path)] = true;
        }
      });
      return {
        preloadedModules: moduleMap,
        transform: { inlineRequires: { blockList: moduleMap } }
      };
    }
  },
  projectRoot: ROOT_FOLDER
};

module.exports = config;

تشير المدخلة preloadedModules في config إلى الوحدات التي يجب تمييزها على أنها محمَّلة مسبقًا عند إنشاء حزمة RAM. تُحمَّل هذه الوحدات على الفور عند تحميل الحزمة، قبل تنفيذ أي متطلب. تشير المدخلة blockList إلى أن هذه الوحدات غير مطلوبة ضمنيًا، ولكن بما أنها محمَّلة مسبقًا، فلا يوجد تحسين في الأداء من استخدام متطلب مضمَّن. تقضي شيفرة JavaScript المنشَأة وقتًا إضافيًا في حل الطلبيات المضمنة في كل مرة يشار فيها إلى عمليات الاستيراد.

اختبار التحسينات وقياسها

يجب أن تكون الآن جاهزًا لإنشاء تطبيقك باستخدام تنسيق RAM والطلبيات المضمنة. تأكّد من قياس أوقات قبل بدء التشغيل وبعده.

مصادر