স্থিতিশীলতা সংক্রান্ত সমস্যার ডায়াগনসিস করা

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

লেআউট ইন্সপেক্টর

Android Studio-তে লেআউট ইন্সপেক্টর আপনাকে দেখতে দেয় যে আপনার অ্যাপে কোন কম্পোজেবল রিকম্পোজ হচ্ছে। Compose কতবার কোনও কম্পোনেন্ট রিকম্পোজ বা স্কিপ করেছে তার সংখ্যা এটি দেখায়।

লেআউট ইন্সপেক্টরে রিকম্পোজিশন ও স্কিপের সংখ্যা

কম্পোজ কম্পাইলার রিপোর্ট

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

সেট-আপ করুন

Compose কম্পাইলার রিপোর্ট ডিফল্ট হিসেবে চালু করা থাকে না। আপনি কম্পাইলার ফ্ল্যাগ ব্যবহার করে সেগুলি অ্যাক্টিভেট করতে পারবেন। আপনার প্রোজেক্টের উপর নির্ভর করে সঠিক সেট-আপ আলাদা আলাদা হয়, তবে Compose কম্পাইলার গ্রেডেল প্লাগ-ইন ব্যবহার করা প্রোজেক্টের জন্য আপনি প্রতিটি মডিউলের build.gradle ফাইলে নিম্নলিখিতগুলি যোগ করতে পারবেন।

  android { ... }

  composeCompiler {
    reportsDestination = layout.buildDirectory.dir("compose_compiler")
    metricsDestination = layout.buildDirectory.dir("compose_compiler")
  }

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

আউটপুটের উদাহরণ

reportsDestination তিনটি ফাইল আউটপুট করে। JetSnack থেকে নিম্নলিখিত আউটপুটগুলি উদাহরণ হিসেবে দেওয়া হল।

  • <modulename>-classes.txt: এই মডিউলে ক্লাসের স্টেবিলিটি সংক্রান্ত রিপোর্ট। স্যাম্পেল।
  • <modulename>-composables.txt: মডিউলে কম্পোজেবলগুলি কতটা রিস্টার্টেবল এবং স্কিপেবল সেই সম্পর্কে একটি রিপোর্ট। স্যাম্পেল।
  • <modulename>-composables.csv:কম্পোজেবল রিপোর্টের একটি CSV ভার্সন যা আপনি স্প্রেডশিটে ইমপোর্ট করতে পারেন বা স্ক্রিপ্ট ব্যবহার করে প্রসেস করতে পারেন। স্যাম্পেল

কম্পোজেবল রিপোর্ট

composables.txt ফাইলটি প্রদত্ত মডিউলের জন্য প্রতিটি কম্পোজেবল ফাংশনের বিবরণ দেয়, যার মধ্যে তাদের প্যারামিটারের স্থিতিশীলতা এবং সেগুলি রিস্টার্ট করা বা এড়িয়ে যাওয়া যায় কিনা তা অন্তর্ভুক্ত। JetSnack থেকে নেওয়া একটি কাল্পনিক উদাহরণ নিচে দেওয়া হল:

restartable skippable scheme("[androidx.compose.ui.UiComposable]") fun SnackCollection(
  stable snackCollection: SnackCollection
  stable onSnackClick: Function1<Long, Unit>
  stable modifier: Modifier? = @static Companion
  stable index: Int = @static 0
  stable highlight: Boolean = @static true
)

এই উদাহরণে, SnackCollection-এর প্রতিটি প্যারামিটার stable হিসেবে চিহ্নিত করা হয়েছে, তাই Compose স্ট্রাকচারাল ইকুয়ালিটি (Object.equals()) ব্যবহার করে প্রতিটি প্যারামিটার তুলনা করে। stable প্যারামিটার প্রিমিটিভ ভ্যালু এবং ছোট, ফ্ল্যাট ডেটা ক্লাসের জন্য আদর্শ হলেও, সস্তা .equals() চেকের মাধ্যমে, কালেকশন-হোল্ডিং মডেলকে (যেমন List<Snack>-কে র‍্যাপ করা SnackCollection) stable হতে বাধ্য করলে, Compose-কে প্রতিটি রিকম্পোজিশনে প্রতিটি আইটেমে .equals() কল করতে হয়। স্ট্রং স্কিপিং মোড চালু থাকলে, unstable কালেকশন হোল্ড করে এমন মডেল রাখাই ভালো যাতে Compose সেগুলিকে ইনস্ট্যান্স ইকুয়ালিটি (===) ব্যবহার করে তুলনা করে।

বিকল্প হিসেবে, স্ট্রং স্কিপিং মোড বন্ধ করে তৈরি করা আরেকটি উদাহরণ বিবেচনা করুন:

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

স্ট্রং স্কিপিং মোড বন্ধ করা থাকলে (Kotlin 2.0.20-এর আগে), HighlightedSnacks কম্পোজেবল স্কিপ করা যায় না—রিকম্পোজিশনের সময় Compose এটি কখনও স্কিপ করে না, এমনকি এর কোনও প্যারামিটার পরিবর্তন না হলেও, কারণ unstable প্যারামিটার snacks।

স্ট্রং স্কিপিং মোড চালু থাকলে (Kotlin 2.0.20 এবং তার পরবর্তী ভার্সনে ডিফল্ট হিসেবে), HighlightedSnacks-কে skippable হিসেবে চিহ্নিত করা হয় এবং Compose unstable প্যারামিটার snacks-কে ইনস্ট্যান্স ইকুয়ালিটি (===) ব্যবহার করে তুলনা করে। এর ফলে, একই List রেফারেন্স পাস করা হলে Compose HighlightedSnacks-কে স্কিপ করে এবং নতুনভাবে বরাদ্দ করা List ইনস্ট্যান্স পাস করা হলে তবেই এটি রিকম্পোজ করে।

ক্লাসের রিপোর্ট

classes.txt ফাইলে প্রদত্ত মডিউলের ক্লাস সম্পর্কে একই ধরনের রিপোর্ট রয়েছে। নিম্নলিখিত স্নিপেটটি হল Snack ক্লাসের আউটপুট:

unstable class Snack {
  stable val id: Long
  stable val name: String
  stable val imageUrl: String
  stable val price: Long
  stable val tagline: String
  unstable val tags: Set<String>
  <runtime stability> = Unstable
}

রেফারেন্সের জন্য, Snack-এর সংজ্ঞা নিচে দেওয়া হল:

data class Snack(
    val id: Long,
    val name: String,
    val imageUrl: String,
    val price: Long,
    val tagline: String = "",
    val tags: Set<String> = emptySet()
)

Compose কম্পাইলার Snack-কে 'অস্থির' হিসেবে চিহ্নিত করেছে। এটি হওয়ার কারণ হল, tags প্যারামিটারের ধরন হল Set<String>। এটি একটি অপরিবর্তনীয় ধরন, কারণ এটি MutableSet নয়। তবে, Set, List এবং Map-এর মতো স্ট্যান্ডার্ড কালেকশন ক্লাসগুলি শেষ পর্যন্ত ইন্টারফেস। সেই কারণে, অন্তর্নিহিত ইমপ্লিমেন্টেশন এখনও পরিবর্তনযোগ্য হতে পারে।

যেমন, আপনি val set: Set<String> = mutableSetOf("foo") লিখতে পারেন। ভেরিয়েবেলটি কনস্ট্যান্ট এবং এর ঘোষিত ধরন পরিবর্তনযোগ্য নয়, তবে এর প্রয়োগ এখনও পরিবর্তনযোগ্য। Compose কম্পাইলার এই ক্লাসের অপরিবর্তনীয়তা সম্পর্কে নিশ্চিত হতে পারে না কারণ এটি শুধুমাত্র ঘোষিত ধরন দেখে। তাই এটি tags-কে অস্থির হিসেবে চিহ্নিত করে।