رد فعل تقسيم رمز في 2019

إنه 2019! الجميع يعتقد أنهم يعرفون تقسيم التعليمات البرمجية. لذلك - دعونا تحقق ضعف!



ماذا رمز تقسيم الوقوف ل؟


باختصار ، إن تقسيم الشفرة هو مجرد عدم تحميل كل شيء. ثم تقرأ هذه الصفحة ولا يلزمك تحميل موقع كامل. عندما تختار صفًا واحدًا من قاعدة بيانات - لن تضطر إلى أخذ كل شيء.
واضح؟ تقسيم الشفرة واضح أيضًا تمامًا ، لا يتعلق ببياناتك فحسب ، بل يتعلق بكودك أيضًا.


من (ماذا؟) يصنع تقسيم الشفرة؟


React.lazy ؟ لا - يستخدم فقط. يتم تقسيم الشفرة على مستوى المجمّع - حزمة الويب أو الطرود أو مجرد نظام ملفاتك في حالة استخدام وحدات esm "الأصلية". تقسيم الرمز هو مجرد ملفات ، يمكنك تحميل الملفات في مكان ما "لاحقًا". لذلك - على الأسئلة " ما هو تقسيم رمز التشغيل؟ " - الجواب هو - "المجمّع".


من (ما) يستخدم تقسيم الشفرة؟


React.lazy يستخدم. مجرد استخدام رمز تقسيم المجمع الخاص بك. فقط استدعاء الاستيراد عندما حصلت المقدمة. وهذا كل شيء.


ماذا عن رد الفعل للتحميل؟


React.lazy حل محله. وقدمت المزيد من الميزات ، مثل Suspense للتحكم في حالة التحميل. لذلك - استخدم React.Lazy بدلاً من ذلك.


نعم ، هذا كل شيء. شكرا لك على القراءة وتمتع بيوم جميل.

لماذا لم تنته المقالة؟


حسنا. هناك بعض المناطق الرمادية حول React.lazy وتقسيم الرمز نسيت أن أذكره.


المنطقة الرمادية 1 - الاختبار


ليس من السهل اختبار React.lazy بسبب React.lazy . سيكون "فارغًا" فقط ، طالما لم يتم تحميله بعد (حتى لو كان) - Promises وعوائد import ، والقبول كسول ، الوعود ، والتي يتم تنفيذها دائمًا في العلامة التالية .


الحل المقترح؟ لن تصدق ، ولكن الحل المقترح هو استخدام مواد متزامنة - انظر طلب السحب . لذلك - دعنا نجعل imports متزامنة !!! (لإصلاح مشكلة كسول للاختبارات ، أو أي حالة جانب الخادم الأخرى)


 const LazyText = lazy(() => ({ then(cb) { cb({default: Text}); // this is "sync" thenable }, })); const root = ReactTestRenderer.create( <Suspense fallback={<Text text="Loading..." />}> <LazyText text="Hi" /> // this lazy is not very lazy </Suspense>, ); 

ليس من الصعب تحويل وظيفة الاستيراد إلى ملفوف متزامن قابل للتذكير.


 const syncImport = (importFn) => { let preloaded = undefined; const promise = importFn().then(module => preloaded = module); // ^ "auto" import and "cache" promise return () => preloaded ? { then: () => preloaded } : promise; // ^ return sync thenable then possible } const lazyImport = isNode ? syncImport : a => a; // ^ sync for node, async for browser const LazyComponent = React.lazy(lazyImport(() => import('./file')); 

المنطقة الرمادية 2 - SSR


إذا كنت لا تحتاج إلى SSR - يرجى متابعة قراءة المقال!

React.lazy هو SSR ودية. لكنه يتطلب العمل المعلق ، والتعليق ليس صديق الخادم .


هناك حلان:


  • استبدل التشويق بجزء ، عبر السخرية على سبيل المثال. بعد ذلك ، استخدم الإصدار الذي تم تغييره import مع التزامن then لجعل الكسل يتصرف أيضًا بشكل متزامن.
     import React from 'react'; const realLazy = React.lazy; React.lazy = importer => realLazy(syncImport(importer)); React.Suspense = React.Fragment; // :P // ^ React SSR just got fixed :D 

هذا خيار جيد ، لكنه لن يكون مناسبًا تمامًا للعميل. لماذا؟ دعونا نحدد الحل الثاني الممكن:


  • استخدم مكتبة متخصصة لتتبع البرامج النصية وقطع الغيار والأساليب المستخدمة وتحميلها على جانب العميل (خاصة الأنماط!) قبل رد فعل الماء. أو غير ذلك - يمكنك عرض ثقوب فارغة بدلاً من مكونات التعليمات البرمجية المقسمة. مرة أخرى - لم تقم بتحميل الكود الذي قسمته للتو ، لذلك لا يمكنك تقديم أي شيء تريده.

ها رمز تقسيم المكتبات


  • مكون عالمي - أقدم مكتبة ، ولا تزال قابلة للصيانة. انها "اخترعت" تقسيم التعليمات البرمجية من حيث - Webpack تدرس لتقسيم التعليمات البرمجية.
  • قابل للتحميل - شائع جدًا ، ولكن مكتبة غير معترف بها. جعل رمز البصق شيء شائع. المشكلات مغلقة ، لذلك لا يوجد مجتمع حوله.
  • مكونات قابلة للتحميل - مكتبة ميزات كاملة ، من دواعي سروري أن تستخدم ، مع المجتمع الأكثر نشاطا حولها.
  • مكون مستورد - مكتبة واحدة ، غير مرتبطة بـ Webpack ، أي قادرة على التعامل مع الطرود أو esm.
  • React-async-component - مكتبة ميتة بالفعل (لكنها شائعة) ، والتي أحدثت تأثيرًا كبيرًا على كل شيء حول تقسيم الشفرة وتقاطع شجرة React المخصص و SSR.
  • مكتبة أخرى - كانت هناك العديد من المكتبات ، لم ينج الكثير منها من تطور Webpack أو React 16 - لم أذكرها هنا ، لكن إذا كنت تعرف مرشحًا جيدًا - أنا فقط أختارها.

أي مكتبة لاختيار؟


إنها سهلة - غير قابلة للتحميل - فهي ثقيلة غير معادة ومتقادمة ، حتى لو كانت لا تزال تتمتع بشعبية كبيرة. (وأشكركم على تعميم تقسيم الشفرة ، مرة أخرى)


مكونات قابلة للتحميل - قد تكون اختيارًا جيدًا للغاية. هو مكتوب بشكل جيد للغاية ، وصيانتها بنشاط ودعم كل شيء من خارج منطقة الجزاء. دعم "عمليات الاستيراد الديناميكية الكاملة" ، مما يسمح لك باستيراد الملفات وفقًا للدعائم المقدمة ، ولكن بالتالي لا يمكن كتابتها. يدعم التشويق ، لذلك يمكن أن يحل محل React.lazy.


مكون عالمي - في الواقع "مخترعين" للواردات الديناميكية الكاملة - قاموا بتطبيقه في Webpack. وأشياء أخرى كثيرة في مستوى منخفض - لقد فعلوا ذلك. أود أن أقول - هذه المكتبة هي المتشددين قليلاً ، وأقل سهولة في الاستخدام. وثائق المكونات القابلة للتحميل لا تقبل المنافسة. من المفيد إن لم يكن استخدام هذه المكتبة ، ثم قراءة الوثائق - هناك الكثير من التفاصيل التي يجب أن تعرفها ...


رد فعل المستوردة - عنصر غريب بعض الشيء. إنها حزمة مستقلة ، لذلك لن تنكسر أبدًا (لا يوجد شيء يمكن كسره) ، ستعمل مع Webpack 5 و 55 ، لكن ذلك يأتي بتكلفة. بينما تضيف المكتبات السابقة أثناء SSR جميع النصوص المستخدمة إلى نص الصفحة ، وستكون قادرًا على تحميل جميع النصوص في موازاة ذلك - المستوردة لا تعرف أسماء الملفات ، وستتصل بـ "عمليات الاستيراد" الأصلية (لهذا السبب حزمة مستقل) لتحميل القطع المستخدمة ، ولكن لا يمكن إجراء مكالمة إلا من داخل الحزمة الرئيسية - لذلك سيتم تحميل جميع النصوص الإضافية فقط بعد تنزيل البرنامج الرئيسي وتنفيذه. لا يدعم عمليات الاستيراد الديناميكية الكاملة ، مثل React.lazy ، ونتيجة لذلك - يمكن طباعتها. كما يدعم التشويق. يستخدم ثمانية متزامنة على SSR. كما أن لديها نهجًا مختلفًا تمامًا عن CSS ، وتقديم دعم مثالي لتقديم الدفق.


لا يوجد فرق في الجودة أو الشعبية بين المكتبات المدرجة ، وكلنا أصدقاء حميمون - لذلك اختر من قلبك.


المنطقة الرمادية 3 - تقديم الهجين


SSR شيء جيد ، ولكن ، كما تعلمون ، صعب. قد ترغب المشروعات الصغيرة في الحصول على SSR - هناك الكثير من الأسباب للحصول عليها - ولكنها قد لا ترغب في إعدادها وصيانتها.


SSR يمكن أن يكون حقا ، من الصعب حقا. جرب razzle أو اذهب مع Next.js إذا كنت تريد فوزًا سريعًا.

لذا فإن الحل الأسهل لحلول SSR ، وخاصة بالنسبة لـ SPA البسيط ، سيكون بمثابة عرض مسبق. مثل فتح SPA الخاص بك في متصفح وضرب زر "حفظ". مثل:


  • React-snap - يستخدم دمية ( تُعرف أيضًا باسم Chrome مقطوعة الرأس) لتقديم صفحتك في "مستعرض" وحفظ نتيجة كصفحة HTML ثابتة.
  • Rendertron - الذي يفعل الشيء نفسه ، ولكن بطريقة ( سحابة ) مختلفة.

التقديم هو "SSR" بدون "خادم". انها SSR باستخدام عميل. السحر! والعمل من خارج منطقة الجزاء ... ... ... ولكن ليس للبصق رمز.
لذلك - لقد قمت للتو بتقديم صفحتك في متصفح ، وحفظ HTML ، وطلب تحميل نفس الأشياء. ولكن لم يتم استخدام كود خاص من جانب الخادم (لجمع كل القطع المستخدمة) ، لأنك لا يوجد خادم !



في الجزء السابق ، أشرت إلى المكتبات المرتبطة بحزمة الويب من حيث جمع المعلومات حول القطع المستخدمة - لم يتمكنوا من التعامل مع التجسيد المختلط على الإطلاق.


المكونات القابلة للتحميل ، الإصدار 2 (غير متوافق مع الإصدار الحالي 5) ، تم دعمها جزئيًا عن طريق التفاعل المفاجئ. ذهب الدعم.

يمكن للمكون المستورد التفاعلي التعامل مع هذه الحالة ، طالما أنه غير مرتبط بالتجميع / الجانب ، لذلك لا يوجد فرق بين SSR أو Hybrid ، ولكن فقط للتفاعل المفاجئ ، طالما أنه يدعم "ترطيب الحالة" ، بينما rendertron لا.


تم العثور على هذه القدرة من رد الفعل مكون المستوردة أثناء كتابة هذه المقالة ، لم يكن معروفا من قبل - انظر المثال . انه سهل جدا.

وهنا يجب عليك استخدام حل آخر ، وهو عمودي فقط على جميع المكتبات الأخرى.


الرد-prerendered مكون


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


  • أثناء SSR - جعل المكون ، ملفوفًا بـ <div />
  • على العميل - ابحث عن div ، واستخدم innerHTML حتى يصبح المكون جاهزًا لاستبدال HTML الميت.
  • لست مضطرًا إلى التحميل ، وانتظر جزءًا ذا مكون مقسم قبل hydrate حتى لا تعرض فجوة بيضاء بدلاً من ذلك - استخدم فقط HTML مقدم مسبقًا ، والذي يساوي تمامًا المكون الذي سيعرضه مكون حقيقي وأي موجود بالفعل - لأنه يأتي مع استجابة الخادم (أو hydrid).

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

 import {PrerenderedComponent} from 'react-prerendered-component'; const importer = memoizeOne(() => import('./Component')); // ^ it's very important to keep the "one" promise const Component = React.lazy(importer); // or use any other library with ".prefetch" support // all libraries has it (more or less) const App = () => ( <PrerenderedComponent live={importer()}> {/* ^ shall return the same promise */ } <Component /> {/* ^ would be rendered when a component goes "live" */ } </PrerenderedComponent> ); 

هناك مقال آخر حول هذه التكنولوجيا ، قد تقرأ. لكن رئيسي هنا - أنه يحل "فلاش المحتوى غير المحمّل" بطريقة أخرى ، وليس شائعًا في طريقة تقسيم مكتبة التعليمات البرمجية . كن مفتوحًا لحلول جديدة.


TLDR؟


  • لا تستخدم قابلية التحميل ، فلن تضيف أي قيمة
  • React.lazy جيد ، لكنه بسيط جدًا ، حتى الآن.
  • SSR هو شيء صعب ، ويجب أن تعرف ذلك
  • الهجين يحركها التقديم هو شيء. في بعض الأحيان شيء أصعب.

Source: https://habr.com/ru/post/ar444402/


All Articles