0

پنج روش برای بهبود کارایی و پرفرمنس برنامه های فلاتر flutter

پنج روش برای بهبود کارایی و پرفرمنس اپلیکیشن های فلاتری flutter

 

میخوام باهات پنج موردی که ممکنه پرفرمنس و کارایی برنامه فلاتری که نوشتی و یا میخوای بنویسی رو بالا ببره به اشتراک بزارم.
که وقتی خودم تو یکی از اپ هایی که نوشتم امتحانش کردم و باعث بهبود پرفرمنس برنامه شد صحبت کنم.
من امیدوارم که این موارد و نکات به شما و بقیه توسعه دهندگان flutter کمک کنه که کاراریی وسرعت برنامه خودشون رو بالاتر ببرن.

۱. از stateless widgets استفاده کنید

اولین اشتباه یا چالشی که در بتدا باهاش برخورد کردم این بوده که به شخصه خیلیی خیلی به stateful widgets ها وابسته بودم و دلیلش هم ممکنه که این باشه که دیر با getx یا bloc اشنا شدم.در حالی که stateful widgets ها عالی هستن.اما اگر شما یک تابع سنگین یا بزرگ build داشته باشین با هر بار صدا زدن setstate کل ویجت های شما مجددا رندر میشودو از منابع زیادی برای این کار ممکنه که استفاده بشه. پس کم‌کم سعی کن از stateful widgets کمتر استفاده کنی توسعه دهنده خاص 🙂

توبع سنگین و زیاد در build functions را خرد و کوچک‌تر کنید

یک راه حل برای جلوگیری از توابع build سنگین، تجزیه ویجت های بزرگ به ویجت های متعدد است.دقت کنین که ویجت های فرعی ایجاد شده باید در حد امکان stateless باشن. stateless widget ها نیاز به پیکربندی غیرقابل تغییر دارد، بنابراین باید از آنها برای بخش هایی از رابط کاربری که به صورت پویا تغییر نمی کنند استفاده کنی(منظورم جاهایی از اپ هست که ثابت هست مثل یه متن که تغییری نمیکنه تو و اپ)

از توابع کمکی برای رندر UI استفاده نکنید

اگر از یک زبان برنامه نویسی دیگر تجربه دارید، مراقب توابع کمکی باشید. توابع Helper عالی هستند، اما نه در هنگام رندر کردن UI، درflutter. برای مثال، اگر قسمت‌هایی از صفحه در برنامه خود دارید که تکرار می‌شوند، به جای ایجاد یک تابع خصوصی کمکی برای تولید ویجت، سعی کنید در عوض یک ویجت stateless حالت ایجاد کنید.
بهترین راه برای درک این موضوع، مشاهده یک مثال است. کدی که با مشکلات عملکردی و پرفرمنسی  مواجه می‌شود چگونه به نظر می‌رسد:
import 'package:flutter/material.dart';

class JDHomePage extends StatefulWidget {

  @override

  _JDHomePageState createState() => _JDHomePageState();

}

class _JDHomePageState extends State<JDHomePage> {

  int count = 0;

  @override

  Widget build(BuildContext context) {

    return Scaffold(

      body: Column(

        children: [

          IconButton(

            icon: Icon(Icons.search),

            onPressed: () {

              Navigator.of(context).pushNamed('productSearch');

            }),

          InkWell(

              onTap: () {

                setState(() {

                  count += 1;

                });

              },

              child: Text(

                count.toString(),

              )),

          IconButton(

            icon: Icon(Icons.search),

            onPressed: () {

              Navigator.of(context).pushNamed('productSearch');

            })]));  }}
ما به وضوح می بینیم که کد از خط ۲۵ تا خط ۳۳ مشابه کد خط ۵۳ تا ۶۱ است. این کدی است که برای نمایش ایکون جستجو استفاده می شود که کاربران را در صفحه جستجو قرار می دهد. این کد رندر در یک ویجت statefull است که با ضربه زدن کاربر روی ویجت Text بازسازی می شود.
اولین بهینه‌سازی که بسیاری با دیدن این کد فکر می کنند اضافه کردن کد تکراری در داخل یک تابع کمکی است:
// Build method

@override

Widget build(BuildContext context) {

  return Scaffold(

    body: Column(

      children: [

        _getIcon(),

        InkWell(

            onTap: () {

              setState(() {

                count += 1;

              });

            },

            child: Text(

              count.toString(),

            )),

        _getIcon()

      ], ),);}

Widget _getIcon() {

  return IconButton(

      icon: Icon(Icons.search),

      onPressed: () {

        Navigator.of(context).pushNamed('productSearch');

      });

}

}
این کد در حال حاضر بهتر به نظر می رسد، ما خوانایی و قابلیت استفاده مجدد کد را افزایش دادیم اما هنوز عملکرد روش ساخت خود را بهبود نداده ایم. برای این کار، باید متد _getIcon() خود را به یک ویجت بدون حالت تبدیل کنیم. ویجت های stateless در کش ذخیره می شوند و با فراخوانی setState دوباره ساخته نمی شوند.
// Build method

@override

  Widget build(BuildContext context) {

    return Scaffold(

      body: Column(

        children: [

          JDSearchIcon(),

          InkWell(

              onTap: () {

                setState(() {

                  count += 1;

                });

              },

              child: Text(

                count.toString(),

              )),

          JDSearchIcon(),

        ],),);}}

class JDSearchIcon extends StatelessWidget {

  const JDSearchIcon({Key? key}) : super(key: key);

  @override

  Widget build(BuildContext context) {

    return IconButton(

      icon: Icon(Icons.search),

      onPressed: () {

        Navigator.of(context).pushNamed('productSearch');

      },

    );

  }

}

می‌توانید ویجت جدید JDSearchIcon را در یک تابع جدید قرار دهید و سپس می‌توانید از آن در سراسر برنامه به عنوان یک جزء stateless استفاده مجدد کنید.

۲.widgets ویجت های بزرگ را به ویجت های کوچکتر تقسیم کنید

مشابه نکته شماره 1، باید سعی کنید اندازه عملکرد ساخت خود را به حداقل برسانید و ویجت ها را تا حد امکان کوچک و ماژولار نگه دارید. استدلال پشت این نکته مشابه استدلال پشت سر نکته شماره 1 است. ویجت های Stateful هنگامی که تغییر حالت وجود دارد دوباره ترسیم می شوند، به این معنی که کل ویجت باید بازسازی شود.

هر چه درخت تابع build بزرگتر باشد، منابع بیشتری برای بازسازی نیاز است.

به عنوان مثال، مثال را در نکته شماره 1 ببینید، جایی که یک ویجت بزرگتر را به دو ویجت تقسیم می کنیم.

۳.از کلمه کلیدی const استفاده کنید

اکنون که ویجت های خود را به زیر ویجت های کوچکتر تقسیم کردم و در صورت امکان از ویجت های بدون حالت(stateless) استفاده کردم، زمان بهینه‌سازی ویجت های به دست آمده فرا رسیده است. یکی از راه‌های انجام این کار، کاهش استفاده از حافظه ویجت‌های من است.

استفاده از کلمه کلیدی const در هر کجا که قابل اجرا باشد می تواند یک راه عالی برای کاهش مصرف حافظه باشد.
در اینجا چند مورد استفاده رایج وجود دارد که من از کلمه کلیدی const استفاده کردم:

استفاده از const برای EdgeInsets, Color and Text

const EdgeInsets.fromLTRB(16, 4, 16, 8); 
const Color lightGray = Color(0xFFFEFEFE); 
const Text('This is a static text')

استفاده از const در سازنده ها

اگر یک ویجت بدون حالت تغییرناپذیر دارید، می‌توانید آن را به صورت Const درآورید، به این معنی که Flutter تنها یک نمونه از این ویجت را در حافظه ایجاد می‌کند. در مثال از نکته شماره 1، می توانید ببینید که ویجت JDSearchIcon دارای یک سازنده const است.

Column( children: 
[ 
const JDSearchIcon(), 
InkWell(....),
 const JDSearchIcon(),
 ], ),

اکنون که از کلمه کلیدی مناسب در مقابل ویجت های بدون حالت خود استفاده کردیم، Flutter تنها یک ویجت را در حافظه نگه می دارد و در هر دو مورد به آن ارجاع می دهد. اگر مکان‌های زیادی دارید که می‌توانید این بهینه‌سازی را اضافه کنید، قطعاً باید عملکرد برنامه فلوتر شما را بهبود بخشد.

همچنین، یکی دیگر از مزیت های بزرگ استفاده از کلمه کلیدی const در این مثال با افزایش عملکرد جلوگیری از ساخت های غیر ضروری یک ویجت است. به عنوان مثال، اگر ویجت والد JDSearchIcon بازسازی شود، ویجت های JDSearchIcon را نیز بازسازی نمی کنیم.

۴.تنها ویجت هایی را رندر کنید که روی صفحه قابل مشاهده هستند

هنگامی که با یک لیست عمودی یا افقی بزرگ از ویجت‌ها سر و کار دارید، باید از استفاده از راه‌حلی که همه ویجت‌ها را به‌طور هم‌زمان روی صفحه‌نمایش قابل مشاهده است، استفاده نکنید. در عوض، سعی کنید از ListView.builder برای بهبود عملکرد برنامه flutter خود استفاده کنید.

به عنوان مثال، تصور کنید ما در حال ساخت اپلیکیشن توییتر هستیم و می‌خواهیم یک جدول زمانی با صدها توییت بسازیم. شما باید از استفاده از یک ستون یا سازنده ListView مانند این اجتناب کنید:

ListView(children: _getTwets());
 // or Column(children: _getTweets()); 
List<Widget> _getTweets() {
 for (var tweet in dataSource) { 
return Tweet(tweet);
 } 
}

اگر از مثال در مورد استفاده کنیم، در نهایت هنگام بارگذاری برنامه، تمام توییت ها را یکجا می سازیم. این بسیار ناکارآمد است و ما باید از Listview.builder استفاده کنیم:

ListView.builder( 
itemCount: dataSource.length, 
itemBuilder: (context, index) { 
return Tweet(dataSource[index]); 
}, 
)

۵.تا حد امکان از استفاده از Opacity خودداری کنید.

تا حد امکان از استفاده از ویجت Opacity خودداری کنید. بسیاری از افراد ممکن است از ویجت Opacity برای مخفی کردن یک ویجت خاص استفاده کنند که در زبان های برنامه نویسی دیگر مانند Objective-C رایج است. برای مثال، اگر می‌خواهید یک ویجت را مخفی کنید، می‌توانید به سادگی آن را در یک ویجت Opacity قرار دهید.


Opacity( opacity: _visible ? 1.0 : 0.0, child: Text("Text!"), ) 

در حالی که این کار می کند، مخفی نگه داشتن ویجت روی صفحه است. در عوض، سعی کنید ویجت خود را به گونه ای بازسازی کنید که بدون ویجت Text بازسازی شود. اگر می‌خواهید ویجت روی صفحه فضا بگیرد، می‌توانید از ویجت Visibility استفاده کنید که کارآمدتر از Opacity است زیرا فقط دو حالت قابل مشاهده/غیر قابل مشاهده دارد.

نتیجه

ساختن یک اپلیکیشن موبایل فلاتر می تواند سریع باشد، اما ساختن یک اپلیکیشن با عملکرد بالا کار ساده ای نیست. امیدوارم 5 نکته عملکرد flutter ارائه شده در بالا به شما کمک کند تا سرعت برنامه تلفن همراه خود را افزایش دهید.

همچنین، اگر به ساختن یک اپلیکیشن با فلاتر و آشنایی با استیت منیجمنت ها علاقه دارین دوره های سایت برای شماست 🙂

دیدگاه کاربران
  • zakarya 23 آذر 1400

    پست خوبی بود . ایول

    • حسن نوروزی 27 آذر 1400

      ممنونم زکریا جان باعث افتخاره که مورد توجهتون قرار گرفته

ارسال دیدگاه

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *