سلام به همه دوستان اين مقاله يا بهتر بگم اين نوشته درباره حفظ تعادل در React Native هست و اينكه چرا اين قضيه مهم هست و ميتونه تاثير بزاره در نحوه كار كردن كاربر با اپليكيشن شما. اول از همه بگم وقتي من شروع به نوشتن اپ با اين فريم ورك كرده بودم من يك بكند دولوپر بودم و برام جالب بود كه ميشه با جاوااسكريپت كدي نوشت كه توسط كد هاي Java يا Objective-C رندر بشن. پس شروع كردم به مطالعه درباره اين فريم ورك و بعد از مدتي كلا تغيير فيلد دادم و مشغول توسعه موبايل اپ و بعد از مدتی توسعه اپ های Cross Platform و حل كردن چلنج هاي جذاب و به قول معروف سخت شدم.
اول از همه بهتره يكم راجب خود React Native بنويسم كه دقيقا چي هست، ريكت نيتيو يك فريم ورك و يك واسط اصطلاحا يك پل بين كدهاي جاواسكريپت و كد هاي نيتيو مثل Java يا Objective-c هست، كه وقتي شما در JS نياز به اپديت UI و يا دريافت اطلاعات مربوط به دستگاه را ميخواين به Bridge اعلام ميكنين و اون به نيتيو اعلام ميكنه و بعد نيتيو درخواست شما رو پردازش ميكنه و به Bridge اعلام ميكنه و اون هم نتيجه جواب رو به JS اعلام ميكنه.
در نگاه اول تصور كنين كه اپديت هاي ما و درخواست هاي ما در JS سنگين باشه يا زياد باشه و Bridge مجبور باشه هر لحظه درخواست هاي شما رو منتقل كنه و منتظر جواب بمونه و همين رفت و امد ها باعث ميشه كه اپليكيشن شما منابع بسياري رو از CPU ، Ram و بقيه سخت افزار هاي دستگاه رو مصرف كنه و همينطور باعث كندي اپ شما بشه و در نهایت باتری بیشتری مصرف کنه. ساده ترين مثالي كه ميشه گفت براي اين نمونه استفاده از كامپوننت TextInput هست.
وقتي كاربر شروع به تايپ كردن در يك TextInput ميكنه اتفاقي مثل شكل زير رخ ميده و ميبينين كه در قدم اول از سمت نيتيو اعلام ميشه كه كاربر يك حرف رو وارد كرده و نيتيو فانكشن Text رو صدا ميزنه و بعد از اون در Js فانكشن SetValue صدا زده ميشه تا React تغييرات رو بفهمه و پردازش كنه و به Native هم تغييرات اعلام بشه و كامپوننت رندر بشه مجدد و همين عمل ساده براي هر كاراكتري كه كاربر وارد ميكنه اتفاق ميفته و براي همين عمل ساده براي تايپ كلمه Test حدود ٨ بار ارتباط بين Native و JS برقرار شده
تا اينجاي كار همه چي خيلي خوب كار ميكنه مشكل وقتي شروع ميشه كه ديوايس كاربر ضعيف باشه يا كاربر خيلي سريع تايپ ميكنه و وقتي كاربر تايپ ميكنه برنامه شروع ميكنه به اهسته كار كردن و اصطلاحا اتفاق UI block رخ ميده و اگر به ازای هر مقدار از این تغییرات بخواهیم فانکشن های دیگری رو صدا بزنیم مانند جستجو سربار بسیار بیشتری رو ایجاد کرده ایم و كاربر ما شروع ميكنه به عصباني شدن و ميگه چقدر گيره اين اپ. يكي از راه حل هاي ساده براي حل اين مشكل اين هست كه به جاي اينكه از پراپ Value استفاده كنيم از defaultValue استفاده كنيم و اينبار نيتيو وضعيت رو اعلام ميكنه و ريكت setValue رو كه انجام ميده و چون Native نيازي به اپديت نداره به نيتيو چيزي اعلام نميشه چون مقدار جديدي رو دريافت نميكنه و كامپوننت شما نيازي به رندر تكراري و يكسان نخواهد داشت.
مسئله ديگري كه با اين اتفاق رخ ميده نوع چينش و نوع قرار گيري كامپوننت ها كنار هم هستن و اگر در كد بالا نگاه كنين هربار useState صدا زده ميشه براي اپديت TextInput بقيه كامپوننت ها درون كامپوننت PizzaTranslator هم رندر ميشوند و در طراحي ها و چينش ها بايد به اين مسئله دقت شود و هرچه به اتميك ديزاين نزديكتر بشيم اين مسئله كمتر اتفاق مي افتد.
شبكه:
يكي از بزرگترين چالش هاي كه در توسعه اپ با React Native شبكه هست . همه ما ميدونيم كه يك سري ديتا بايد از Api بخونيم و به كاربر به صورت مرتب شده نشون بديم تا اينجاي كار هم باز همه چيز خوبه ولي اينجا مشكل ميخوريم كه ديتايي كه ميخوايم از Api بخونيم با استفاده از JS بگيريم و هرچه قدر اين ديتا سنگين تر باشه و بيشتر طول بكشه اتفاق UI Block ميفته چرا ؟ افرين چون Javascript Single thread هست و هر در يك زمان مشخص يك كار بيشتر انجام نميده و كارها در Event loop منتظر ميمونن تا تسك قبلي انجام بشه و به همين خاطر هست كه كاربر كه ديتا داره براش لود ميشه و اگه بخواد يك كار ديگه تو اپ انجام بده با كندي و يا قفل شدن اپ اتفاق ميفته و هر چقدر رم كاربر محدود باشه اين اتفاق بيشتر رخ ميده.
راه حل رفع مشكل تقسيم درست وظايف هست يعني به جايي اينكه JS رو خودش بفرستيم بگيم برامون اطلاعات از سرور بگيره به نيتيو كد ها ميگيم شما ديتا رو بگير و هر موقع اومد به JS اعلام كن و اين باعث ميشه كه JS سبك بال به بقيه درخواست هاي كاربر جواب بده.
اگر در شكل بالا يك سمت JavaScript و در سمت ديگه كد هاي Native باشن هر كدوم از سمت ها سنگين تر شون يك سري معايب و يك سري مزايا اتفاق ميفته و براي مثال اگه تمامي كد ها JS بشن كاربر اون نرمي و روون و بودن اپ رو حس نميكنه و اگه كد ها هر چه بيشتر سمت نيتيو بره ايجاد يك كدبيس سختتر ميشه و توسعه اپ براي پلتفرم هاي مختلف با يك كدبيس سختتر ميشه .
در نهایت توسعه اپ های کراس پلتفرم و بقیه اپ ها در وهله اول نیازمند به کشیدن دیاگرام های مختلف و وقت گذاشتن برای تحلیل درست و تقسیم درست وظایف هستن. و هرچقدر این قدم اول کامل تر باشد جلوگیری میکنه از سرو کله زدن با باگ های بیشمار و همچنین کانفلیکت های مختلف.
ممنون که تا اینجا من رو همراهی کردین و امیدوارم که این نوشته به کمکتون بیاد و بتونیم محصول بهتری رو برای کاربرامون توسعه بدهیم و خوشحال میشم که نظر ها و انتقاداتون رو راجب این مقاله بگین بهم .
منابع:
React Native Website
Design Pattern With React Native
The Ultimate Guide To react native Optimization