پایه برنامه‌ها

انتقال دادن دو دهه برنامه Google Play به Jetpack Compose

بلندگو

  • Kirill Grouchnikov

    مهندس نرم‌افزار

  • Jon Boekenoogen

    مهندس نرم‌افزار

درباره

درباره سخنرانی

امسال، Android رسماً برای ساختن همه واسط‌های کاربر به Compose-first تبدیل شد و «نماهای» قدیمی را در حالت نگهداری قرار داد. برای Google Play، این سفر در سال ۲۰۲۰ آغاز شد. در طول یک ردپای مهندسی که نزدیک به دو دهه و میلیاردها کاربر را دربرمی‌گیرد، مهاجرت به Jetpack Compose ازطریق رویه‌های برتر اثبات‌شده، همکاری نزدیک با تیم اصلی Compose، و تکامل مداوم ابزارها حاصل شد.

ببینید چگونه مدرن‌سازی Google Play با Compose باعث بهبودهای قابل‌اندازه‌گیری در سرعت و پایداری بلندمدت شد. این جلسه به بررسی اتصال گردش‌های کاری طراحی Figma عامل‌گرا با پیاده‌سازی Compose، خودکارسازی کیفیت برای جلوگیری از ترکیب‌بندی‌های مجدد غیرضروری، و ساخت رابط‌های گویا با رنگ پویا، تایپوگرافی غنی، و شکل‌های لایه‌بندی‌شده می‌پردازد. در پایان این جلسه، با استراتژی‌های آزمایش‌شده برای اولویت‌بندی سریع‌تر اشکال‌ها و مقیاس‌بندی مطمئن انتقال Compose خود آشنا خواهید شد.

خلاصه

  • ‫Google Play طی شش سال، ۹۷٪ از ظهورهای کاربر را به صفحه‌های فقط Compose منتقل کرد. صفحه‌های اصلی نیز در ۱۴ ماه گذشته شاهد بهبود ۳۰ درصدی در نرخ پرش بودند.
  • پذیرش تدریجی خطرات کسب‌وکار را در پایگاه‌های کد بزرگ کاهش می‌دهد. تیم‌ها می‌توانند ابتدا در صفحه‌های کم‌ترافیک آشنایی ایجاد کنند، سپس به‌سمت میزبانی ComposeView مستقیماً در ریشه «فعالیت» پیش بروند.
  • موضوع‌بندی پویا کاملاً در کد بااستفاده از رونهادهای MaterialTheme و کتابخانه Material Color Utilities کار می‌کند. این کار از تخریب «فعالیت» جلوگیری می‌کند، هرچند تولید آرایش رنگ‌ها در زمان ساخت به محدود کردن تأخیر زمان اجرا کمک می‌کند.
  • جریان داده یک‌سویه و میانای کاربری اعلانی معماری را ساده می‌کند و چندین نوع شرایط رقابتی را حذف می‌کند. اجرای موازی منابع داده و تبدیل‌های واسط کاربر، تأخیر بارگیری Google Play را ده‌ها میلی‌ثانیه بهبود بخشید.
  • بررسی‌های خودکار Lint کیفیت کد و قوانین سیستم طراحی را اعمال می‌کنند. Play از آن‌ها برای مسدود کردن رنگ‌های کدگذاری‌شده و پرچم‌گذاری مشکلات احتمالی عملکرد مانند BoxWithConstraints استفاده می‌کند.

Gemini Notebook

موضوع

  • jetpack-compose
  • انتقال
  • عملکرد
  • موضوع‌بندی
  • unidirectional-data-flow
  • lint-rules
  • developer-velocity

آوانویسی

معرفی و پذیرش «فروشگاه Google Play»

  • به همه خوش‌آمد می‌گویم!

  • نام من جان است.

  • من از تیم «فروشگاه Google Play» به شما ملحق می‌شوم.

  • این همکارم کیریل است.

  • امروز اینجا هستیم تا درباره نحوه انتقال کدهای زیادی از سیستم View و Fragment به Compose صحبت کنیم.

  • بیایید شروع کنیم.

  • خب، این پذیرش چطور پیش رفت و مقیاس آن چقدر بود؟

  • بنابراین برای، برای پایگاه کد برنامه ما، واقعاً از حدود سال ۲۰۰۷ به‌طور طبیعی رشد کرده است.

  • ما بیش‌از چند میلیون خط کد تولید، ۲۰۰ صفحه، و ۵۰۰ مؤلفه واسط کاربر منحصربه‌فرد داریم که در بسیاری از این صفحه‌های مختلف استفاده می‌شوند.

  • در سال ۲۰۲۰، تصمیم گرفتیم، می‌دانید، سرعت، قابلیت اطمینان، و عملکرد توسعه‌دهنده به اهدافی که می‌خواستیم نمی‌رسید.

  • بنابراین تصمیم گرفتیم از پشته فناوری واسط کاربر مدرن استفاده کنیم.

  • ما تعدادی کتابخانه مختلف را ارزیابی کردیم.

  • همچنین در آن زمان چند دوست در AndroidX داشتیم که درباره Compose با ما صحبت می‌کردند و تصمیم گرفتیم Compose را بپذیریم و اولین شریک اصلی Compose شویم.

  • چطور بود؟

  • شش سال بعد، اکنون ۹۷٪ از ظهورهای کاربر در برنامه «فروشگاه Play» در صفحه‌های فقط Compose است.

  • همه، متأسفم، همه توسعه‌های تلفن و صفحه‌نمایش بزرگ از سال ۲۰۲۰ به Compose-only منتقل شده‌اند.

  • و حتی ضریب‌های شکل گسترده ما، واقعیت گسترده، TV،‏ Auto،‏ Wear، از سال ۲۰۲۵ به Compose منتقل شده‌اند.

  • و Compose واقعاً حامی قدرتمندی برای این موفقیت بوده است و به همین دلیل است که ما همچنان به استفاده بیشتر و بیشتر از آن ادامه داده‌ایم.

  • آن‌ها مجموعه آزمون بسیار قوی و جامعی داشتند که به ما کمک کرد دو بار در هفته نسخه‌های جدید Compose را اتخاذ کنیم.

  • با استفاده از نسخه‌های آلفا و APIهای جدید آن‌ها، می‌توانیم از رفع اشکال‌های جدید و بهبودهای عملکردی جدید بهره‌مند شویم و برخی از آن APIهای جدید را واقعاً کاوش کنیم و تجربه‌های کاربری جدیدی ارائه دهیم.

  • به‌ویژه ازنظر عملکرد، Compose واقعاً عملکردی بدون وقفه برای برنامه ما در همه صفحه‌های اصلی ارائه کرده است.

  • این صفحه نتایج جستجو، صفحه اصلی، صفحه جزئیات است.

  • این‌ها سنجه‌های بسیار مهمی برای کسب‌وکار ما و همچنین برای تجربه کاربری ما هستند: عملکرد، لرزش، و تأخیر بارگیری.

  • بنابراین، در ۱۴ ماه گذشته شاهد بهبود ۳۰ درصدی بوده‌ایم.

طرح انتقال

  • اما چطور به اینجا رسیدیم؟

  • این همان چیزی است که ما واقعاً اینجا هستیم تا درباره آن صحبت کنیم.

  • پس بیایید درباره طرح انتقال صحبت کنیم.

  • بنابراین، Play رویکردی چندمرحله‌ای اتخاذ کرد.

  • نمی‌خواستیم یک‌باره وارد شویم و به‌اصطلاح همه تخم‌مرغ‌هایمان را در یک سبد بگذاریم.

  • درنهایت چند گام برداشتیم تا خطرات را درک کنیم، ببینیم چگونه بر کسب‌وکار ما تأثیر می‌گذارد، و واقعاً قبل‌از اینکه کاملاً وارد شویم، اعتماد ایجاد کنیم.

  • بنابراین، من این‌ها را نام‌گذاری می‌کنم: خزیدن، راه رفتن، آهسته دویدن، و دویدن.

  • بنابراین، مرحله مقدماتی برای ما واقعاً درباره آشنایی با Compose بود.

  • با صفحه‌ای با ترافیک کم شروع کردیم.

  • این می‌تواند صفحه تنظیمات، پروانه‌های طرف سوم، و چیزهایی از این قبیل باشد.

  • هدف اصلی شما آشنایی با کتابخانه Compose است.

  • بنابراین این می‌تواند عادت کردن به ردیف‌ها، ستون‌ها، نوشتار، تصاویر، و همه این نوع چیزها باشد.

  • و سپس باید شروع به آوردن تمام زیرساخت‌های برنامه خود کنید و نحوه عملکرد آن را به روش Compose درک کنید.

  • این می‌تواند ثبت ظهور، ثبت کلیک، زمینه‌سازی باشد، ما درحال بازسازی بارگیری داده‌ها به‌طور هم‌زمان بودیم.

  • بنابراین، همه این موارد.

  • و یک چیز خاص که برای ما مفید بود این بود که مطمئن شویم همه صفحه‌های ما یکسان به‌نظر می‌رسند، ما چند آزمایش واحد و آزمایش کارکردی ساختیم تا بررسی کنیم که اشیای زمینه‌سازی ما در Compose مستقیماً به سبک‌های XML، تایپوگرافی، رنگ‌ها، و همه این چیزها نگاشت شده‌اند.

  • بنابراین وقتی کمی آشنایی پیدا کردیم و احساس راحتی کردیم، تصمیم گرفتیم به پیاده‌روی برویم.

  • این کار برای ما به‌معنای برداشتن مؤلفه‌ای کوچک‌تر در صفحه‌ای با ترافیک بسیار بالا و ارزیابی ظاهر آن نوع انتقال بود.

  • توصیه می‌کنیم موردی را که در RecyclerView است انتخاب کنید تا بتوانید هرگونه مشکل سازگاری بین View و سیستم Compose را درک کنید و همچنین عملکرد اندازه‌گیری و پرش را درطول مسیر مشاهده کنید.

  • خود مؤلفه لازم نیست خیلی پیچیده باشد، اما واقعاً می‌خواهید چیزی داشته باشید که چیدمان‌ها را تمرین کند، و می‌دانید، نوشتار، تصاویر، این نوع چیزها، چند نمونه مختلف از آنچه معمولاً می‌بینید.

  • چیزی که باید مراقب آن باشید و احتمالاً در این ناحیه انتظارش را داشته باشید، کمی افزایش در تأخیر و لرزش است، این افزایش جزئی خواهد بود، اما دلیل آن این است که اکنون دو پشته را اجرا می‌کنید.

  • یک پشته پردازشی دارید که کاملاً در Compose است و یک پشته پردازشی که در Views است.

  • بنابراین، مقداری کوبش حافظه، مقداری بارگذاری کلاس اضافی، و همه این چیزها وجود خواهد داشت.

  • اما با استفاده بیشتر و بیشتر از Compose، این مشکل برطرف خواهد شد.

  • و اگر واقعاً در این مدت به آن نیاز دارید، می‌توانید کمی آن صفحه را ازقبل گرم کنید تا به هم‌راستا شدن آن کمک کنید و این هزینه را در کوتاه‌مدت کاهش دهید.

  • بنابراین بعداز پیاده‌روی، به نرم‌دوی می‌رویم.

  • این زمانی است که ما خیلی خیلی راحت شده‌ایم.

  • به‌جای انجام یک مؤلفه در صفحه پرترافیک، کل صفحه پرترافیک را انجام دهید.

  • بنابراین کاری که در این مورد انجام دادیم این بود که همچنان کتابخانه پیمایش را حفظ کردیم و از Fragment استفاده کردیم، اما برای هر صفحه جداگانه، به‌طور کامل در Compose پیاده‌سازی شد.

  • ما فقط Fragment را داشتیم که خود ComposeView را برمی‌گرداند.

  • بنابراین، آنچه می‌توانید انتظار داشته باشید بهبود تأخیر و لرزش است.

  • دیگر با آن مشکل کوبش حافظه و بار کردن کلاس که درباره‌اش صحبت می‌کردم مواجه نمی‌شوید.

  • و خود Compose نیز سطوحی از ذخیره‌سازی موقت را در سطح ComposeView انجام می‌دهد.

  • بنابراین اگر RecyclerView با تعدادی کارت دارید که یکسان به‌نظر می‌رسند و ممکن است نمادهای یکسانی داشته باشند، همه آن تجزیه نماد و استفاده از منابع بین همه چیز در ComposeView مشترک است.

  • بنابراین بعداز آن، به دویدن روی آوردیم.

  • اینجا است که واقعاً با تمام وجود روی آن تمرکز می‌کنید.

  • وقتی بیشتر ترافیک برنامه‌تان را در Compose داشتید، یک سطح بالاتر رفتیم.

  • بنابراین، در بالای صفحه‌ها، «فعالیت» را داریم.

  • بنابراین ComposeView را به ریشه Activity منتقل کنید.

  • و بخش زیادی از کد شما نسبتاً مشابه خواهد بود.

  • هنوز در تلاشید دستورالعمل ناوبری را انجام دهید که می‌خواهید بگویید، از یک صفحه به صفحه دیگر بروید.

  • اما به‌جای انجام تراکنش‌های Fragment، شما یک تابع Composable را فراخوانی می‌کنید.

  • و می‌توانید این کار را روی کتابخانه Nav2 یا کتابخانه Nav3 انجام دهید، هرکدام را که انتخاب کنید.

  • برای ما، همه صفحه‌هایمان منتقل نشده بود.

  • گفتم که تعداد زیادی از آن‌ها را داریم.

  • بنابراین ما سازگاری Fragment را ایجاد کرده بودیم که در آن می‌توانید صفحه‌ای مبتنی بر Fragment داشته باشید و از پوشاننده‌های AndroidFragment در Compose برای انجام این کار استفاده کنید.

  • آنچه می‌توانید انتظار داشته باشید، بازهم، بازهم، لرزش و تأخیر برای کسب‌وکار ما مهم است، بنابراین ما همچنان به پیشبرد این مرزها ادامه می‌دهیم و شما همچنان شاهد بهبود آن خواهید بود زیرا اکنون ما حافظه پنهان را در سراسر صفحه‌ها داریم و مشکل کوبش حافظه بسیار کمتر شده است.

  • اما قابلیت‌های جدیدی نیز دریافت می‌کنید.

  • نمونه‌ای از آن را در سمت راست این GIF داریم که در آن می‌توانید انتقال‌های عنصر مشترک را بین صفحه‌ها انجام دهید.

  • بنابراین تصویری داریم که وقتی از صفحه‌ای به صفحه دیگر می‌روید، آن را بزرگ می‌کنیم و این کار باعث ایجاد تداوم می‌شود.

  • همچنین می‌توانید از تمام انعطاف‌پذیری پویانمایی Compose درحین انجام کل آن انتقال استفاده کنید.

  • و با این مقدمه، ادامه بحث را به کیریل می‌سپارم تا درباره قابلیت‌های بیشتر صحبت کند.

زمینه و عملکرد

  • متشکرم، جان.

  • می‌خواهم کمی درباره موضوعی صحبت کنم که برایم بسیار مهم و عزیز است، یعنی تم‌گذاری و سبک‌دهی برای برنامه‌های Android، کاری که مدتی است انجام می‌دهم.

  • در دنیای View، کد Java و کمی بعد کد Kotlin وجود داشت، و سپس منابع X-- XML، منابعی مانند رنگ‌ها، رشته‌ها، ابعاد، چیدمان‌ها، و زمینه‌ها و سبک‌ها وجود داشتند.

  • و نحوه عملکرد آن به این صورت بود که همه این منابع XML در یک جدول منبع که در APK گنجانده شده بود کامپایل می‌شدند و تقریباً ایستا بود.

  • یک میانای برنامه‌سازی کاربردی Resources.Theme.applyStyle وجود داشت که می‌توانستید به‌طور پویا در زمان اجرا از آن برای اعمال سبک سفارشی در بالای سلسله‌مراتب واسط کاربر استفاده کنید.

  • محدودیت اصلی این بود یا هست که باید این کار را قبل‌از گسترش محتوای خود انجام دهید، به این معنی که اگر می‌خواهید آن سبک را به‌طور پویا روی یک قطعه موجود از واسط کاربر اعمال کنید، باید کل «فعالیت» را ازبین ببرید و دوباره ایجاد کنید، که برای تجربه کاربری خوب نبود.

  • همچنین، چون این بلوک‌های XML پیش‌کامپایل‌شده را اعمال می‌کرد، ترکیب چندین هم‌پوشانی پویای شرطی روی یکدیگر براساس پرچم‌های آزمایش یا هر نیاز تجاری دیگری تا حدودی دشوار می‌شد.

  • ساختن یک مدل ذهنی مناسب از سلسله‌مراتب سبک در آن دنیای XML تاحدی دشوار بود.

  • و درنهایت، هیچ نمای واحد و یکپارچه‌ای در Android Studio یا هر ابزار توسعه دیگری وجود نداشت که به شما اجازه دهد شکاف بین دنیای Java، دنیای کد، و دنیای XML را پر کنید.

  • And it was kind of like difficult to juggle and build the proper mental model and debug why my style is not getting applied, why am I getting the wrong color, and so on.

  • در دنیای جدید، در دنیای Compose، به‌ویژه برای سیستم «طراحی مواد» و کتابخانه Compose Material، و همچنین برای سایر سیستم‌های طراحی موجود، آنچه داریم برای سیستم «طراحی مواد» است، ما یک MaterialTheme Composable داریم که شما آن را در بالاترین سطح سلسله‌مراتب واسط کاربر خود در صفحه‌نمایش اعمال می‌کنید، و همچنین می‌توانید این MaterialTheme را به‌عنوان یک هم‌پوشانی روی هر بخش کوچک‌تری از واسط کاربر خود اعمال کنید.

  • اگر به صفحه سمت راست نگاه کنید، می‌توانید این Play Points Gold را در بالا ببینید، که یک کارت کوچک در اینجا با نشانگر پیشرفت و چند متن است.

  • ما این پوشش «زمینه Material» را با آرایش رنگ‌های سفارشی تولیدشده توسط کتابخانه «ابزارهای کمکی رنگ Material» اعمال می‌کنیم که در GitHub برای استفاده شما دردسترس است.

  • ما چیزی شبیه به این رنگ قهوه‌ای، زرد، طلایی را به‌عنوان رنگ پایه وارد می‌کنیم و این رنگ طیف کاملی از نشان‌های رنگی Material، اصلی روی اصلی، فرعی روی فرعی، را تولید می‌کند که سپس در پیاده‌سازی این کارت استفاده می‌کنیم.

  • و این امر قابلیت کامل زمینه‌سازی پویا را دراختیار توسعه‌دهندگان Android قرار می‌دهد.

  • همه این‌ها در کد انجام می‌شود، همه این‌ها در Kotlin انجام می‌شود، یعنی ساختن مدل ذهنی مناسب از نحوه عملکرد همه این‌ها بسیار آسان‌تر است و اشکال‌زدایی آن بسیار آسان‌تر است.

  • و به‌طور داخلی، این هم‌پوشانی‌ها به‌عنوان ترکیب‌بندی‌های محلی به گره‌های واسط کاربر خاص در سلسله‌مراتب شما، جایی که انتخاب می‌کنید آن‌ها را اعمال کنید، متصل می‌شوند.

  • ملاحظات عملکرد: تولید آرایش رنگ‌ها کامل با کتابخانه Material Color Utilities رایگان نیست.

  • این کار با سربار خاصی همراه است.

  • بنابراین، اگر چیزی به‌اندازه کافی پیچیده دارید که به چند مورد از این‌ها نیاز دارد، نوعی جعبه بنتو، یا هر چیز دیگری که ممکن است باشد، بسته به نیازهای محصولتان، و چندین آرایش رنگی دارید که در زمان اجرا تولید می‌کنید، این شروع به افزایش می‌کند، این شروع به افزایش تأخیر و لرزش می‌کند.

  • بنابراین، الف، می‌خواهید اندازه‌گیری کنید که این موضوع چگونه بر عملکرد شما تأثیر می‌گذارد، و ب، می‌توانید بخشی از این سربار را از زمان اجرا به زمان ساخت منتقل کنید.

  • می‌توانید از همان کتابخانه Material Color Utilities در زمان ساخت استفاده کنید تا آن طرح‌های رنگی را براساس نیازهای نمانام‌سازی یا نیازهای محصولتان ازپیش تولید کنید و این سربار را به زمان ساخت منتقل کنید.

  • برای آن دسته از CompositionLocalهایی که اشاره کردم که دقیقاً مکان هم‌پوشانی‌ها را در درخت سلسله‌مراتب میانای کاربری ردیابی می‌کنند، این‌ها بسیار ارزان‌تر هستند، اما هنوز رایگان نیستند.

  • بنابراین، بسته به اینکه از چندتا از آن‌ها استفاده می‌کنید، ده‌ها، صدها، شروع به جمع شدن می‌کند.

  • و در نقطه‌ای، می‌خواهید شروع به بررسی هزینه همه این ترکیب‌بندی‌های محلی ترکیبی کنید.

  • و این نمونه‌ای از چیزی است که به آن اشاره می‌کردم، یعنی قابلیت‌های زمینه‌سازی زمان اجرای پویای واقعی Compose.

  • در اینجا چهار ربع داریم، همان تصاویر، همان چیزی که بیایید آن را کارت رویداد بنامیم.

  • ما این تصویر اصلی را داریم که کل کارت را دربرمی‌گیرد، و سپس یک برچسب در بالا سمت راست، یک دکمه در پایین سمت چپ، و چند نوشتار داریم.

  • و در سمت راست هریک از ربع‌ها، فراخوانی نشان‌های رنگی را می‌بینید که به‌عنوان مشخصات طراحی برای هریک از عناصر استفاده می‌شوند.

  • پیاده‌سازی کارت برای هر چهار مورد دقیقاً یکسان است.

  • تنها تفاوت این است که روکش «زمینه Material» که کارت را دربرمی‌گیرد با آرایش رنگ‌ها که به‌طور پویا براساس رنگ غالب تصویر (آبی، بنفش، زرد، و قرمز) ایجاد شده است تولید یا پیکربندی می‌شود.

  • همه چیزهای دیگر ثابت می‌ماند.

  • لازم نیست فعالیتتان را ازبین ببرید و دوباره ایجاد کنید.

  • می‌توانید آن را به‌صورت مشروط براساس پرچم‌های آزمایشی خود یا هر نیاز تجاری دیگری اعمال کنید.

  • و همان‌طور که قبلاً گفتم، این روشی بسیار پویاتر، واقعاً پویاتر، برای اعمال سفارشی‌سازی‌های رنگ در برنامه شما است.

  • و اکنون برای بخش بعدی به جان برمی‌گردیم.

مقیاس‌بندی قابلیت اطمینان و سرعت

  • آره.

  • بنابراین، این انعطاف‌پذیری بیشتری است که کیریل درباره آن صحبت می‌کرد.

  • بیایید درباره قابلیت اطمینان و سرعت صحبت کنیم.

  • بنابراین، ساختن سریع کد با کیفیت بالا چیزی است که همه توسعه‌دهندگان و کسب‌وکارها به‌دنبال آن هستند.

  • بنابراین، بیایید ببینیم Compose چگونه به Play کمک کرد تا این کار را انجام دهد.

  • بنابراین، اول از همه، می‌دانم که نمودار بزرگی است، اما سادگی معماری مزایای بسیار زیادی برای همه نویسندگان و نگهدارندگان کد، چه انسان‌ها و چه عامل‌ها، دارد.

  • نمی‌خواهم خیلی عمیق به این موضوع بپردازم، اما یکی از چیزهای مدل ذهنی که Compose سعی می‌کند ارائه دهد، جریان داده یک‌سویه است و واقعاً تأثیر زیادی روی تیم ما داشته است.

  • برای کسانی که با نحوه عملکرد آن آشنا نیستند، اصول اولیه این است که شما یک منبع داده دارید.

  • منبع داده، داده‌ها را ارائه می‌دهد.

  • این داده‌ها ممکن است به یک واسط کاربر خاص تبدیل شوند که ما آن را به‌عنوان یک مدل واسط کاربر خروجی می‌دهیم.

  • و سپس Compose می‌تواند به‌راحتی آن را با فراخوانی ویژگی مقدار در آن وضعیت مشاهده کند.

  • این نوعی از پیکان‌ها در امتداد سمت بالای این نمودار است.

  • و سپس رویدادها در جهت مخالف جریان می‌یابند.

  • بنابراین، اگر کاربر روی دکمه‌ای کلیک کند، این عمل به تبدیل‌کننده میانای کاربری برمی‌گردد، منبع داده را به‌روز می‌کند، مقدار جدیدی صادر می‌کند، تبدیل‌ها اجرا می‌شوند، و این چرخه تکرار می‌شود.

  • بنابراین همه چیز ازطریق این حلقه نسبتاً ساده اجرا می‌شود.

  • مزایایی که واقعاً از این کار دیده‌ایم این است که به کاهش زمان آماده‌سازی کمک می‌کند.

  • دیگر این‌طور نیست که همه این فراخوانی‌ها در رشته اصلی یا خارج از این رشته‌های دیگر اتفاق بیفتد.

  • این فرایند از یک حلقه کلی پیروی می‌کند.

  • Compose مشاهده داده‌ها را بسیار ساده می‌کند و داده‌ها در لایه‌های معماری از تضمین‌های سازگاری قوی برخوردارند.

  • مدل ذهنی بسیاری از مکالمات درباره منابع حقیقت را در تیم ما کاهش داده و چندین نوع شرایط رقابتی را به‌طور کامل حذف کرده است.

  • مزیت بزرگ دیگر برای ما این است که در مقایسه با معماری قبلی مدل-نما-کنترل‌کننده که داشتیم، اجرای موازی منابع داده و تبدیل‌های واسط کاربر بسیار بسیار ساده شد.

  • بنابراین، این کار واقعاً تأخیر بارگیری ما را در «فروشگاه» بهبود بخشید، مثلاً حدود ۵۰ میلی‌ثانیه یا چیزی شبیه به آن.

  • برای ما خیلی جالب بود.

  • درکنار جریان داده یک‌سویه، طرفدار بزرگ دیگر Compose حول رابط کاربری اعلانی است.

  • کیریل کمی به این موضوع اشاره کرد.

  • بنابراین، توسعه‌دهندگان Play نیز واقعاً از این موضوع لذت برده‌اند.

  • جریان کنترل میانای کاربر اکنون در یک فایل است.

  • در سمت چپ نمونه‌ای داریم که نسبتاً ساده است.

    @Composable
    fun PurchaseRow(onClick: () -> Unit, modifier: Modifier) {
      Row(modifier) {
        Text("20% off sale")
        if (LocalExpts.current.useButtonV2) {
          ButtonV2("Buy", onClick = onClick)
        } else {
          ButtonV1("Buy", onClick = onClick)
        }
      }
    }
  • درحال جابه‌جایی بین دو پیاده‌سازی دکمه براساس پرچم آزمایش هستیم.

  • به‌جای اینکه لازم باشد چندین فایل نمای یا مثلاً فایل‌های تکه‌ای و فایل‌های XML را بخوانید، فقط آن را از بالا به پایین می‌خوانید و این کار را بسیار ساده‌تر کرده است.

  • هزینه تودرتو کردن ترکیب‌شدنی‌ها نیز بسیار بسیار کمتر از سلسله‌مراتب‌های نمای تودرتو است و به ما اجازه می‌دهد تا کد خود را به‌طور طبیعی مرتب کنیم تا خواناتر شود، به‌جای اینکه نیاز باشد برای عملکرد بهتر، هر بخش کوچک را به‌سختی بهینه کنیم.

  • مزیت دیگری که دیده‌ایم این است که فراخوانی‌های برگشتی چرخه عمر بسیار ساده‌تر شده‌اند و تعداد مواردی که باید نگرانشان باشید کاهش یافته است.

  • بنابراین، به‌جای داشتن چرخه حیات نما، چرخه حیات قطعه، چرخه حیات فعالیت، شما اثر یک‌بار مصرف، اثر جانبی دریافت می‌کنید و بسته به جایی که آن را قرار می‌دهید، به روشی بسیار سازگار عمل می‌کند.

  • بنابراین، این مزیت بزرگی برای ما بوده است.

آماده‌سازی برای مدل‌های زبانی بزرگ

  • بنابراین، این دو تغییر معماری واقعاً زمینه را برای مدل‌های زبانی بزرگ از نظر من فراهم کردند و به آن امکان دادند تا کدهای با کیفیت بسیار بالا تولید کند.

  • و مطمئنم که بسیاری از شما احتمالاً این کار را با مدل زبانی بزرگ موردعلاقه‌تان امتحان کرده‌اید یا انجام داده‌اید.

  • ممکن است نماگرفتی بگیرید که با رنگ‌ها و تایپوگرافی حاشیه‌نویسی شده است و آن را وارد کنید و ببینید که می‌تواند ردیف‌ها، ستون‌ها، نوشتار، و دکمه‌ها را تولید کند و کار قابل‌قبولی انجام می‌دهد.

  • البته محدودیت‌هایی هم دارد.

  • و چیزی که Play واقعاً دیده این است که پایگاه کد شما را درک نمی‌کند، درست است؟

  • نمی‌داند چه مؤلفه‌هایی را قبلاً ساخته‌اید که باید دوباره از آن‌ها استفاده کند، نام‌های نشان طراحی را نمی‌داند.

  • این ابزار فقط رنگ‌ها و رشته‌های کدنویسی‌شده را به شما می‌دهد.

  • چه محتوایی باید از دستگاه باشد، چه محتوایی باید از سرور بیاید، یا چگونه مطمئن شوم که در استفاده از LazyList عملکرد خوبی دارد و فقط یک ستون بزرگ ایجاد نمی‌کند؟

  • بنابراین، کاری که برای رسیدگی به برخی‌از این موارد انجام داده‌ایم این است که آن نماگرفت‌ها را با کمی فراداده بیشتر حاشیه‌نویسی کرده‌ایم.

  • بنابراین، نام‌های واسط کاربر، کادرهای مرزبندی تا بدانیم مؤلفه‌ها کجا شروع و کجا تمام می‌شوند، نشان‌های طراحی برای نام‌های معنایی رنگ‌ها و تایپوگرافی، مهارت‌ها، و همچنین برخی پیام‌واره‌ها برای اینکه بگوییم این کجا قرار خواهد گرفت تا بتواند آن ملاحظات عملکردی را درنظر بگیرد.

  • و سپس فقط یک امضای تابع سطح بسیار بالا، تا بتوانید به آن بگویید چه محتوایی پویا و چه محتوایی ایستا است.

  • بنابراین، درنهایت به چیزی شبیه به آنچه قبلاً داشتیم می‌رسید، که به بعد منتقل می‌شود.

  • من جعبه‌های مرزی را در اینجا ندارم زیرا این کار باعث اضافه شدن نویز زیادی به نمودار می‌شود.

  • اما می‌توانید ببینید که آن رنگ‌های کدگذاری‌شده و نام‌های تایپوگرافی با عنوان بزرگ و روی سطح جایگزین می‌شوند.

  • نام مؤلفه‌ها را به‌وضوح علامت‌گذاری کرده‌ایم، مثل سرصفحه کارت و نشان نماد.

  • بنابراین، از این طریق، این موارد را می‌توان در پایگاه کد شما پیدا کرد.

  • و برای ما، می‌دانید، بسیاری از این‌ها از کتابخانه‌های طراحی مشترک نیز می‌آیند، که کیریل در یک دقیقه درباره آن صحبت خواهد کرد.

  • بنابراین، شما همیشه همه این‌ها را برچسب‌گذاری سفارشی نمی‌کنید.

  • آن را با امضای روشی مثل آنچه در پایین داریم، OfferCard، جفت می‌کنید و سپس می‌داند که عنوان، endDate، و تصویر همگی پویا هستند.

  • نباید آن‌ها را کدگذاری ثابت کنیم.

  • و همراه با آن نام‌های معنایی، اکنون می‌توانیم به همه آن کاربردهای رنگی مختلف که کیریل درباره آن‌ها صحبت می‌کرد جابه‌جا شویم.

  • و با این کار، کدهای بسیار بیشتری تولید می‌کنیم.

  • من می‌خواهم صحبت کنم و آن را به Kirill برگردانم تا درباره نحوه حفظ کیفیت صحبت کنیم.

خودکارسازی کیفیت

  • راست.

  • متشکرم، جان.

  • بنابراین، با ادامه این موضوع درباره LLM و توسعه با کمک عامل، ابتدا از سمت طراحی تجربه کاربری شروع می‌کنیم.

  • کاری که باید انجام دهید این است که، هر ابزار طراحی که انتخاب می‌کنید، شاید Figma، شاید چیز دیگری، باید یک الگوی مشترک داشته باشید که توسط همه طراحان استفاده می‌شود و دارای نشان‌های رنگ، نشان‌های تایپوگرافی، نشان‌های شکل از سیستم طراحی انتخابی شما باشد.

  • شاید Material باشد.

  • شاید سیستم طراح سفارشی شما باشد.

  • و به‌طور خاص برای نشان‌های رنگی، می‌خواهید این الگوها از پشتیبانی داخلی برای جابه‌جایی بین حالت روشن و تیره و جابه‌جایی بین حالت‌های کنتراست عادی، متوسط، و بالا که چند سال پیش در سطح Android معرفی شدند برخوردار باشند.

  • تا طراحان بتوانند به‌سرعت بین این ترکیب‌های مختلف جابه‌جا شوند و ببینند مشخصات طراحی‌شان چگونه به آن پاسخ می‌دهد.

  • سپس، وقتی که درحال نهایی شدن و تحویل به بخش پیاده‌سازی است، در آن خط لوله صادر کردن، می‌خواهید نوعی قابلیت داشته باشید تا ردیابی کنید که هر رنگ، هر عنصر تایپوگرافی، هر شکل از یک کد همسان استفاده می‌کند، به‌جای اینکه یک مقدار RGB کدگذاری‌شده، یا خانواده قلم کدگذاری‌شده، یا اندازه قلم کدگذاری‌شده باشد.

  • و درنهایت، چیزی که در مقیاس Google Play برای ما بسیار مفید بود، این است که ما نه ده‌ها، بلکه چند صد مؤلفه، خوشه، کارت، و محفظه داریم که در انواع صفحه‌هایی که داریم استفاده می‌شوند.

  • چیزی که برای ما مفید بود این بود که همه این‌ها را در یک مکان واحد، که ما آن را کاتالوگ مؤلفه می‌نامیم، پیگیری کنیم و سپس یک عامل سفارشی را روی آن کاتالوگ مؤلفه آموزش دهیم.

  • و جایی که مفید واقع می‌شود زمانی است که صفحه جدیدی را شروع می‌کنید، شاید یک مسیر کاربر جدید، شاید یک حوزه محصول جدید، و از آن کاوش‌های طراحی اولیه، شاید اسلایدها، شاید مشخصات Figma، می‌توانید آن را به آن عامل تغذیه کنید، و عامل کمک می‌کند تا به‌سرعت شناسایی شود که کدام مؤلفه‌ها ازقبل وجود دارند تا نیازی به طراحی مجدد و مشخص کردن مجدد آن‌ها نباشد، بنابراین نیازی به پیاده‌سازی مجدد آن‌ها از ابتدا نیست.

  • و این به طور قابل توجهی هزینه‌های طراحی و هزینه‌های اجرا را کاهش می‌دهد.

  • در بخش پیاده‌سازی، ما به‌شدت به قوانین اصلی و سفارشی Lint تکیه می‌کنیم.

  • A couple of core Lint rules that I want to call out are FrequentlyChangingValueDetector that helps identify sources of unnecessary recompositions, which can lead to latency and jank, and the other one is ScaffoldPaddingDetector for flagging cases where we use the Material Compose Scaffold composable, but ignore the incoming paddings.

  • این منبع تأخیر و لرزش نیست، اما در برخی موارد می‌تواند منجر به اشکال‌زدایی بسیار دشوار شود، مثلاً ناهماهنگی‌های چیدمان در موارد خاصی که مثلاً لبه‌به‌لبه است، یا تا شدن، باز شدن.

  • و درنهایت، BoxWithConstraints که با ملاحظات عملکردی خاصی همراه است.

  • ممکن است دو فریم طول بکشد تا همه چیز به‌درستی چیده شود.

  • ما آن را به‌طور کامل مسدود نمی‌کنیم، اما آن را به‌عنوان هشدار Lint پرچم‌گذاری می‌کنیم تا توسعه‌دهنده‌ای که روی آن صفحه خاص کار می‌کند بداند که انتخاب خاصی برای استفاده از BoxWithConstraints انجام می‌دهد، یا شاید بتواند از چیز دیگری برای آن طرح‌بندی خاص استفاده کند.

  • برای خودکارسازی زمینه‌سازی، دوباره، نشان‌های رنگ، نشان‌های نویسه‌نگاری، نشان‌های شکل.

  • ما یک قانون Lint داریم که استفاده از رنگ‌های کدگذاری‌شده و حروف‌چینی کدگذاری‌شده را مسدود می‌کند.

  • ما یک قانون Lint داریم که استفاده از مؤلفه‌های Material 2 را پرچم‌گذاری می‌کند.

  • ما فقط می‌خواهیم از Material 3، جدیدترین و بهترین، ازجمله مؤلفه‌های گویای جدیدی که سال گذشته و امسال معرفی شدند، استفاده کنیم.

  • ما می‌خواهیم یک قانون Lint سفارشی داشته باشیم که از خواندن رنگ‌ها توسط افراد، مثلاً از فایل‌های XML قدیمی، جلوگیری کند.

  • می‌خواهیم برای صفحه‌های جدید، Compose-first و Compose-only باشیم.

  • و، Text composables، به‌ویژه در سیستم طراحی Material، برای سبک و رنگ جایگزین دارند.

  • آن‌ها این را از رنگ محتوای محلی و تایپوگرافی محلی می‌خوانند، اما ما نمی‌خواهیم به آن تکیه کنیم.

  • می‌خواهیم هر نوشتار به‌طور عمدی از سبک خاص، سبک طرح حروف، و رنگ خاص مشخصات طراحی استفاده کند.

  • بنابراین، این یک قانون Lint است که ما داریم.

  • و آخرین مورد، در راستای ScaffoldPaddingDetector، ما یک قانون Lint سفارشی داریم که اعمال می‌کند هر تابع «ترکیب‌پذیر» که داریم از اصلاح‌کننده ورودی خود استفاده کند.

  • باز هم، برای جلوگیری از، مثلاً، می‌دانید، استفاده‌های جدید از قرار گرفتن نادرست، یا عدم احترام به پس‌زمینه ورودی، یا هر چیز دیگری که ممکن است باشد.

نتیجه‌گیری

  • و این‌ها سه نکته اصلی هستند که می‌خواهیم از این ارائه برداشت کنید.

  • اولین مورد این است که امروز، در پایان سال ۲۰۲۶، از نظر ما Compose یک جعبه‌ابزار واسط کاربر بالغ است که در مقیاس بزرگ اثبات شده است.

  • خود Android هم Compose-first است.

  • اوایل امسال در Google I/O اعلام کردیم که همه کتابخانه‌های میانای کاربر و همه جریان‌های عاملی Compose-first هستند.

  • و همان‌طور که جان قبلاً در ارائه اشاره کرد، خزیدن، راه رفتن، دویدن آهسته، و دویدن، پیشنهاد می‌کنیم که به‌صورت تدریجی مهاجرت کنید، به‌ویژه پایگاه‌های کد بزرگ، تا سرعت خود را برای جریان‌های توسعه‌دهنده و جریان‌های عاملی افزایش دهید.

  • و با این، از شما سپاس‌گزاریم که امروز وقتتان را با ما گذراندید، و چند دقیقه دیگر، من و جان بیرون خواهیم بود تا به هر سؤالی که دارید پاسخ دهیم.

  • و بازهم از وقتی که گذاشتید سپاس‌گزاریم.

کد

تکه‌کدها

قطعه Kotlin در ۱۶:۰۹ در «Scaling reliability and velocity»
@Composable
fun PurchaseRow(onClick: () -> Unit, modifier: Modifier) {
  Row(modifier) {
    Text("20% off sale")
    if (LocalExpts.current.useButtonV2) {
      ButtonV2("Buy", onClick = onClick)
    } else {
      ButtonV1("Buy", onClick = onClick)
    }
  }
}