پیاده سازی بارگذاری تنبل یا Lazy Loading در ری اکت

با سلام و عرض ادب خدمت کاربران گرامی و همراهان آکادمی Rahkarino.
در خدمتتون هستیم با یک آموزش دیگه در زمینه کتابخانه React.js در این مقاله قصد داریم نحوه پیاده سازی بارگذاری تنبل (Lazy-Loading) را در ری اکت بررسی کنیم.
در سال های اخیر، تولید اپلیکیشن های تجاری و پیشرفته توسط ری اکت در حال افزایش است و هر اندازه مقیاس پروژه های طراحی شده بزرگ تر باشد کدهای سنگین تری خواهد داشت و در نتیجه بارگذاری (لودینگ) آنها زمان بیشتری صرف می کند. در اینگونه پروژه ها توضیه می شود از قابلیت لود تنبل در ریکت استفاده شود.
در ادامه این پست، نحوه اجرای لیزی لودینگ و همچنین Code Splitting را در ری اکت توسط react.lazy و react.suspense آموزش خواهیم داد. همراه ما باشید…
بارگذاری تنبل یا Lazy Loading چیست؟
لیزی لودینگ یک الگوی طراحی (دیزاین پترن: design pattern) است برای بهینه سازی و افزایش بهره وری اپلیکیشن های موبایل و وب. مفهوم بارگذاری تنبل ساده است: لود کامپوننت های مهم و ضروری برای UI در ابتدا و لود سایر کامپوننت های غیر حیاتی در ادامه.
وقتی یک وب اپلیکیشن پیشرفته و بزرگ را باز می کنید به احتمال زیاد تمام کامپوننت های آن در ابتدا لود نمی شوند و فقط بخش های مهم و کامپوننت هایی که در viewport کاربر قرار دارند لود خواهند شد.
بارگذاری تنبل یا لیزی لودینگ این امکان را به توسعه دهندگان می دهد تا کامپوننت های حیاتی را در ابتدای درخواست کاربر لود کنند و سپس سایر بخش های اپلیکیشن را به کاربر نمایش دهند. اینکار باعث افزایش سرعت اجرای برنامه و نیز بهبود تجربه کاربری آن خواهد شد.
بارگذاری تنبل یا لیزی لودینگ چگونه در ری اکت اجرا می شود؟
در ری اکت توسط دو ویژگی می توان Code Splitting و Lazy Loading را پیاده سازی کرد: ()React.lazy و React.Suspense
React.lazy یک فانکشن است که امکان رندر یک Dynamic Import را بصورت یک کامپوننت عادی را فراهم می کند. درون ریزی پویا یا داینامیک ایمپورت یکی از روش های پیاده سازی Code-Splitting می باشد که هسته اصلی لیزی لودینگ است.
React.Suspense این امکان را فراهم می کند که در کامپوننت هایی که هنوز لود نشده اند یا در حال بارگذاری هستند یک تصویر لودینگ یا پیغام متناسب نمایش دهیم.
قبل از اینکه به سراغ react.lazy و react.suspense برویم، ابتدا می خواهیم نگاهی به مفاهیم Dynamic import و نیز Code Splitting بیاندازیم. ببینیم این دو ویژگی دقیقا به چه معنا هستند و چکاری انجام می دهند.
جداسازی کد یا Code Splitting در ری اکت:
با کمک ES Modules و ترنسپایلرهایی مانند Babel و باندلرهایی مانند webpack و browserify می توان اپلیکیشن های جاوا اسکریپتی تولید کرد که کاملا ماژولار باشد و عملیات توسعه نگهداری آنها ساده تر باشد. معمولا هر ماژول داخل یک فایل بنام bundle ایمپورت و ادغام می شود. سپس فایل باندل در داخل صفحه وب درج می شود تا بتوان اپلیکیشن را لود کرد.
Code Splitting به فرآیند جداسازی یک فایل bundle بزرگ به چندین فایل مجزا گفته می شود تا بتوان هر یک از آنها را بصورت داینامیک لود کرد. اینکار باعث می شود بدلیل وجود فایل های باندل کوچکتر، لود برنامه سریع تر انجام شود.
درون ربزی پویا یا Dynamic Import در ری اکت:
یکی از روش های پیاده سازی code-splitting استفاده از dynamic import می باشد که بوسیله دستور ()import انجام می شود. دستور import یک promise برمی گرداند که اگر موفقیت آمیز باشد ماژول موردنظر را return می کند و اگر نتواند ماژول را لود کند reject می شود.
در تصویر زیر نحوه استفاده از داینامیک ایمپورت را مشاهده می کنید در اپلیکیشنی که از webpack بعنوان ماژول باندلر استفاده می کند.
وقتی وب پک کد فوق را می بیند متوجه می شود که باید بصورت داینامیک برای کتابخانه moment یک فایل bundle مجزا بسازد. اگر اپلیکیشن ری اکت را توسط دستور create-react-app ایجاد کرده باشید یا اپلیکیشن nextjs را توسط create next-app راه اندازی کرده باشید، عملیات code splitting با استفاده از daynamic import بطور پیش فرض انجام می شود.
اما اگر وب پک را بطور دستی تنظیم کرده اید (custom webpack config) باید برای اجرای code-splitting در webpack از این مقاله آموزشی استفاده کنید. برای ترنسپایل Babel باید از پلاگین babel-plugin-syntax-dynamic-import به منظور dynamic import استفاده کنید.
اکنون می خواهیم به سراغ React.lazy برویم.
استفاده از React.lazy در ری اکت:
()React.lazy یک تابع است که این امکان را فراهم می کند تا کامپوننت هایی تعریف کنیم که بصورت داینامیک ایمپورت لود می شوند اما به شکل کامپوننت های عادی رندر می شوند. این قضیه بطور خودکار باعث می شود فایل bundle مربوط به کامپوننتی که در حال رندر است لود شود و سایر فایل های باندل لود نشوند. React.lazy بعنوان آرگومان ورودی که تابع می گیرد که شامل dynamic import است و یک Promise برمی گرداند.
از تابع React.lazy به شکل زیر استفاده کنید:
استفاده از React.Suspense در ری اکت:
کامپوننتی که توسط تابع ()React.lazy ایجاد می شود تنها زمانی لود می شود که نیاز است رندر شود. پس بهتر است در زمانی که منتظر لود این گونه کامپوننت ها هستیم یک پیغام یا تصویر لودینگ به کاربر نمایش دهیم. اینجا جایی است که React.Suspense پا به میدان می گذارد.
در واقع React.Suspense یک کامپوننت است که کامپوننت تنبل یا Lazy را درون خود احاطه (wrap) می کند. البته می توان چندین کامپوننت تنبل را بصورت درختی درون یک Suspense تعریف کرد.
React.Suspense یک props بنام fallback دارد که شامل پیغام یا تصویر لودینگ شما می باشد. یعنی مثلا می توان عبارت “در حال بارگذاری” را در این props تعریف کرد یا یک تصویر متحرک loading در آن درج کرد.
نکته: به منظور بهبود تجربه کاربری (UX) می توان کامپوننت Lazy را درون یک Error Boundary تعریف کرد. تا در صورتی که به هر دلیلی کامپوننت تنبل لود نشد، پیغام خطای متناسب برای کاربر نمایش یابد.
در کد زیر، یک مثال ساده از نحوه استفاده از Suspense و Lazy و Error boundary را مشاهده می کنید:
import React, { Suspense } from "react"; import Loader from "./components/Loader"; import Header from "./components/Header"; import ErrorBoundary from "./components/ErrorBoundary"; const Calendar = React.lazy(() => { return new Promise(resolve => setTimeout(resolve, 5 * 1000)).then( () => Math.floor(Math.random() * 10) >= 4 ? import("./components/Calendar") : Promise.reject(new Error()) ); }); export default function CalendarComponent() { return ( <div> <ErrorBoundary> <Header>Calendar</Header> <Suspense fallback={<Loader />}> <Calendar /> </Suspense> </ErrorBoundary> </div> ); }
در کد بالا، از کامپوننت Loader بعنوان مقدار fallback استفاده شده است. یعنی در زمانی که کامپوننت تنبل در حال لود می باشد کامپوننت Loader به کاربر نمایش داده می شود. همچنین از Error boundary برای زمان لود نشدن کامپوننت Calendar استفاده شده است. در ادامه کد بالا، از یک تابع setTimeOut برای شبیه سازی تاخیر لود کامپوننت Calendar استفاده شده است. در نهایت هم کاری کردیم که Promise بازگشتی، reject شود تا قابلیت Error boundary را چک کنیم.
نتیجه گیری:
توسط React.lazy و React.Suspense براحتی می توان قابلیت های Code-Splitting و Lazy-Loading را در اپلیکیشن های ری اکت پیاده سازی کرد. با اینکار، علاوه بر افزایش سرعت و بهره وری اپلیکیشن های موبایل و وب، تجربه کاربری هم بهبود می یابد.
همراهان عزیز آکادمی راهکارینو، در صورتیکه سوال یا پیشنهادی دارید می توانید از طریق فرم ارسال دیدگاه با ما در تماس باشید. کارشناسان ما در اسرع وقت پاسخگوی شما خواهند بود.
دیدگاهتان را بنویسید