الفرق بين المراجعتين لصفحة: «React/code splitting»
Kinan-mawed (نقاش | مساهمات) لا ملخص تعديل |
Kinan-mawed (نقاش | مساهمات) لا ملخص تعديل |
||
سطر 2: | سطر 2: | ||
== التحزيم (Bundling) == | == التحزيم (Bundling) == | ||
تكون معظم الملفّات في تطبيقات React مُحزَّمة باستخدام أدوات مثل Webpack أو Browserify. التحزيم هو عملية تتبّع الملفّات المستوردة ودمجها في ملف واحد وهو الحزمة (Bundle). يُمكِن بعدها تضمين هذه الحزمة في صفحة ويب لتحميل كامل التطبيق دفعة واحدة. | تكون معظم الملفّات في تطبيقات React مُحزَّمة باستخدام أدوات مثل [https://webpack.js.org/ Webpack] أو [http://browserify.org/ Browserify]. التحزيم هو عملية تتبّع الملفّات المستوردة ودمجها في ملف واحد وهو الحزمة (Bundle). يُمكِن بعدها تضمين هذه الحزمة في صفحة ويب لتحميل كامل التطبيق دفعة واحدة. | ||
=== مثال === | === مثال === | ||
سطر 20: | سطر 20: | ||
</syntaxhighlight>'''ملاحظة:''' سينتهي مظهر الحزم لديك إلى شكلٍ مختلف عن هذا. | </syntaxhighlight>'''ملاحظة:''' سينتهي مظهر الحزم لديك إلى شكلٍ مختلف عن هذا. | ||
إن كنت تستخدم <code>create-react-app</code>، أو Next. | إن كنت تستخدم <code>[https://github.com/facebookincubator/create-react-app create-react-app]</code>، أو [https://github.com/zeit/next.js/ Next.js]، أو [https://www.gatsbyjs.org/ Gatsby]، أو أي أداة مشابهة، فسيكون لديك إعداد Webpack جاهز لتحزيم تطبيقك. | ||
أمّا إن لم تكن تستخدم أي من هذه الأدوات فستحتاج إلى إعداد التحزيم بنفسك. انظر إلى دليل التثبيت ودليل البدء في توثيق Webpack. | أمّا إن لم تكن تستخدم أي من هذه الأدوات فستحتاج إلى إعداد التحزيم بنفسك. انظر إلى دليل [https://webpack.js.org/guides/installation/ التثبيت] [https://webpack.js.org/guides/getting-started/ ودليل البدء] في توثيق Webpack. | ||
== تقسيم الشيفرة == | == تقسيم الشيفرة == | ||
يكون التحزيم رائعًا، ولكن عندما يكبر تطبيقك ستكبر الحزمة لديك أيضًا، خاصّة إن كنت تُضمِّن مكتبات طرف ثالث كبيرة الحجم. يجب الانتباه إلى الشيفرة التي تُضمِّنها في حزمتك لكي لا تجعلها كبيرة من غير قصد لدرجة أن يستغرق تطبيقك زمنًا طويلًا للتحميل. | يكون التحزيم رائعًا، ولكن عندما يكبر تطبيقك ستكبر الحزمة لديك أيضًا، خاصّة إن كنت تُضمِّن مكتبات طرف ثالث كبيرة الحجم. يجب الانتباه إلى الشيفرة التي تُضمِّنها في حزمتك لكي لا تجعلها كبيرة من غير قصد لدرجة أن يستغرق تطبيقك زمنًا طويلًا للتحميل. | ||
لتجنّب الحصول على حزمة كبيرة من الأفضل استباق حصول المشكلة والبدء في تقسيم حزمتك. تقسيم الشيفرة (Code-Splitting) هو ميّزة مدعومة من قبل المُحزِّمات مثل Webpack و Browserify (عبر <code>factor-bundle</code>) والتي تستطيع إنشاء حزم متعددة يُمكِن تحميلها بشكل ديناميكي في زمن التنفيذ. | لتجنّب الحصول على حزمة كبيرة من الأفضل استباق حصول المشكلة والبدء في تقسيم حزمتك. [https://webpack.js.org/guides/code-splitting/ تقسيم الشيفرة (Code-Splitting)] هو ميّزة مدعومة من قبل المُحزِّمات مثل Webpack و Browserify (عبر <code>[https://github.com/browserify/factor-bundle factor-bundle]</code>) والتي تستطيع إنشاء حزم متعددة يُمكِن تحميلها بشكل ديناميكي في زمن التنفيذ. | ||
يُساعدك تقسيم شيفرة تطبيقك على إجراء تحميل مُتأخّر (Lazy Load) للأشياء التي يحتاجها المستخدم حاليًّا فقط، ممّا يُحسِّن بشكل كبير أداء تطبيقك. وفي حين أنّك لم تُقلِّل الحجم الكلي لشيفرة تطبيقك، فقد تجنّبت تحميل شيفرة قد لا يحتاجها المستخدم أبدًا وقلّلتَ حجم الشيفرة التي تحتاج إلى تحميلها في البداية. | يُساعدك تقسيم شيفرة تطبيقك على إجراء تحميل مُتأخّر (Lazy Load) للأشياء التي يحتاجها المستخدم حاليًّا فقط، ممّا يُحسِّن بشكل كبير أداء تطبيقك. وفي حين أنّك لم تُقلِّل الحجم الكلي لشيفرة تطبيقك، فقد تجنّبت تحميل شيفرة قد لا يحتاجها المستخدم أبدًا وقلّلتَ حجم الشيفرة التي تحتاج إلى تحميلها في البداية. | ||
سطر 44: | سطر 44: | ||
}); | }); | ||
</syntaxhighlight>'''ملاحظة:''' صياغة <code>import()</code> الديناميكية هي عبارة عن اقتراح في ECMAScript (أي JavaScript) وليست جزءًا من اللغة المعيارية، ومن المتوقع قبولها في المستقبل القريب. | </syntaxhighlight>'''ملاحظة:''' صياغة <code>import()</code> الديناميكية هي عبارة عن [https://github.com/tc39/proposal-dynamic-import اقتراح] في ECMAScript (أي JavaScript) وليست جزءًا من اللغة المعيارية، ومن المتوقع قبولها في المستقبل القريب. | ||
عندما يأتي Webpack على هذه الصياغة سيبدأ بتقسيم شيفرة تطبيقك تلقائيًّا. إن كنت تستخدم <code>create-react-app</code> فهذا الإعداد موجود لديك مُسبقًا | عندما يأتي Webpack على هذه الصياغة سيبدأ بتقسيم شيفرة تطبيقك تلقائيًّا. إن كنت تستخدم <code>create-react-app</code> فهذا الإعداد موجود لديك مُسبقًا و[https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#code-splitting تستطيع استخدامه مباشرةً]. وهو أيضًا موجود بشكل جاهز عندما تستخدم [https://github.com/zeit/next.js/#dynamic-import Next.js]. | ||
إن كنت تُعِد Webpack بنفسك فستحتاج لقراءة دليل Webpack | إن كنت تُعِد Webpack بنفسك فستحتاج لقراءة [https://webpack.js.org/guides/code-splitting/ دليل Webpack حول تقسيم الشيفرة]. يجب أن تبدو إعدادات Webpack لديك مثل [https://gist.github.com/gaearon/ca6e803f5c604d37468b0091d9959269 هذا]. | ||
عند استخدامك Babel يجب أن تتأكد من قدرته على تصريف صياغة الاستيراد (<code>import()</code>) الديناميكية بدون تحويلها. ستحتاج من أجل ذلك إلى هذه الإضافة <code>babel-plugin-syntax-dynamic-import</code>. | عند استخدامك Babel يجب أن تتأكد من قدرته على تصريف صياغة الاستيراد (<code>import()</code>) الديناميكية بدون تحويلها. ستحتاج من أجل ذلك إلى هذه الإضافة <code>[https://yarnpkg.com/en/package/babel-plugin-syntax-dynamic-import babel-plugin-syntax-dynamic-import]</code>. | ||
== المكتبات == | == المكتبات == | ||
=== React Loadable === | === React Loadable === | ||
تُغلِّف مكتبة React Loadable الاستيراد الديناميكي ضمن واجهة برمجة تطبيقات (API) قريبة من React لتقديم تقسيم الشيفرة إلى تطبيقك ضمن مكوّن مُعطى. | تُغلِّف مكتبة [https://github.com/thejameskyle/react-loadable React Loadable] الاستيراد الديناميكي ضمن واجهة برمجة تطبيقات (API) قريبة من React لتقديم تقسيم الشيفرة إلى تطبيقك ضمن مكوّن مُعطى. | ||
قبل استخدام المكتبة:<syntaxhighlight lang="javascript"> | قبل استخدام المكتبة:<syntaxhighlight lang="javascript"> | ||
سطر 76: | سطر 76: | ||
); | ); | ||
</syntaxhighlight>تُساعِدك React Loadable على إنشاء حالات | </syntaxhighlight>تُساعِدك React Loadable على إنشاء [https://github.com/thejameskyle/react-loadable#creating-a-great-loading-component حالات للتحميل]، و[https://github.com/thejameskyle/react-loadable#loading-error-states حالات للأخطاء]، والتحميل المُسبَق، والمزيد من ذلك. تستطيع أيضًا مساعدتك على تصيير تطبيق من جانب الخادم (server-side) مع الكثير من تقسيم الشيفرة. | ||
== تقسيم الشيفرة المعتمد على الطريق (Route) == | == تقسيم الشيفرة المعتمد على الطريق (Route) == |
مراجعة 08:46، 30 أغسطس 2018
التحزيم (Bundling)
تكون معظم الملفّات في تطبيقات React مُحزَّمة باستخدام أدوات مثل Webpack أو Browserify. التحزيم هو عملية تتبّع الملفّات المستوردة ودمجها في ملف واحد وهو الحزمة (Bundle). يُمكِن بعدها تضمين هذه الحزمة في صفحة ويب لتحميل كامل التطبيق دفعة واحدة.
مثال
شيفرة التطبيق هي:
// app.js
import { add } from './math.js';
console.log(add(16, 26)); // 42
شيفرة الحزمة هي:
function add(a, b) {
return a + b;
}
console.log(add(16, 26)); // 42
ملاحظة: سينتهي مظهر الحزم لديك إلى شكلٍ مختلف عن هذا.
إن كنت تستخدم create-react-app
، أو Next.js، أو Gatsby، أو أي أداة مشابهة، فسيكون لديك إعداد Webpack جاهز لتحزيم تطبيقك.
أمّا إن لم تكن تستخدم أي من هذه الأدوات فستحتاج إلى إعداد التحزيم بنفسك. انظر إلى دليل التثبيت ودليل البدء في توثيق Webpack.
تقسيم الشيفرة
يكون التحزيم رائعًا، ولكن عندما يكبر تطبيقك ستكبر الحزمة لديك أيضًا، خاصّة إن كنت تُضمِّن مكتبات طرف ثالث كبيرة الحجم. يجب الانتباه إلى الشيفرة التي تُضمِّنها في حزمتك لكي لا تجعلها كبيرة من غير قصد لدرجة أن يستغرق تطبيقك زمنًا طويلًا للتحميل.
لتجنّب الحصول على حزمة كبيرة من الأفضل استباق حصول المشكلة والبدء في تقسيم حزمتك. تقسيم الشيفرة (Code-Splitting) هو ميّزة مدعومة من قبل المُحزِّمات مثل Webpack و Browserify (عبر factor-bundle
) والتي تستطيع إنشاء حزم متعددة يُمكِن تحميلها بشكل ديناميكي في زمن التنفيذ.
يُساعدك تقسيم شيفرة تطبيقك على إجراء تحميل مُتأخّر (Lazy Load) للأشياء التي يحتاجها المستخدم حاليًّا فقط، ممّا يُحسِّن بشكل كبير أداء تطبيقك. وفي حين أنّك لم تُقلِّل الحجم الكلي لشيفرة تطبيقك، فقد تجنّبت تحميل شيفرة قد لا يحتاجها المستخدم أبدًا وقلّلتَ حجم الشيفرة التي تحتاج إلى تحميلها في البداية.
import()
أفضل طريقة لتقديم تقسيم الشيفرة إلى تطبيقك هي عبر استخدام صياغة import()
الديناميكية.
الشيفرة قبل الاستخدام:
import { add } from './math';
console.log(add(16, 26));
الشيفرة بعد الاستخدام:
import("./math").then(math => {
console.log(math.add(16, 26));
});
ملاحظة: صياغة import()
الديناميكية هي عبارة عن اقتراح في ECMAScript (أي JavaScript) وليست جزءًا من اللغة المعيارية، ومن المتوقع قبولها في المستقبل القريب.
عندما يأتي Webpack على هذه الصياغة سيبدأ بتقسيم شيفرة تطبيقك تلقائيًّا. إن كنت تستخدم create-react-app
فهذا الإعداد موجود لديك مُسبقًا وتستطيع استخدامه مباشرةً. وهو أيضًا موجود بشكل جاهز عندما تستخدم Next.js.
إن كنت تُعِد Webpack بنفسك فستحتاج لقراءة دليل Webpack حول تقسيم الشيفرة. يجب أن تبدو إعدادات Webpack لديك مثل هذا.
عند استخدامك Babel يجب أن تتأكد من قدرته على تصريف صياغة الاستيراد (import()
) الديناميكية بدون تحويلها. ستحتاج من أجل ذلك إلى هذه الإضافة babel-plugin-syntax-dynamic-import
.
المكتبات
React Loadable
تُغلِّف مكتبة React Loadable الاستيراد الديناميكي ضمن واجهة برمجة تطبيقات (API) قريبة من React لتقديم تقسيم الشيفرة إلى تطبيقك ضمن مكوّن مُعطى.
قبل استخدام المكتبة:
import OtherComponent from './OtherComponent';
const MyComponent = () => (
<OtherComponent/>
);
بعد استخدام المكتبة:
import Loadable from 'react-loadable';
const LoadableOtherComponent = Loadable({
loader: () => import('./OtherComponent'),
loading: () => <div>Loading...</div>,
});
const MyComponent = () => (
<LoadableOtherComponent/>
);
تُساعِدك React Loadable على إنشاء حالات للتحميل، وحالات للأخطاء، والتحميل المُسبَق، والمزيد من ذلك. تستطيع أيضًا مساعدتك على تصيير تطبيق من جانب الخادم (server-side) مع الكثير من تقسيم الشيفرة.
تقسيم الشيفرة المعتمد على الطريق (Route)
قد يكون من الصعب تحديد موضع تقسيم الشيفرة في تطبيقك. يجب عليك أن تتأكد من اختيار أماكن تُقسِّم الشيفرة بشكلٍ متساوٍ ولكن من دون الضرر بتجربة المستخدم.
المكان الجيد للبدء بذلك هو الطرق (routes). اعتاد معظم مستخدمي الويب على أنّ أزرار التقليب بين الصفحات تستغرق وقتًا لتحميلها. تميل حينها أيضًا إلى إعادة تصيير كامل الصفحة مرة واحدة لذا من غير المحتمل أن يكون المستخدم يحاول التفاعل مع الصفحة في نفس الوقت.
هذا مثال حول إعداد تقسيم الشيفرة اعتمادًا على الطريق في تطبيقك باستخدام مكتبات مثل React Router و React Loadable:
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Loadable from 'react-loadable';
const Loading = () => <div>Loading...</div>;
const Home = Loadable({
loader: () => import('./routes/Home'),
loading: Loading,
});
const About = Loadable({
loader: () => import('./routes/About'),
loading: Loading,
});
const App = () => (
<Router>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
</Switch>
</Router>
);