অ্যাপ অপটিমাইজেশন চালু করতে, আপনাকে অবশ্যই অ্যান্ড্রয়েড অপটিমাইজেশনের সাথে সামঞ্জস্যপূর্ণ লাইব্রেরি ব্যবহার করতে হবে। যদি কোনো লাইব্রেরি অ্যান্ড্রয়েড অপটিমাইজেশনের জন্য কনফিগার করা না থাকে—উদাহরণস্বরূপ, যদি এটি সংশ্লিষ্ট কিপ রুলস বান্ডল না করেই রিফ্লেকশন ব্যবহার করে—তবে এটি একটি অ্যান্ড্রয়েড অ্যাপের জন্য উপযুক্ত নাও হতে পারে। এই পৃষ্ঠাটি ব্যাখ্যা করে কেন কিছু লাইব্রেরি অ্যাপ অপটিমাইজেশনের জন্য বেশি উপযুক্ত এবং আপনাকে বেছে নিতে সাহায্য করার জন্য সাধারণ কিছু পরামর্শ প্রদান করে।
লাইব্রেরি বাছাই করার সময় সাধারণ কিছু পরামর্শ
আপনার লাইব্রেরিগুলো যেন অ্যাপ অপটিমাইজেশনের সাথে সামঞ্জস্যপূর্ণ থাকে, তা নিশ্চিত করতে এই পরামর্শগুলো ব্যবহার করুন।
রিফ্লেকশনের চেয়ে কোডজেনকে প্রাধান্য দিন।
রিফ্লেকশনের পরিবর্তে কোড জেনারেশন ( কোডজেন ) ব্যবহার করে এমন লাইব্রেরি বেছে নিন। কোডজেনের সাহায্যে অপটিমাইজার নির্ধারণ করতে পারে যে রানটাইমে কোন কোড আসলে ব্যবহৃত হচ্ছে এবং কোন কোড বাদ দেওয়া যেতে পারে। কোনো লাইব্রেরি কোডজেন নাকি রিফ্লেকশন ব্যবহার করে, তা বোঝা কঠিন হতে পারে, তবে কিছু লক্ষণ রয়েছে—সাহায্যের জন্য টিপসগুলো দেখুন।
কোডজেন বনাম রিফ্লেকশন সম্পর্কে আরও তথ্যের জন্য, লাইব্রেরি লেখকদের জন্য অপ্টিমাইজেশন দেখুন।
প্রতিফলনের ব্যবহার পরীক্ষা করুন (উন্নত)
কোনো লাইব্রেরি রিফ্লেকশন ব্যবহার করে কিনা, তা তার কোড পরীক্ষা করে বোঝা যায়। যদি লাইব্রেরিটি রিফ্লেকশন ব্যবহার করে, তবে পরীক্ষা করে দেখুন যে এটি সংশ্লিষ্ট কিপ রুলস (keep rules) প্রদান করে কিনা। একটি লাইব্রেরি সম্ভবত রিফ্লেকশন ব্যবহার করে যদি এটি নিম্নলিখিত কাজগুলো করে:
-
kotlin.reflectঅথবাjava.lang.reflectপ্যাকেজের ক্লাস বা মেথড ব্যবহার করে। -
Class.forNameঅথবাclassLoader.getClassফাংশনগুলো ব্যবহার করে। - রানটাইমে অ্যানোটেশনগুলো পড়ে, যেমন যদি এটি
val value = myClass.getAnnotation()বাval value = myMethod.getAnnotation()ব্যবহার করে কোনো অ্যানোটেশনের মান সংরক্ষণ করে এবং তারপর সেইvalueদিয়ে কোনো কাজ করে। নিম্নলিখিত উদাহরণের মতো, মেথডের নামটিকে একটি স্ট্রিং হিসাবে ব্যবহার করে মেথড কল করা হয়:
// Calls the private `processData` API with reflection myObject.javaClass.getMethod("processData", DataType::class.java) ?.invoke(myObject, data)
অপ্টিমাইজেশন সমস্যাগুলি পরীক্ষা করুন
নতুন কোনো লাইব্রেরি বিবেচনা করার সময়, সেটির ইস্যু ট্র্যাকার এবং অনলাইন আলোচনাগুলো দেখে নিন যে মিনিফিকেশন বা অ্যাপ অপটিমাইজেশন কনফিগারেশন সম্পর্কিত কোনো সমস্যা আছে কিনা। যদি থাকে, তবে আপনার সেই লাইব্রেরির বিকল্প খোঁজা উচিত। নিম্নলিখিত বিষয়গুলো মনে রাখবেন:
- AndroidX লাইব্রেরি এবং Hilt- এর মতো লাইব্রেরিগুলো অ্যাপ অপটিমাইজেশনের জন্য বেশ ভালো কাজ করে, কারণ এগুলো মূলত রিফ্লেকশনের পরিবর্তে কোডজেন ব্যবহার করে। যখন তারা রিফ্লেকশন ব্যবহার করে, তখন তারা শুধুমাত্র প্রয়োজনীয় কোড রাখার জন্য ন্যূনতম কিপ রুলস প্রদান করে।
- অবজেক্ট ইনস্ট্যানশিয়েট বা সিরিয়ালাইজ করার সময় বয়লারপ্লেট কোড এড়ানোর জন্য সিরিয়ালাইজেশন লাইব্রেরিগুলো প্রায়শই রিফ্লেকশন ব্যবহার করে। রিফ্লেকশন-ভিত্তিক পদ্ধতির (যেমন JSON-এর জন্য Gson) পরিবর্তে, এই সমস্যাগুলো এড়ানোর জন্য কোডজেন ব্যবহার করে এমন লাইব্রেরি খুঁজুন; উদাহরণস্বরূপ Kotlin Serialization {:.external} অথবা codegen সহ Moshi ব্যবহার করতে পারেন।
- সম্ভব হলে, প্যাকেজ-ব্যাপী কিপ রুল অন্তর্ভুক্ত লাইব্রেরিগুলো এড়িয়ে চলুন। প্যাকেজ-ব্যাপী কিপ রুল ত্রুটি সমাধানে সাহায্য করতে পারে, কিন্তু ব্যাপক কিপ রুলগুলোকে অবশেষে পরিমার্জন করে শুধু প্রয়োজনীয় কোডটুকুই রাখা উচিত। আরও তথ্যের জন্য, ‘অ্যাডপ্ট অপটিমাইজেশনস ইনক্রিমেন্টালি ’ দেখুন।
- থার্ড-পার্টি লাইব্রেরি ব্যবহার করে এমন কোনো অ্যাপ প্রকাশ করার আগে, এর দেওয়া কিপ রুলগুলো নিরীক্ষা করতে R8 কনফিগারেশন অ্যানালাইজার ব্যবহার করুন। রিপোর্টটি পর্যালোচনা করে আপনি যাচাই করতে পারবেন যে, লাইব্রেরিটির কিপ রুলগুলো অতিরিক্ত ব্যাপক কি না, যা আপনার কোডবেসে R8-কে গুরুত্বপূর্ণ অপটিমাইজেশন করতে বাধা দিচ্ছে। এই যাচাইকরণ নিশ্চিত করে যে, আপনার নির্বাচিত লাইব্রেরিগুলো আপনার অ্যাপের পারফরম্যান্সের লক্ষ্যের সাথে সামঞ্জস্যপূর্ণ এবং অপ্রয়োজনীয় কনফিগারেশন স্ফীতি তৈরি করে না।
- লাইব্রেরিগুলোর জন্য ডকুমেন্টেশন থেকে কিপ রুলস কপি করে আপনার প্রোজেক্টের কোনো ফাইলে পেস্ট করার প্রয়োজন হওয়া উচিত নয়, বিশেষ করে প্যাকেজ-ব্যাপী কিপ রুলস তো নয়ই। দীর্ঘমেয়াদে এই নিয়মগুলো অ্যাপ ডেভেলপারের জন্য রক্ষণাবেক্ষণের বোঝা হয়ে দাঁড়ায় এবং সময়ের সাথে সাথে এগুলোকে অপ্টিমাইজ করা ও পরিবর্তন করা কঠিন হয়ে পড়ে।
নতুন লাইব্রেরি যোগ করার পর অপ্টিমাইজেশন সক্রিয় করুন
যখন আপনি একটি নতুন লাইব্রেরি যোগ করবেন, তখন অপটিমাইজেশন চালু করুন এবং কোনো ত্রুটি আছে কিনা তা পরীক্ষা করুন। যদি ত্রুটি থাকে, তবে সেই লাইব্রেরির বিকল্প সন্ধান করুন অথবা রাখার নিয়ম (keep rules) লিখুন। যদি কোনো লাইব্রেরি অপটিমাইজেশনের সাথে সামঞ্জস্যপূর্ণ না হয়, তবে সেই লাইব্রেরির বিরুদ্ধে একটি বাগ রিপোর্ট করুন।
খারাপ রাখার নিয়মগুলি ফিল্টার করে বাদ দিন (উন্নত)
কিপ রুলগুলো সংযোজনযোগ্য। এর মানে হলো, কোনো লাইব্রেরি ডিপেন্ডেন্সিতে অন্তর্ভুক্ত কিছু নির্দিষ্ট রুল সরানো যায় না এবং সেগুলো আপনার অ্যাপের অন্যান্য অংশের কম্পাইলেশনকে প্রভাবিত করতে পারে। উদাহরণস্বরূপ, যদি কোনো লাইব্রেরি কোড অপটিমাইজেশন নিষ্ক্রিয় করার জন্য একটি রুল অন্তর্ভুক্ত করে, তবে সেই রুলটি আপনার পুরো প্রোজেক্টের জন্য অপটিমাইজেশন নিষ্ক্রিয় করে দেবে।
আপনার এমন লাইব্রেরি এড়িয়ে চলা উচিত যেগুলোর 'কিপ রুল' (keep rules) এমন কোড রেখে দেয় যা আসলে মুছে ফেলা উচিত। কিন্তু যদি আপনাকে সেগুলো ব্যবহার করতেই হয়, তবে নিচের কোডে দেখানো উপায়ে আপনি রুলগুলো ফিল্টার করে বাদ দিতে পারেন:
// If you're using AGP 8.4 and higher
buildTypes {
release {
optimization.keepRules {
it.ignoreFrom("com.somelibrary:somelibrary")
}
}
}
// If you're using AGP 7.3-8.3
buildTypes {
release {
optimization.keepRules {
it.ignoreExternalDependencies("com.somelibrary:somelibrary")
}
}
}
কেস স্টাডি: অপটিমাইজেশনের ক্ষেত্রে Gson কেন ব্যর্থ হয়
Gson একটি সিরিয়ালাইজেশন লাইব্রেরি যা প্রায়শই অ্যাপ অপটিমাইজেশনে সমস্যা তৈরি করে, কারণ এটি ব্যাপকভাবে রিফ্লেকশন ব্যবহার করে। নিচের কোড স্নিপেটটি দেখায় কিভাবে Gson সাধারণত ব্যবহৃত হয়, যা রানটাইমে ক্র্যাশ ঘটাতে পারে। লক্ষ্য করুন যে, যখন আপনি User অবজেক্টের একটি তালিকা পেতে Gson ব্যবহার করেন, তখন আপনি fromJson() ফাংশনে কনস্ট্রাক্টর কল করেন না বা কোনো ফ্যাক্টরি পাস করেন না। নিচের যেকোনো একটি ছাড়া অ্যাপ-সংজ্ঞায়িত ক্লাস তৈরি করা বা ব্যবহার করা এই ইঙ্গিত দেয় যে লাইব্রেরিটি সম্ভবত ওপেন-এন্ডেড রিফ্লেকশন ব্যবহার করছে:
- অ্যাপ ক্লাস যা একটি লাইব্রেরি, বা স্ট্যান্ডার্ড ইন্টারফেস বা ক্লাস বাস্তবায়ন করে
- KSP-এর মতো কোড জেনারেশন প্লাগইন
class User(val name: String)
class UserList(val users: List<User>)
// This code runs in debug mode, but crashes when optimizations are enabled
Gson().fromJson("""[{"name":"myname"}]""", User::class.java).toString()
Gson-এর উপর R8 কীভাবে কাজ করে তা বুঝতে, Gson কনজিউমার রুলস দেখুন। যখন R8 এই কোডটি বিশ্লেষণ করে এবং কোথাও UserList বা User ইনস্ট্যানশিয়েট করা দেখতে পায় না, তখন এটি ফিল্ডের নাম পরিবর্তন করতে পারে, অথবা এমন কনস্ট্রাক্টর সরিয়ে দিতে পারে যা ব্যবহৃত হচ্ছে বলে মনে হয় না, যার ফলে আপনার অ্যাপ ক্র্যাশ করতে পারে। আপনি যদি একইভাবে অন্য কোনো লাইব্রেরি ব্যবহার করেন, তবে আপনার পরীক্ষা করে দেখা উচিত যে সেগুলি অ্যাপ অপটিমাইজেশনে হস্তক্ষেপ করবে না, এবং যদি করে, তবে সেগুলি এড়িয়ে চলুন।
Gson-এর কনজিউমার রুলসের সাথে সামঞ্জস্যপূর্ণ পদ্ধতিতে ক্লাসগুলো সংজ্ঞায়িত করতে, রেফারেন্স হিসেবে নিম্নলিখিত কোড স্নিপেটটি ব্যবহার করুন:
class User(@com.google.gson.annotations.SerializedName("name") val name: String)
class UserList(@com.google.gson.annotations.SerializedName("users") val users: List<User>)
উল্লেখ্য যে, Room , Hilt , এবং Moshi কোডজেন সহ অ্যাপ-সংজ্ঞায়িত টাইপ তৈরি করে, কিন্তু রিফ্লেকশনের প্রয়োজনীয়তা এড়াতে কোডজেন ব্যবহার করে।