যখন কোনও অস্থির শ্রেণীর মুখোমুখি হন যা কর্মক্ষমতা সংক্রান্ত সমস্যার সৃষ্টি করে, তখন আপনার এটিকে স্থিতিশীল করা উচিত। এই নথিতে আপনি এটি করার জন্য ব্যবহার করতে পারেন এমন বেশ কয়েকটি কৌশলের রূপরেখা দেওয়া হয়েছে।
জোরে জোরে স্কিপিং সক্ষম করুন
প্রথমে আপনার শক্তিশালী স্কিপিং মোড সক্ষম করার চেষ্টা করা উচিত। শক্তিশালী স্কিপিং মোড অস্থির পরামিতি সহ কম্পোজেবলগুলিকে এড়িয়ে যাওয়ার অনুমতি দেয় এবং স্থিতিশীলতার কারণে সৃষ্ট কর্মক্ষমতা সমস্যাগুলি সমাধান করার এটি সবচেয়ে সহজ পদ্ধতি।
আরও তথ্যের জন্য স্ট্রং স্কিপিং দেখুন।
ক্লাসটিকে অপরিবর্তনীয় করুন
আপনি একটি অস্থির শ্রেণীকে সম্পূর্ণরূপে অপরিবর্তনীয় করার চেষ্টা করতে পারেন।
- অপরিবর্তনীয় : এমন একটি ধরণ নির্দেশ করে যেখানে কোনও বৈশিষ্ট্যের মান সেই ধরণের একটি উদাহরণ তৈরি করার পরে কখনই পরিবর্তন হতে পারে না এবং সমস্ত পদ্ধতি রেফারেন্সিয়ালভাবে স্বচ্ছ।
- নিশ্চিত করুন যে সমস্ত ক্লাসের বৈশিষ্ট্যগুলি
varএর পরিবর্তেvalএবং অপরিবর্তনীয় ধরণের। -
String, IntএবংFloatএর মতো আদিম প্রকারগুলি সর্বদা অপরিবর্তনীয়। - যদি এটি অসম্ভব হয়, তাহলে আপনাকে যেকোনো পরিবর্তনযোগ্য বৈশিষ্ট্যের জন্য Compose state ব্যবহার করতে হবে।
- নিশ্চিত করুন যে সমস্ত ক্লাসের বৈশিষ্ট্যগুলি
- Stable : এমন একটি টাইপ নির্দেশ করে যা পরিবর্তনযোগ্য। কম্পোজ রানটাইম কখন এবং কখন টাইপের কোনও পাবলিক প্রোপার্টি বা মেথড আচরণ পূর্ববর্তী ইনভোকেশন থেকে ভিন্ন ফলাফল দেবে তা জানতে পারে না।
অপরিবর্তনীয় সংগ্রহ
কম্পোজ কেন একটি ক্লাসকে অস্থির মনে করে তার একটি সাধারণ কারণ হল সংগ্রহ। স্থিতিশীলতা সমস্যা নির্ণয় পৃষ্ঠায় যেমন উল্লেখ করা হয়েছে, কম্পোজ কম্পাইলার সম্পূর্ণরূপে নিশ্চিত হতে পারে না যে 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 ব্যবহার করে অস্থির ক্লাসগুলি টীকা করা।
একটি ক্লাস অ্যানোটেশন করা মানে কম্পাইলার আপনার ক্লাস সম্পর্কে যা অনুমান করবে তা ওভাররাইড করা। এটি Kotlin এর !! অপারেটরের মতো। এই অ্যানোটেশনগুলি কীভাবে ব্যবহার করবেন সে সম্পর্কে আপনার খুব সতর্ক থাকা উচিত। কম্পাইলার আচরণ ওভাররাইড করলে আপনার অপ্রত্যাশিত বাগ দেখা দিতে পারে, যেমন আপনার কম্পোজেবল যখন আপনি আশা করেন তখন পুনরায় কম্পোজ না করা।
যদি টীকা ছাড়াই আপনার ক্লাসকে স্থিতিশীল করা সম্ভব হয়, তাহলে আপনার সেইভাবে স্থিতিশীলতা অর্জনের চেষ্টা করা উচিত।
নিম্নলিখিত স্নিপেটটি অপরিবর্তনীয় হিসাবে টীকাযুক্ত একটি ডেটা ক্লাসের একটি ন্যূনতম উদাহরণ প্রদান করে:
@Immutable
data class Snack(
…
)
আপনি @Immutable অথবা @Stable অ্যানোটেশন ব্যবহার করুন না কেন, Compose কম্পাইলার Snack ক্লাসটিকে স্থিতিশীল হিসেবে চিহ্নিত করে।
সংগ্রহে টীকাযুক্ত ক্লাস
একটি কম্পোজেবল বিবেচনা করুন যাতে List<Snack> ধরণের একটি প্যারামিটার থাকে :
restartable scheme("[androidx.compose.ui.UiComposable]") fun HighlightedSnacks(
…
unstable snacks: List<Snack>
…
)
এমনকি যদি আপনি @Immutable দিয়ে Snack টিকা দেন, তবুও Compose কম্পাইলার 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
)
সমাধান
এই পদ্ধতিগুলির যেকোনো একটি গ্রহণ করার পরে, Compose কম্পাইলার এখন HighlightedSnacks Composable কে 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 এড়িয়ে যেতে পারে যদি এর কোনও ইনপুট পরিবর্তন না হয়।
স্থিতিশীলতা কনফিগারেশন ফাইল
কম্পোজ কম্পাইলার ১.৫.৫ থেকে শুরু করে, কম্পাইলের সময় স্থিতিশীল বিবেচনা করার জন্য ক্লাসগুলির একটি কনফিগারেশন ফাইল সরবরাহ করা যেতে পারে। এটি আপনার নিয়ন্ত্রণে নেই এমন ক্লাসগুলিকে, যেমন 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 লেয়ারের সাথে আলাদা একটি মডিউলে থাকে, যা প্রস্তাবিত পদ্ধতি, তাহলে এটি আপনার সম্মুখীন হতে পারে এমন একটি সমস্যা।
সমাধান
এই সমস্যা সমাধানের জন্য আপনি নিম্নলিখিত পদ্ধতিগুলির মধ্যে একটি গ্রহণ করতে পারেন:
- আপনার কম্পাইলার কনফিগারেশন ফাইলে ক্লাসগুলি যোগ করুন।
- আপনার ডেটা লেয়ার মডিউলগুলিতে কম্পোজ কম্পাইলার সক্ষম করুন, অথবা আপনার ক্লাসগুলিকে
@Stableবা@Immutableদিয়ে ট্যাগ করুন যেখানে উপযুক্ত।- এর জন্য আপনার ডেটা লেয়ারে একটি Compose নির্ভরতা যোগ করা প্রয়োজন। তবে, এটি কেবল Compose রানটাইমের জন্য নির্ভরতা,
Compose-UIএর জন্য নয়।
- এর জন্য আপনার ডেটা লেয়ারে একটি Compose নির্ভরতা যোগ করা প্রয়োজন। তবে, এটি কেবল Compose রানটাইমের জন্য নির্ভরতা,
- আপনার UI মডিউলের মধ্যে, আপনার ডেটা লেয়ার ক্লাসগুলিকে UI-নির্দিষ্ট র্যাপার ক্লাসে মোড়ানো।
একই সমস্যা তখনও দেখা দেয় যখন বহিরাগত লাইব্রেরিগুলি কম্পোজ কম্পাইলার ব্যবহার না করে।
প্রতিটি কম্পোজেবল বাদ দেওয়া উচিত নয়
স্থিতিশীলতার সমস্যা সমাধানের জন্য কাজ করার সময়, প্রতিটি কম্পোজেবল এড়িয়ে যাওয়ার চেষ্টা করা উচিত নয়। এটি করার চেষ্টা করলে অকাল অপ্টিমাইজেশন হতে পারে যা সমাধানের চেয়ে বেশি সমস্যা তৈরি করে।
এমন অনেক পরিস্থিতি আছে যেখানে স্কিপেবল থাকার কোনও প্রকৃত সুবিধা নেই এবং কোড বজায় রাখা কঠিন হতে পারে। উদাহরণস্বরূপ:
- একটি কম্পোজেবল যা প্রায়শই পুনর্গঠিত হয় না, অথবা একেবারেই হয় না।
- একটি কম্পোজেবল যা নিজেই কেবল স্কিপেবল কম্পোজেবল বলে।
- একটি কম্পোজেবল যেখানে প্রচুর সংখ্যক প্যারামিটার এবং ব্যয়বহুল সমান বাস্তবায়ন রয়েছে। এই ক্ষেত্রে, কোনও প্যারামিটার পরিবর্তিত হয়েছে কিনা তা পরীক্ষা করার খরচ একটি সস্তা পুনর্গঠনের খরচের চেয়ে বেশি হতে পারে।
যখন একটি কম্পোজেবল স্কিপেবল হয় তখন এটি একটি ছোট ওভারহেড যোগ করে যা এর মূল্য নাও হতে পারে। আপনি এমনকি আপনার কম্পোজেবলকে অ-রিস্টার্টেবল হিসেবে টীকাবদ্ধ করতে পারেন, যেখানে আপনি নির্ধারণ করেন যে রিস্টার্টেবল তার মূল্যের চেয়ে বেশি ওভারহেড।