স্থিতিশীলতার সমস্যা নির্ণয় করুন

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

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

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

লেআউট ইন্সপেক্টরে রিকম্পোজিশন এবং স্কিপ কাউন্ট

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

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

সেটআপ

কম্পোজ কম্পাইলার রিপোর্ট ডিফল্টরূপে সক্রিয় থাকে না। আপনি একটি কম্পাইলার ফ্ল্যাগ ব্যবহার করে এগুলো সক্রিয় করতে পারেন। এর সঠিক সেটআপ আপনার প্রোজেক্টের উপর নির্ভর করে ভিন্ন হতে পারে, কিন্তু যেসব প্রোজেক্টে কম্পোজ কম্পাইলার গ্র্যাডল প্লাগইন ব্যবহৃত হয়, সেগুলোর প্রতিটি মডিউলের 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 কম্পোজেবলটি সম্পূর্ণরূপে রিস্টার্টযোগ্য, স্কিপযোগ্য এবং স্থিতিশীল। এটি সাধারণত কাম্য, যদিও অবশ্যই বাধ্যতামূলক নয়।

বিকল্পভাবে, অন্য একটি উদাহরণ বিবেচনা করুন।

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
)

HighlightedSnacks কম্পোজেবলটি স্কিপ করা যায় না। রিকম্পোজিশনের সময় Compose এটিকে কখনোই স্কিপ করে না। এর কোনো প্যারামিটার পরিবর্তিত না হলেও এমনটা ঘটে। এর কারণ হলো snacks নামক unstable প্যারামিটারটি।

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

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 আনস্টেবল (unstable) হিসেবে চিহ্নিত করেছে। এর কারণ হলো, tags প্যারামিটারের টাইপটি হলো Set<String> । এটি একটি ইমিউটেবল (immutable) টাইপ, কারণ এটি একটি MutableSet নয়। তবে, Set , List , এবং Map এর মতো স্ট্যান্ডার্ড কালেকশন ক্লাসগুলো মূলত ইন্টারফেস। সেই হিসেবে, এদের অন্তর্নিহিত ইমপ্লিমেন্টেশনটি মিউটেবল (mutable) হতে পারে।

উদাহরণস্বরূপ, আপনি লিখতে পারেন val set: Set<String> = mutableSetOf("foo") । ভেরিয়েবলটি কনস্ট্যান্ট এবং এর ডিক্লেয়ার্ড টাইপটি মিউটেবল নয়, কিন্তু এর ইমপ্লিমেন্টেশনটি মিউটেবল । Compose কম্পাইলার এই ক্লাসটির ইমিউটেবিলিটি সম্পর্কে নিশ্চিত হতে পারে না, কারণ এটি শুধুমাত্র ডিক্লেয়ার্ড টাইপটি দেখতে পায়। তাই এটি tags আনস্টেবল হিসেবে চিহ্নিত করে।