অ্যাপ শুরুর সময়

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

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

অ্যাপের বিভিন্ন স্টার্টআপ অবস্থা বুঝুন

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

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

আপনার অ্যাপকে দ্রুত চালু করার জন্য অপ্টিমাইজ করতে, সিস্টেম এবং অ্যাপ স্তরে কী ঘটছে এবং এই প্রতিটি অবস্থায় তারা কীভাবে একে অপরের সাথে মিথস্ক্রিয়া করে, তা বোঝা সহায়ক।

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

ঠান্ডা শুরু

কোল্ড স্টার্ট বলতে কোনো অ্যাপের একেবারে গোড়া থেকে চালু হওয়াকে বোঝায়। এর মানে হলো, এই চালু হওয়ার আগ পর্যন্ত সিস্টেমের প্রসেসটিই অ্যাপটির প্রসেস তৈরি করে। ডিভাইস বুট হওয়ার পর বা সিস্টেম অ্যাপটি বন্ধ করে দেওয়ার পর আপনার অ্যাপটি প্রথমবার চালু হলে কোল্ড স্টার্ট ঘটে থাকে।

এই ধরনের সূচনা স্টার্টআপ সময় কমানোর ক্ষেত্রে সবচেয়ে বড় চ্যালেঞ্জ তৈরি করে, কারণ অন্যান্য লঞ্চ অবস্থার তুলনায় সিস্টেম এবং অ্যাপকে বেশি কাজ করতে হয়।

কোল্ড স্টার্টের শুরুতে সিস্টেমটির নিম্নলিখিত তিনটি কাজ থাকে:

  1. অ্যাপটি লোড করে চালু করুন।
  2. অ্যাপটি চালু করার ঠিক পরেই একটি খালি প্রারম্ভিক উইন্ডো প্রদর্শন করুন।
  3. অ্যাপ প্রক্রিয়াটি তৈরি করুন।

সিস্টেমটি অ্যাপ প্রসেস তৈরি করার সাথে সাথেই, অ্যাপ প্রসেসটি পরবর্তী পর্যায়গুলোর জন্য দায়ী থাকে:

  1. অ্যাপ অবজেক্টটি তৈরি করুন।
  2. প্রধান থ্রেডটি চালু করুন।
  3. মূল অ্যাক্টিভিটি তৈরি করুন।
  4. দৃশ্যগুলিকে প্রসারিত করুন।
  5. স্ক্রিনটি বিন্যস্ত করুন।
  6. প্রাথমিক ড্রটি সম্পাদন করুন।

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

চিত্র ১-এ দেখানো হয়েছে কীভাবে সিস্টেম এবং অ্যাপ প্রসেসগুলো একে অপরের মধ্যে কাজ হস্তান্তর করে।

চিত্র ১. একটি কোল্ড অ্যাপ লঞ্চের গুরুত্বপূর্ণ অংশগুলোর একটি চাক্ষুষ উপস্থাপনা।

অ্যাপ তৈরি এবং অ্যাক্টিভিটি তৈরির সময় পারফরম্যান্স সংক্রান্ত সমস্যা দেখা দিতে পারে।

অ্যাপ তৈরি

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

যদি আপনি আপনার নিজের অ্যাপে Application.onCreate() ওভাররাইড করেন, তাহলে সিস্টেম আপনার অ্যাপ অবজেক্টের onCreate() মেথডটি কল করে। এরপর, অ্যাপটি মেইন থ্রেড, যা UI থ্রেড নামেও পরিচিত, চালু করে এবং এটিকে আপনার মেইন অ্যাক্টিভিটি তৈরি করার দায়িত্ব দেয়।

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

কার্যকলাপ তৈরি

অ্যাপ প্রসেসটি আপনার অ্যাক্টিভিটি তৈরি করার পর, অ্যাক্টিভিটিটি নিম্নলিখিত অপারেশনগুলো সম্পাদন করে:

  1. মানগুলো প্রারম্ভিক করে।
  2. কনস্ট্রাক্টরগুলোকে কল করে।
  3. অ্যাক্টিভিটির বর্তমান লাইফসাইকেল স্টেটের জন্য উপযুক্ত কলব্যাক মেথড, যেমন Activity.onCreate() , কল করে।

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

উষ্ণ সূচনা

একটি ওয়ার্ম স্টার্টে কোল্ড স্টার্টের সময় সংঘটিত অপারেশনগুলোর একটি উপসেট অন্তর্ভুক্ত থাকে। একই সাথে, এতে হট স্টার্টের চেয়ে বেশি ওভারহেড থাকে। এমন অনেক সম্ভাব্য অবস্থা রয়েছে যেগুলোকে ওয়ার্ম স্টার্ট হিসেবে বিবেচনা করা যেতে পারে, যেমন নিম্নলিখিতগুলো:

  • ব্যবহারকারী আপনার অ্যাপ থেকে বেরিয়ে যান কিন্তু তারপর আবার এটি চালু করেন। প্রসেসটি চলতে থাকতে পারে, কিন্তু অ্যাপটিকে অবশ্যই onCreate() কল ব্যবহার করে প্রথম থেকে অ্যাক্টিভিটিটি পুনরায় তৈরি করতে হবে।

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

হট স্টার্ট

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

তবে, যদি onTrimMemory() এর মতো মেমরি ট্রিমিং ইভেন্টের প্রতিক্রিয়ায় কিছু মেমরি মুছে ফেলা হয়, তাহলে হট স্টার্ট ইভেন্টের প্রতিক্রিয়ায় এই অবজেক্টগুলিকে পুনরায় তৈরি করতে হবে।

হট স্টার্টের ক্ষেত্রে স্ক্রিনে কোল্ড স্টার্টের মতোই আচরণ দেখা যায়। অ্যাপটি অ্যাক্টিভিটি রেন্ডার করা শেষ না করা পর্যন্ত সিস্টেম প্রসেসটি একটি ফাঁকা স্ক্রিন প্রদর্শন করে।

চিত্র ২. বিভিন্ন প্রারম্ভিক অবস্থা এবং তাদের নিজ নিজ প্রক্রিয়া সম্বলিত একটি ডায়াগ্রাম, যেখানে প্রতিটি অবস্থা অঙ্কিত প্রথম ফ্রেম থেকে শুরু হয়েছে।

পারফেটোতে অ্যাপ স্টার্টআপ কীভাবে শনাক্ত করবেন

অ্যাপ চালু হওয়ার সমস্যা ডিবাগ করার জন্য, অ্যাপ চালু হওয়ার পর্যায়ে ঠিক কী কী অন্তর্ভুক্ত রয়েছে তা নির্ধারণ করা সহায়ক। Perfetto- তে সম্পূর্ণ অ্যাপ চালু হওয়ার পর্যায়টি শনাক্ত করতে, এই ধাপগুলো অনুসরণ করুন:

  1. পারফেটোতে, 'Android App Startups' ডিরাইভড মেট্রিকযুক্ত সারিটি খুঁজুন। যদি আপনি এটি দেখতে না পান, তবে ডিভাইসের সিস্টেম ট্রেসিং অ্যাপ ব্যবহার করে একটি ট্রেস ক্যাপচার করার চেষ্টা করুন।

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

  3. অ্যান্ড্রয়েড অ্যাপ স্টার্টআপস সারিটি পিন করতে, পিন আইকনটিতে ক্লিক করুন, যেটি সারিটির উপর পয়েন্টার ধরে রাখলে দেখা যায়।

  4. প্রশ্নোক্ত অ্যাপটি থাকা সারিটিতে স্ক্রল করুন এবং সারিটি প্রসারিত করতে প্রথম সেলটিতে ক্লিক করুন।

  5. মূল থ্রেডে জুম করতে, যা সাধারণত উপরে থাকে, w চাপুন (জুম আউট করতে, বামে ও ডানে যেতে যথাক্রমে s, a, d চাপুন)।

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

স্টার্টআপগুলি পরিদর্শন ও উন্নত করতে মেট্রিক্স ব্যবহার করুন

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

স্টার্টআপ মেট্রিক্স ব্যবহারের সুবিধা

অ্যান্ড্রয়েড কোল্ড ও ওয়ার্ম অ্যাপ স্টার্টআপ অপ্টিমাইজ করার জন্য টাইম টু ইনিশিয়াল ডিসপ্লে (TTID) এবং টাইম টু ফুল ডিসপ্লে (TTFD) মেট্রিকগুলো ব্যবহার করে। অ্যান্ড্রয়েড রানটাইম (ART) ভবিষ্যতের স্টার্টআপ অপ্টিমাইজেশনের জন্য দক্ষতার সাথে কোড প্রি-কম্পাইল করতে এই মেট্রিকগুলোর ডেটা ব্যবহার করে।

দ্রুত স্টার্টআপের ফলে ব্যবহারকারীরা আপনার অ্যাপের সাথে আরও দীর্ঘক্ষণ যুক্ত থাকেন, যা অ্যাপ মাঝপথে বন্ধ করে দেওয়া, ইনস্ট্যান্সটি রিস্টার্ট করা বা অন্য কোনো অ্যাপে চলে যাওয়ার মতো ঘটনা কমিয়ে দেয়।

অ্যান্ড্রয়েড ভাইটালস

আপনার অ্যাপ চালু হতে অতিরিক্ত সময় নিলে, অ্যান্ড্রয়েড ভাইটালস প্লে কনসোলে আপনাকে সতর্ক করার মাধ্যমে অ্যাপটির পারফরম্যান্স উন্নত করতে সাহায্য করতে পারে।

অ্যান্ড্রয়েড ভাইটালস আপনার অ্যাপের জন্য নিম্নলিখিত স্টার্টআপ সময়গুলোকে অতিরিক্ত বলে মনে করে:

  • ঠান্ডা অবস্থায় চালু হতে ৫ সেকেন্ড বা তার বেশি সময় লাগে।
  • ওয়ার্ম স্টার্টআপ হতে ২ সেকেন্ড বা তার বেশি সময় লাগে।
  • হট স্টার্টআপ হতে ১.৫ সেকেন্ড বা তার বেশি সময় লাগে।

অ্যান্ড্রয়েড ভাইটালস টাইম টু ইনিশিয়াল ডিসপ্লে (TTID) মেট্রিক ব্যবহার করে। গুগল প্লে কীভাবে অ্যান্ড্রয়েড ভাইটালস ডেটা সংগ্রহ করে, সে সম্পর্কে জানতে প্লে কনসোল ডকুমেন্টেশন দেখুন।

প্রাথমিক প্রদর্শনের সময়

টাইম টু ইনিশিয়াল ডিসপ্লে (TTID) হলো অ্যাপের UI-এর প্রথম ফ্রেমটি প্রদর্শন করতে যে সময় লাগে। এই মেট্রিকটি একটি অ্যাপের প্রথম ফ্রেম তৈরি করতে যে সময় লাগে তা পরিমাপ করে, যার মধ্যে কোল্ড স্টার্টের সময় প্রসেস ইনিশিয়ালাইজেশন, কোল্ড বা ওয়ার্ম স্টার্টের সময় অ্যাক্টিভিটি তৈরি এবং প্রথম ফ্রেমটি প্রদর্শন করা অন্তর্ভুক্ত। আপনার অ্যাপের TTID কম রাখলে তা ব্যবহারকারীর অভিজ্ঞতা উন্নত করতে সাহায্য করে, কারণ এর ফলে ব্যবহারকারীরা আপনার অ্যাপটি দ্রুত চালু হতে দেখতে পান। অ্যান্ড্রয়েড ফ্রেমওয়ার্ক দ্বারা প্রতিটি অ্যাপের জন্য TTID স্বয়ংক্রিয়ভাবে রিপোর্ট করা হয়। অ্যাপ স্টার্টআপ অপ্টিমাইজ করার সময়, আমরা TTFD পর্যন্ত তথ্য পেতে reportFullyDrawn প্রয়োগ করার পরামর্শ দিই।

TTID একটি সময় মান হিসাবে পরিমাপ করা হয় যা নিম্নলিখিত ঘটনাক্রম সহ মোট অতিবাহিত সময়কে প্রতিনিধিত্ব করে:

  • প্রক্রিয়াটি চালু করা হচ্ছে।
  • অবজেক্টগুলো প্রারম্ভিকীকরণ করা হচ্ছে।
  • অ্যাক্টিভিটিটি তৈরি এবং প্রারম্ভিকীকরণ করা হচ্ছে।
  • লেআউটটি স্ফীত করা হচ্ছে।
  • প্রথমবারের মতো অ্যাপটি আঁকছি।

TTID পুনরুদ্ধার করুন

TTID খুঁজে পেতে, Logcat কমান্ড-লাইন টুলে ' Displayed নামক ভ্যালু সম্বলিত একটি আউটপুট লাইন অনুসন্ধান করুন। এই ভ্যালুটিই হলো TTID এবং এটি দেখতে নিচের উদাহরণের মতো, যেখানে TTID হলো 3s534ms:

ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms

অ্যান্ড্রয়েড স্টুডিওতে TTID খুঁজে পেতে, আপনার Logcat ভিউ-এর ফিল্টার ড্রপ-ডাউন থেকে ফিল্টারগুলি নিষ্ক্রিয় করুন এবং তারপরে চিত্র ৫-এ দেখানো অনুযায়ী Displayed time' খুঁজুন। ফিল্টারগুলি নিষ্ক্রিয় করা প্রয়োজন, কারণ এই লগটি অ্যাপ নিজে নয়, বরং সিস্টেম সার্ভার পরিবেশন করে।

চিত্র ৫. নিষ্ক্রিয় ফিল্টারসমূহ এবং লগক্যাটে Displayed মান।

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

কখনও কখনও Logcat আউটপুটের Displayed লাইনে মোট সময়ের জন্য একটি অতিরিক্ত ফিল্ড থাকে। উদাহরণস্বরূপ:

ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms (total +1m22s643ms)

এক্ষেত্রে, প্রথম সময় পরিমাপটি শুধুমাত্র সেই অ্যাক্টিভিটির জন্য করা হয় যা প্রথমে চালু হয়। total সময় পরিমাপ অ্যাপ প্রসেস শুরু হওয়ার মুহূর্ত থেকে শুরু হয় এবং এতে এমন অন্য কোনো অ্যাক্টিভিটিও অন্তর্ভুক্ত থাকতে পারে যা প্রথমে চালু হলেও স্ক্রিনে কিছু প্রদর্শন করে না। total সময় পরিমাপটি শুধুমাত্র তখনই দেখানো হয় যখন একক অ্যাক্টিভিটি এবং মোট চালু হওয়ার সময়ের মধ্যে কোনো পার্থক্য থাকে।

আমরা অ্যান্ড্রয়েড স্টুডিওতে লগক্যাট (Logcat) ব্যবহার করার পরামর্শ দিই, কিন্তু আপনি যদি অ্যান্ড্রয়েড স্টুডিও ব্যবহার না করেন, তাহলেও adb shell activity manager’ কমান্ড দিয়ে আপনার অ্যাপটি চালিয়ে TTID পরিমাপ করতে পারেন। এখানে একটি উদাহরণ দেওয়া হলো:

adb [-d|-e|-s <serialNumber>] shell am start -S -W
com.example.app/.MainActivity
-c android.intent.category.LAUNCHER
-a android.intent.action.MAIN

আগের মতোই Logcat আউটপুটে Displayed মেট্রিকটি দেখা যাচ্ছে। আপনার টার্মিনাল উইন্ডোতে নিম্নলিখিত বিষয়গুলো প্রদর্শিত হচ্ছে:

Starting: Intent
Activity: com.example.app/.MainActivity
ThisTime: 2044
TotalTime: 2044
WaitTime: 2054
Complete

-c এবং -a আর্গুমেন্টগুলো ঐচ্ছিক এবং এগুলো আপনাকে <category><action> নির্দিষ্ট করার সুযোগ দেয়।

সম্পূর্ণ প্রদর্শনে সময়

সম্পূর্ণ প্রদর্শনের সময় (TTFD) হলো ব্যবহারকারীর জন্য একটি অ্যাপকে ইন্টারেক্টিভ হতে যে সময় লাগে। অ্যাপের UI-এর প্রথম ফ্রেমটি প্রদর্শিত হতে যে সময় লাগে, সেইসাথে প্রাথমিক ফ্রেমটি প্রদর্শিত হওয়ার পরে অ্যাসিঙ্ক্রোনাসভাবে লোড হওয়া কন্টেন্টের সময়কেও এর অন্তর্ভুক্ত করা হয়। সাধারণত, অ্যাপ দ্বারা রিপোর্ট করা অনুযায়ী, এটি হলো নেটওয়ার্ক বা ডিস্ক থেকে লোড হওয়া প্রাথমিক কন্টেন্ট। অন্য কথায়, TTFD-এর মধ্যে TTID-এর পাশাপাশি অ্যাপটিকে ব্যবহারযোগ্য হতে যে সময় লাগে, তাও অন্তর্ভুক্ত থাকে। আপনার অ্যাপের TTFD কম রাখলে ব্যবহারকারীরা দ্রুত আপনার অ্যাপের সাথে ইন্টারঅ্যাক্ট করতে পারায় ইউজার এক্সপেরিয়েন্স উন্নত করতে সাহায্য করে।

যখন Choreographer অ্যাক্টিভিটির onDraw() মেথড কল করে এবং যখন সিস্টেমটি জানতে পারে যে এটি প্রথমবারের মতো কল করা হচ্ছে, তখন TTID নির্ধারণ করে। তবে, সিস্টেমটি জানে না কখন TTFD নির্ধারণ করতে হবে, কারণ প্রতিটি অ্যাপের আচরণ ভিন্ন। TTFD নির্ধারণ করার জন্য, অ্যাপটিকে সম্পূর্ণ অঙ্কিত অবস্থায় পৌঁছালে সিস্টেমকে সংকেত দিতে হয়।

TTFD পুনরুদ্ধার করুন

TTFD খুঁজে পেতে, ComponentActivity এর reportFullyDrawn() মেথডটি কল করে অ্যাপটির সম্পূর্ণ অঙ্কিত অবস্থা নির্দেশ করুন। reportFullyDrawn মেথডটি জানায় কখন অ্যাপটি সম্পূর্ণ অঙ্কিত এবং ব্যবহারযোগ্য অবস্থায় আছে। সিস্টেম যখন অ্যাপ চালুর ইনটেন্ট গ্রহণ করে, তখন থেকে reportFullyDrawn() কল হওয়া পর্যন্ত অতিবাহিত সময়ই হলো TTFD। আপনি যদি reportFullyDrawn() কল না করেন, তাহলে কোনো TTFD মান রিপোর্ট করা হবে না।

TTFD পরিমাপ করতে, UI এবং সমস্ত ডেটা সম্পূর্ণরূপে আঁকার পরে reportFullyDrawn() কল করুন। সিস্টেম দ্বারা পরিমাপ অনুযায়ী প্রথম অ্যাক্টিভিটির উইন্ডোটি প্রথমবার আঁকা এবং প্রদর্শিত হওয়ার আগে reportFullyDrawn() কল করবেন না, কারণ সেক্ষেত্রে সিস্টেম তার নিজের পরিমাপ করা সময় রিপোর্ট করে। অন্য কথায়, সিস্টেম TTID শনাক্ত করার আগে যদি আপনি reportFullyDrawn() কল করেন, তাহলে সিস্টেম TTID এবং TTFD উভয়কেই একই মান হিসাবে রিপোর্ট করে, এবং এই মানটিই হলো TTID মান।

যখন আপনি reportFullyDrawn() ব্যবহার করেন, Logcat নিম্নলিখিত উদাহরণের মতো একটি আউটপুট প্রদর্শন করে, যেখানে TTFD হলো 1s54ms:

system_process I/ActivityManager: Fully drawn {package}/.MainActivity: +1s54ms

Logcat আউটপুটে মাঝে মাঝে একটি total সময় অন্তর্ভুক্ত থাকে, যেমনটি 'Time to initial display' অংশে আলোচনা করা হয়েছে।

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

সাধারণ ক্ষেত্রে, যখন আপনি জানেন যে সম্পূর্ণ অঙ্কিত অবস্থা অর্জিত হয়েছে, তখন সেই অবস্থাটি জানানোর জন্য আপনি reportFullyDrawn() ব্যবহার করতে পারেন। তবে, যেসব ক্ষেত্রে সম্পূর্ণ অঙ্কিত অবস্থা অর্জিত হওয়ার আগেই ব্যাকগ্রাউন্ড থ্রেডগুলোকে তাদের কাজ শেষ করতে হয়, সেখানে আরও নির্ভুল TTFD পরিমাপের জন্য আপনাকে reportFullyDrawn() বিলম্বিত করতে হবে। কীভাবে reportFullyDrawn() বিলম্বিত করতে হয় তা জানতে, পরবর্তী বিভাগটি দেখুন।

স্টার্টআপ টাইমিংয়ের নির্ভুলতা উন্নত করুন

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

উদাহরণস্বরূপ, যদি UI-তে একটি ডাইনামিক লিস্ট, যেমন একটি RecyclerView বা লেজি লিস্ট থাকে, তবে এটি একটি ব্যাকগ্রাউন্ড টাস্ক দ্বারা পপুলেট করা হতে পারে যা লিস্টটি প্রথমবার ড্র হওয়ার পরে এবং ফলস্বরূপ, UI-টিকে সম্পূর্ণরূপে ড্র হওয়া হিসাবে চিহ্নিত করার পরে সম্পন্ন হয়। এই ধরনের ক্ষেত্রে, লিস্ট পপুলেশনের বিষয়টি বেঞ্চমার্কিং-এ অন্তর্ভুক্ত করা হয় না।

আপনার বেঞ্চমার্ক টাইমিংয়ের অংশ হিসেবে লিস্ট পপুলেশন অন্তর্ভুক্ত করতে, getFullyDrawnReporter() ব্যবহার করে FullyDrawnReporter টি নিন এবং আপনার অ্যাপ কোডে এতে একটি রিপোর্টার যুক্ত করুন। ব্যাকগ্রাউন্ড টাস্কটি লিস্ট পপুলেট করা শেষ করলে রিপোর্টারটি রিলিজ করুন।

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

নিম্নলিখিত উদাহরণটি দেখায় কিভাবে আপনি একই সাথে একাধিক ব্যাকগ্রাউন্ড টাস্ক চালাতে পারেন, যেখানে প্রতিটি তার নিজস্ব রিপোর্টার নিবন্ধন করে:

কোটলিন

class MainActivity : ComponentActivity() {

    sealed interface ActivityState {
        data object LOADING : ActivityState
        data object LOADED : ActivityState
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            var activityState by remember {
                mutableStateOf(ActivityState.LOADING as ActivityState)
            }
            fullyDrawnReporter.addOnReportDrawnListener {
                activityState = ActivityState.LOADED
            }
            ReportFullyDrawnTheme {
                when(activityState) {
                    is ActivityState.LOADING -> {
                        // Display the loading UI.
                    }
                    is ActivityState.LOADED -> {
                        // Display the full UI.
                    }
                }
            }
            SideEffect {
                fullyDrawnReporter.addReporter()
                lifecycleScope.launch(Dispatchers.IO) {
                    // Perform the background operation.
                    fullyDrawnReporter.removeReporter()
                }
                fullyDrawnReporter.addReporter()
                lifecycleScope.launch(Dispatchers.IO) {
                    // Perform the background operation.
                    fullyDrawnReporter.removeReporter()
                }
            }
        }
    }
}

জাভা

public class MainActivity extends ComponentActivity {
    private FullyDrawnReporter fullyDrawnReporter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        fullyDrawnReporter = getFullyDrawnReporter();
        fullyDrawnReporter.addOnReportDrawnListener(() -> {
            // Trigger the UI update.
            return Unit.INSTANCE;
        });

        new Thread(new Runnable() {
            @Override
            public void run() {
                fullyDrawnReporter.addReporter();
                // Do the background work.
                fullyDrawnReporter.removeReporter();
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                fullyDrawnReporter.addReporter();
                // Do the background work.
                fullyDrawnReporter.removeReporter();
            }
        }).start();
    }
}

আপনার অ্যাপে যদি Jetpack Compose ব্যবহৃত হয়, তাহলে সম্পূর্ণ অঙ্কিত অবস্থা নির্দেশ করতে আপনি নিম্নলিখিত API-গুলো ব্যবহার করতে পারেন:

  • ReportDrawn : নির্দেশ করে যে আপনার কম্পোজেবলটি ইন্টারঅ্যাকশনের জন্য অবিলম্বে প্রস্তুত।
  • ReportDrawnWhen : আপনার কম্পোজেবলটি কখন ইন্টারঅ্যাকশনের জন্য প্রস্তুত তা নির্দেশ করতে list.count > 0 এর মতো একটি প্রেডিকেট গ্রহণ করে।
  • ReportDrawnAfter : এটি একটি সাসপেন্ডিং মেথড গ্রহণ করে, যা সম্পন্ন হলে নির্দেশ করে যে আপনার কম্পোজেবলটি ইন্টারঅ্যাকশনের জন্য প্রস্তুত।
বাধাগুলি চিহ্নিত করুন

বাধাগুলো খুঁজে বের করার জন্য, আপনি অ্যান্ড্রয়েড স্টুডিও সিপিইউ প্রোফাইলার ব্যবহার করতে পারেন। আরও তথ্যের জন্য, ‘সিপিইউ প্রোফাইলার দিয়ে সিপিইউ কার্যকলাপ পরিদর্শন’ দেখুন।

আপনার অ্যাপ এবং অ্যাক্টিভিটির onCreate() মেথডের ভিতরে ইনলাইন ট্রেসিং-এর মাধ্যমেও আপনি সম্ভাব্য প্রতিবন্ধকতাগুলো সম্পর্কে ধারণা পেতে পারেন। ইনলাইন ট্রেসিং সম্পর্কে জানতে, Trace ফাংশনগুলোর ডকুমেন্টেশন এবং সিস্টেম ট্রেসিং-এর ওভারভিউ দেখুন।

সাধারণ সমস্যা সমাধান করুন

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

ভারী অ্যাপ প্রারম্ভিককরণ

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

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

অ্যাপ ইনিশিয়ালাইজেশনের সময় অন্যান্য চ্যালেঞ্জের মধ্যে রয়েছে প্রভাবশালী বা অসংখ্য গার্বেজ কালেকশন ইভেন্ট, অথবা ইনিশিয়ালাইজেশনের সাথে একই সময়ে ডিস্ক I/O ঘটা, যা ইনিশিয়ালাইজেশন প্রক্রিয়াকে আরও বাধাগ্রস্ত করে। ডালভিক রানটাইমের ক্ষেত্রে গার্বেজ কালেকশন বিশেষভাবে বিবেচ্য; অ্যান্ড্রয়েড রানটাইম (ART) একই সাথে গার্বেজ কালেকশন সম্পাদন করে, যা এই অপারেশনের প্রভাব কমিয়ে আনে।

সমস্যাটি নির্ণয় করুন

সমস্যাটি নির্ণয় করার জন্য আপনি মেথড ট্রেসিং বা ইনলাইন ট্রেসিং ব্যবহার করতে পারেন।

পদ্ধতি ট্রেসিং

সিপিইউ প্রোফাইলার চালালে দেখা যায় যে callApplicationOnCreate() মেথডটি অবশেষে আপনার com.example.customApplication.onCreate মেথডটিকে কল করে। যদি টুলটি দেখায় যে এই মেথডগুলোর এক্সিকিউশন শেষ হতে অনেক বেশি সময় লাগছে, তাহলে সেখানে কী কাজ হচ্ছে তা দেখতে আরও অনুসন্ধান করুন।

ইনলাইন ট্রেসিং

সম্ভাব্য দোষীদের তদন্ত করতে ইনলাইন ট্রেসিং ব্যবহার করুন, যার মধ্যে নিম্নলিখিতগুলি অন্তর্ভুক্ত:

  • আপনার অ্যাপের প্রাথমিক onCreate() ফাংশন।
  • আপনার অ্যাপ দ্বারা ইনিশিয়ালাইজ করা যেকোনো গ্লোবাল সিঙ্গেলটন অবজেক্ট।
  • বাধা সৃষ্টিকারী মুহূর্তে ঘটতে পারে এমন যেকোনো ডিস্ক I/O, ডিসিরিয়ালাইজেশন, বা টাইট লুপ।

সমস্যার সমাধান

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

এছাড়াও, Hilt-এর মতো একটি ডিপেন্ডেন্সি ইনজেকশন ফ্রেমওয়ার্ক ব্যবহার করার কথা বিবেচনা করুন, যা প্রথমবার ইনজেক্ট করার সময় অবজেক্ট এবং ডিপেন্ডেন্সি তৈরি করে।

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

ভারী কার্যকলাপ প্রারম্ভিককরণ

অ্যাক্টিভিটি তৈরি করতে প্রায়শই প্রচুর অতিরিক্ত কাজ করতে হয়। প্রায়শই, কর্মক্ষমতা উন্নত করার জন্য এই কাজটিকে অপ্টিমাইজ করার সুযোগ থাকে। এই ধরনের সাধারণ সমস্যাগুলোর মধ্যে নিম্নলিখিতগুলো অন্তর্ভুক্ত:

  • বৃহৎ বা জটিল লেআউট স্ফীত করা।
  • ডিস্কে স্ক্রিন ড্রয়িং বা নেটওয়ার্ক I/O ব্লক করা।
  • বিটম্যাপ লোড এবং ডিকোড করা।
  • VectorDrawable অবজেক্টগুলোকে রাস্টারাইজ করা।
  • কার্যক্রমের অন্যান্য উপ-সিস্টেমগুলোর প্রারম্ভিককরণ।

সমস্যাটি নির্ণয় করুন

এক্ষেত্রেও মেথড ট্রেসিং এবং ইনলাইন ট্রেসিং উভয়ই কার্যকর হতে পারে।

পদ্ধতি ট্রেসিং

সিপিইউ প্রোফাইলার ব্যবহার করার সময়, আপনার অ্যাপের Application সাবক্লাসের কনস্ট্রাক্টর এবং com.example.customApplication.onCreate() মেথডগুলোর দিকে মনোযোগ দিন।

যদি টুলটি দেখায় যে এই পদ্ধতিগুলো কার্যকর হতে দীর্ঘ সময় নিচ্ছে, তাহলে সেখানে কী কাজ হচ্ছে তা দেখতে আরও অনুসন্ধান করুন।

ইনলাইন ট্রেসিং

সম্ভাব্য দোষীদের তদন্ত করতে ইনলাইন ট্রেসিং ব্যবহার করুন, যার মধ্যে নিম্নলিখিতগুলি অন্তর্ভুক্ত:

  • আপনার অ্যাপের প্রাথমিক onCreate() ফাংশন।
  • এটি যেকোনো গ্লোবাল সিঙ্গেলটন অবজেক্টকে ইনিশিয়ালাইজ করে।
  • বাধা সৃষ্টিকারী মুহূর্তে ঘটতে পারে এমন যেকোনো ডিস্ক I/O, ডিসিরিয়ালাইজেশন, বা টাইট লুপ।

সমস্যার সমাধান

অনেক সম্ভাব্য প্রতিবন্ধকতা রয়েছে, কিন্তু দুটি সাধারণ সমস্যা ও তার প্রতিকার নিচে দেওয়া হলো:

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

কাস্টম স্প্ল্যাশ স্ক্রিন

আপনি যদি পূর্বে অ্যান্ড্রয়েড ১১ (এপিআই লেভেল ৩০) বা তার আগের সংস্করণে একটি কাস্টম স্প্ল্যাশ স্ক্রিন প্রয়োগ করার জন্য নিম্নলিখিত পদ্ধতিগুলির মধ্যে একটি ব্যবহার করে থাকেন, তাহলে স্টার্টআপের সময় অতিরিক্ত সময় যুক্ত হতে পারে:

  • লঞ্চের সময় সিস্টেম দ্বারা প্রদর্শিত প্রাথমিক ফাঁকা স্ক্রিনটি বন্ধ করতে windowDisablePreview থিম অ্যাট্রিবিউট ব্যবহার করা হয়।
  • একটি নির্দিষ্ট Activity ব্যবহার করে।

অ্যান্ড্রয়েড ১২ থেকে SplashScreen এপিআই (SplashScreen API)-তে স্থানান্তরিত হওয়া আবশ্যক। এই এপিআই দ্রুততর স্টার্টআপ টাইম সক্ষম করে এবং আপনাকে নিম্নলিখিত উপায়ে আপনার স্প্ল্যাশ স্ক্রিন পরিবর্তন করার সুযোগ দেয়:

এছাড়াও, কম্প্যাট লাইব্রেরিটি ব্যাকওয়ার্ড-কম্প্যাটিবিলিটি সক্ষম করতে এবং সমস্ত অ্যান্ড্রয়েড সংস্করণে স্প্ল্যাশ স্ক্রিন প্রদর্শনের জন্য একটি সামঞ্জস্যপূর্ণ চেহারা ও অনুভূতি তৈরি করতে SplashScreen এপিআই-কে ব্যাকপোর্ট করে।

বিস্তারিত জানতে স্প্ল্যাশ স্ক্রিন মাইগ্রেশন গাইডটি দেখুন।

{% হুবহু %} {% endverbatim %} {% হুবহু %} {% endverbatim %}