স্থিতিশীলতার সমস্যাগুলি ঠিক করুন

কর্মক্ষমতা সমস্যা সৃষ্টিকারী একটি অস্থির শ্রেণীর মুখোমুখি হলে, আপনার এটিকে স্থিতিশীল করা উচিত। এই নথিতে আপনি এটি করতে ব্যবহার করতে পারেন এমন কয়েকটি কৌশলের রূপরেখা দেয়।

শক্তিশালী স্কিপিং সক্ষম করুন

আপনার প্রথমে শক্তিশালী স্কিপিং মোড সক্ষম করার চেষ্টা করা উচিত। শক্তিশালী স্কিপিং মোড অস্থির পরামিতি সহ কম্পোজেবলগুলিকে এড়িয়ে যাওয়ার অনুমতি দেয় এবং স্থিতিশীলতার কারণে সৃষ্ট পারফরম্যান্স সমস্যাগুলি সমাধান করার সবচেয়ে সহজ পদ্ধতি।

আরও তথ্যের জন্য শক্তিশালী স্কিপিং দেখুন।

ক্লাস অপরিবর্তনীয় করুন

আপনি একটি অস্থির শ্রেণীকে সম্পূর্ণ অপরিবর্তনীয় করার চেষ্টা করতে পারেন।

  • অপরিবর্তনীয় : এমন একটি টাইপ নির্দেশ করে যেখানে কোনো বৈশিষ্ট্যের মান সেই প্রকারের একটি উদাহরণ তৈরি হওয়ার পরে কখনই পরিবর্তিত হতে পারে না এবং সমস্ত পদ্ধতি রেফারেন্সিয়ালভাবে স্বচ্ছ।
    • নিশ্চিত করুন যে সমস্ত শ্রেণীর বৈশিষ্ট্যগুলি var পরিবর্তে val এবং অপরিবর্তনীয় প্রকারের।
    • আদিম প্রকারগুলি যেমন String, Int এবং Float সর্বদা অপরিবর্তনীয়।
    • যদি এটি অসম্ভব হয়, তাহলে আপনাকে অবশ্যই কোনো পরিবর্তনযোগ্য বৈশিষ্ট্যের জন্য রচনা অবস্থা ব্যবহার করতে হবে।
  • স্থিতিশীল : পরিবর্তনযোগ্য একটি প্রকার নির্দেশ করে। কম্পোজ রানটাইম সচেতন হয় না যদি এবং কখন কোন ধরনের পাবলিক প্রপার্টি বা পদ্ধতি আচরণ পূর্ববর্তী আহ্বান থেকে ভিন্ন ফলাফল দেয়।

অপরিবর্তনীয় সংগ্রহ

কম্পোজ একটি ক্লাসকে অস্থির মনে করার একটি সাধারণ কারণ হল সংগ্রহ। ডায়াগনেস স্থায়িত্ব সমস্যা পৃষ্ঠায় উল্লেখ করা হয়েছে, কম্পোজ কম্পাইলার সম্পূর্ণরূপে নিশ্চিত হতে পারে না যে List, Map এবং Set মতো সংগ্রহগুলি সত্যিই অপরিবর্তনীয় এবং তাই সেগুলিকে অস্থির হিসাবে চিহ্নিত করে৷

এটি সমাধান করতে, আপনি অপরিবর্তনীয় সংগ্রহ ব্যবহার করতে পারেন। কম্পোজ কম্পাইলার Kotlinx অপরিবর্তনীয় সংগ্রহের জন্য সমর্থন অন্তর্ভুক্ত করে। এই সংগ্রহগুলি অপরিবর্তনীয় হওয়ার গ্যারান্টিযুক্ত, এবং কম্পোজ কম্পাইলার সেগুলিকে এমনভাবে বিবেচনা করে। এই লাইব্রেরিটি এখনও আলফাতে রয়েছে, তাই এর API-তে সম্ভাব্য পরিবর্তনগুলি আশা করুন৷

নির্ণয় স্থিতিশীলতা সমস্যা নির্দেশিকা থেকে এই অস্থির শ্রেণীটি আবার বিবেচনা করুন:

unstable class Snack {
  
  unstable val tags: Set<String>
  
}

আপনি একটি অপরিবর্তনীয় সংগ্রহ ব্যবহার করে tags স্থিতিশীল করতে পারেন। ক্লাসে, tags ধরন পরিবর্তন করুন ImmutableSet<String> :

data class Snack{
    
    val tags: ImmutableSet<String> = persistentSetOf()
    
}

এটি করার পরে, ক্লাসের সমস্ত প্যারামিটার অপরিবর্তনীয়, এবং কম্পোজ কম্পাইলার ক্লাসটিকে স্থিতিশীল হিসাবে চিহ্নিত করে।

Stable বা Immutable সহ টীকা

স্থিতিশীলতার সমস্যাগুলি সমাধানের একটি সম্ভাব্য পথ হল অস্থির ক্লাসগুলি @Stable বা @Immutable সাথে টীকা করা।

একটি ক্লাস টীকা করা কম্পাইলার আপনার ক্লাস সম্পর্কে অন্যথায় অনুমান করবে তা ওভাররাইড করছে। এর সাথে মিল আছে !! কোটলিনে অপারেটর । আপনি কীভাবে এই টীকাগুলি ব্যবহার করবেন সে সম্পর্কে আপনার খুব সতর্ক হওয়া উচিত। কম্পাইলার আচরণ ওভাররাইড করা আপনাকে অপ্রত্যাশিত বাগগুলির দিকে নিয়ে যেতে পারে, যেমন আপনার কম্পোজেবল পুনরায় কম্পোজ না করা যখন আপনি এটি আশা করেন।

যদি কোনো টীকা ছাড়াই আপনার শ্রেণীকে স্থিতিশীল করা সম্ভব হয়, তাহলে আপনার সেইভাবে স্থিতিশীলতা অর্জনের চেষ্টা করা উচিত।

নিম্নলিখিত স্নিপেটটি অপরিবর্তনীয় হিসাবে টীকাযুক্ত ডেটা ক্লাসের একটি ন্যূনতম উদাহরণ প্রদান করে:

@Immutable
data class Snack(

)

আপনি @Immutable বা @Stable টীকা ব্যবহার করুন না কেন, কম্পোজ কম্পাইলার Snack ক্লাসটিকে স্থিতিশীল হিসাবে চিহ্নিত করে।

সংগ্রহে টীকা ক্লাস

একটি কম্পোজেবল বিবেচনা করুন যা List<Snack> প্রকারের একটি প্যারামিটার অন্তর্ভুক্ত করে :

restartable scheme("[androidx.compose.ui.UiComposable]") fun HighlightedSnacks(
  
  unstable snacks: List<Snack>
  
)

এমনকি যদি আপনি @Immutable সাথে Snack টীকা করেন, তবুও কম্পোজ কম্পাইলার HighlightedSnacks -এ snacks প্যারামিটারটিকে অস্থির হিসেবে চিহ্নিত করে।

প্যারামিটারগুলি ক্লাসের মতো একই সমস্যার সম্মুখীন হয় যখন এটি সংগ্রহের ধরনগুলির ক্ষেত্রে আসে, কম্পোজ কম্পাইলার সর্বদা টাইপ List একটি প্যারামিটারকে অস্থির হিসাবে চিহ্নিত করে , এমনকি যখন এটি স্থিতিশীল প্রকারের সংগ্রহ হয়।

আপনি একটি পৃথক প্যারামিটারকে স্থিতিশীল হিসাবে চিহ্নিত করতে পারবেন না, বা আপনি সর্বদা এড়িয়ে যাওয়ার জন্য একটি কম্পোজেবল টীকা করতে পারবেন না। সামনে একাধিক পথ আছে।

অস্থির সংগ্রহের সমস্যা থেকে আপনি পেতে পারেন বিভিন্ন উপায় আছে. নিম্নলিখিত উপধারাগুলি এই বিভিন্ন পদ্ধতির রূপরেখা দেয়।

কনফিগারেশন ফাইল

আপনি যদি আপনার কোডবেসে স্থিতিশীলতা চুক্তি মেনে চলতে খুশি হন, তাহলে আপনি আপনার স্থিতিশীলতা কনফিগারেশন ফাইলে kotlin.collections.* যোগ করে Kotlin সংগ্রহগুলিকে স্থিতিশীল হিসাবে বিবেচনা করতে বেছে নিতে পারেন।

অপরিবর্তনীয় সংগ্রহ

অপরিবর্তনীয়তার কম্পাইল সময় নিরাপত্তার জন্য, আপনি List এর পরিবর্তে একটি kotlinx অপরিবর্তনীয় সংগ্রহ ব্যবহার করতে পারেন।

@Composable
private fun HighlightedSnacks(
    
    snacks: ImmutableList<Snack>,
    
)

মোড়ক

আপনি যদি একটি অপরিবর্তনীয় সংগ্রহ ব্যবহার করতে না পারেন তবে আপনি নিজের তৈরি করতে পারেন। এটি করার জন্য, একটি টীকাযুক্ত স্থিতিশীল ক্লাসে List মোড়ানো। আপনার প্রয়োজনীয়তার উপর নির্ভর করে একটি জেনেরিক মোড়ক সম্ভবত এটির জন্য সেরা পছন্দ।

@Immutable
data class SnackCollection(
   val snacks: List<Snack>
)

তারপরে আপনি এটিকে আপনার কম্পোজেবলের প্যারামিটারের ধরণ হিসাবে ব্যবহার করতে পারেন।

@Composable
private fun HighlightedSnacks(
    index: Int,
    snacks: SnackCollection,
    onSnackClick: (Long) -> Unit,
    modifier: Modifier = Modifier
)

সমাধান

এই পদ্ধতির যেকোনো একটি গ্রহণ করার পর, কম্পোজ কম্পাইলার এখন HighlightedSnacks কম্পোজেবলকে skippable এবং restartable উভয় হিসাবে চিহ্নিত করে।

restartable skippable scheme("[androidx.compose.ui.UiComposable]") fun HighlightedSnacks(
  stable index: Int
  stable snacks: ImmutableList<Snack>
  stable onSnackClick: Function1<Long, Unit>
  stable modifier: Modifier? = @static Companion
)

পুনর্গঠনের সময়, কম্পোজ এখন HighlightedSnacks এড়িয়ে যেতে পারে যদি এর কোনো ইনপুট পরিবর্তিত না হয়।

স্থিতিশীলতা কনফিগারেশন ফাইল

কম্পোজ কম্পাইলার 1.5.5 দিয়ে শুরু করে, স্থিতিশীল বিবেচনা করার জন্য ক্লাসগুলির একটি কনফিগারেশন ফাইল কম্পাইলের সময় প্রদান করা যেতে পারে। এটি এমন ক্লাসগুলি বিবেচনা করার অনুমতি দেয় যা আপনি নিয়ন্ত্রণ করেন না, যেমন LocalDateTime এর মতো স্ট্যান্ডার্ড লাইব্রেরি ক্লাসগুলি স্থিতিশীল হিসাবে।

কনফিগারেশন ফাইলটি একটি প্লেইন টেক্সট ফাইল যার প্রতি সারিতে একটি ক্লাস রয়েছে। মন্তব্য, একক এবং ডবল ওয়াইল্ডকার্ড সমর্থিত। একটি উদাহরণ কনফিগারেশন:

// Consider LocalDateTime stable
java.time.LocalDateTime
// Consider my datalayer stable
com.datalayer.*
// Consider my datalayer and all submodules stable
com.datalayer.**
// Consider my generic type stable based off it's first type parameter only
com.example.GenericClass<*,_>

এই বৈশিষ্ট্যটি সক্ষম করতে, কম্পোজ কম্পাইলার গ্রেডল প্লাগইন কনফিগারেশনের composeCompiler অপশন ব্লকে কনফিগারেশন ফাইলের পাথ পাস করুন।

composeCompiler {
  stabilityConfigurationFile = rootProject.layout.projectDirectory.file("stability_config.conf")
}

যেহেতু কম্পোজ কম্পাইলার আপনার প্রজেক্টের প্রতিটি মডিউলে আলাদাভাবে চলে, প্রয়োজনে আপনি বিভিন্ন মডিউলে বিভিন্ন কনফিগারেশন প্রদান করতে পারেন। বিকল্পভাবে, আপনার প্রকল্পের রুট স্তরে একটি কনফিগারেশন রাখুন এবং প্রতিটি মডিউলে সেই পথটি পাস করুন।

একাধিক মডিউল

আরেকটি সাধারণ সমস্যা মাল্টি-মডিউল আর্কিটেকচার জড়িত। কম্পোজ কম্পাইলার শুধুমাত্র একটি ক্লাস স্থিতিশীল কিনা তা অনুমান করতে পারে যদি এটি উল্লেখ করে এমন সমস্ত নন-প্রিমিটিভ প্রকারগুলিকে হয় স্পষ্টভাবে স্থিতিশীল হিসাবে চিহ্নিত করা হয় বা একটি মডিউলে যা কম্পোজ কম্পাইলারের সাথে তৈরি করা হয়েছিল।

যদি আপনার ডেটা স্তরটি আপনার UI স্তরের একটি পৃথক মডিউলে থাকে, যা প্রস্তাবিত পদ্ধতি, এটি আপনার সম্মুখীন হতে পারে এমন একটি সমস্যা।

সমাধান

এই সমস্যাটি সমাধান করার জন্য আপনি নিম্নলিখিত পদ্ধতির একটি গ্রহণ করতে পারেন:

  1. আপনার কম্পাইলার কনফিগারেশন ফাইলে ক্লাস যোগ করুন।
  2. আপনার ডেটা লেয়ার মডিউলগুলিতে কম্পোজ কম্পাইলার সক্ষম করুন, অথবা যেখানে উপযুক্ত সেখানে @Stable বা @Immutable দিয়ে আপনার ক্লাসগুলিকে ট্যাগ করুন।
    • এটি আপনার ডেটা স্তরে একটি রচনা নির্ভরতা যোগ করে। যাইহোক, এটি শুধুমাত্র রচনা রানটাইমের জন্য নির্ভরতা এবং Compose-UI এর জন্য নয়।
  3. আপনার UI মডিউলের মধ্যে, UI-নির্দিষ্ট র‍্যাপার ক্লাসে আপনার ডেটা স্তরের ক্লাসগুলিকে মোড়ানো করুন৷

বহিরাগত লাইব্রেরি ব্যবহার করার সময় একই সমস্যা দেখা দেয় যদি তারা কম্পোজ কম্পাইলার ব্যবহার না করে।

প্রতিটি কম্পোজেবল এড়িয়ে যাওয়া উচিত নয়

স্থিতিশীলতার সাথে সমস্যাগুলি সমাধান করার জন্য কাজ করার সময়, আপনার প্রতিটি কম্পোজেবল এড়িয়ে যাওয়ার চেষ্টা করা উচিত নয়। এটি করার প্রচেষ্টা অকাল অপ্টিমাইজেশানের দিকে নিয়ে যেতে পারে যা এটির সমাধানের চেয়ে আরও বেশি সমস্যা উপস্থাপন করে।

এমন অনেক পরিস্থিতি রয়েছে যেখানে এড়িয়ে যাওয়ার কোনো প্রকৃত সুবিধা নেই এবং কোড বজায় রাখা কঠিন হতে পারে। যেমন:

  • একটি সংমিশ্রণযোগ্য যা প্রায়শই পুনর্গঠিত হয় না বা একেবারেই হয় না।
  • একটি কম্পোজেবল যা নিজেই শুধু স্কিপযোগ্য কম্পোজেবল বলে।
  • ব্যয়বহুল সমান বাস্তবায়ন সহ বিপুল সংখ্যক পরামিতি সহ একটি রচনাযোগ্য। এই ক্ষেত্রে, কোনো পরামিতি পরিবর্তিত হয়েছে কিনা তা পরীক্ষা করার খরচ একটি সস্তা পুনর্গঠনের খরচের চেয়ে বেশি হতে পারে।

যখন একটি কম্পোজেবল এড়ানো যায় তখন এটি একটি ছোট ওভারহেড যোগ করে যা এটির মূল্য নাও হতে পারে। এমনকি আপনি আপনার কম্পোজেবলটিকে অ-পুনঃসূচনাযোগ্য হওয়ার জন্য টীকাও দিতে পারেন যেখানে আপনি নির্ধারণ করেন যে পুনঃসূচনা করা মূল্যের চেয়ে বেশি ওভারহেড।