Nghiên cứu điển hình

Cách các kỹ sư của Instagram Direct xây dựng cấu trúc giao diện người dùng gốc dựa trên AI bằng Jetpack Compose và giảm 33% chi phí mã thông báo cho mỗi phiên của tác nhân

11 phút đọc

Bài đăng này trên blog được viết với sự cộng tác của nhóm Meta

Instagram Direct là một trong những nền tảng cốt lõi trên Instagram, xử lý hàng tỷ tin nhắn của người dùng mỗi ngày. Sau nhiều năm lặp lại, nhóm đã tận dụng mọi điểm tối ưu hoá nhỏ nhất có thể trong hệ thống View cũ của Android. Tuy nhiên, việc duy trì và mở rộng một nền tảng cũ được tối ưu hoá cao sẽ tạo ra khoản nợ kỹ thuật và chi phí kỹ thuật đáng kể, đặc biệt là khi các nhóm ngày càng áp dụng giao diện người dùng khai báo và trợ lý lập trình AI. 

Việc áp dụng Jetpack Compose cho Instagram Direct không chỉ là một quá trình hiện đại hoá giao diện người dùng thông thường. Nhóm này đã tạo một cơ sở mã giao diện người dùng gốc dựa trên AI, có kích thước nhỏ hơn 50% so với quá trình triển khai ban đầu, đồng thời giảm 35% thời gian thực thi tác nhân AI, giảm 32% số lượt trao đổi giữa kỹ sư và tác nhân và giảm 33% chi phí mã thông báo. Trong quá trình hợp tác chặt chẽ với Google, nhóm đã áp dụng Jetpack Compose trong khi vẫn duy trì hiệu suất cao. Thông qua việc tối ưu hoá hiệu suất, Meta và Google đã cải thiện Compose không chỉ cho Instagram mà còn cho hệ sinh thái nhà phát triển Android nói chung.

Hiện đại hoá toàn bộ mã nguồn trên quy mô lớn

AI đã nhanh chóng trở thành người bạn đồng hành hằng ngày của các kỹ sư trong ngành, và việc áp dụng AI cho một toàn bộ mã nguồn quy mô lớn như Instagram đã mang lại những lợi ích thực sự về năng suất. Nhóm Instagram Direct đã đặt ra một mục tiêu tham vọng hơn. Thay vì chỉ sử dụng các công cụ AI cho mã hiện có, nhóm đã thiết kế lại cơ sở mã và cấu trúc của cơ sở mã để có thể sử dụng AI ngay từ đầu, nhờ đó tăng tác động của AI lên gấp nhiều lần so với việc chỉ điều chỉnh.

Nhóm Instagram Direct đã chọn Jetpack Compose làm một thành phần chính để xây dựng cấu trúc giao diện người dùng gốc dựa trên AI. Bản chất khai báo của Compose đảm bảo mã ngắn gọn, dễ đoán và dễ dàng hơn về cấu trúc để các mô hình AI suy luận, với ít tác dụng phụ hơn, ít trạng thái ngầm hơn và ranh giới thành phần rõ ràng hơn.

Việc di chuyển sang Jetpack Compose đòi hỏi phải lên kế hoạch cẩn thận. Mỗi ngày, có hàng trăm triệu người gửi tin nhắn trên Instagram. Vì vậy, quá trình di chuyển phải diễn ra từ từ, suôn sẻ và không làm gián đoạn trải nghiệm trong khi nhóm tái cấu trúc nền tảng bên dưới. Để minh hoạ quy mô của thách thức này: Các thành phần giao diện người dùng riêng lẻ có thể hiển thị trong hơn 160 cách bố trí trạng thái riêng biệt và chỉ riêng một màn hình trò chuyện đã xử lý hơn 200 loại tin nhắn riêng biệt.

Product Design 1.png

Khi di chuyển một cơ sở mã có kích thước như vậy sang Compose, bạn có thể muốn chọn cách dễ dàng nhất là nhúng các thành phần giao diện người dùng Compose vào hệ phân cấp Khung hiển thị hiện có. Đây là một bước gia tăng trong quá trình di chuyển dần dần, hoàn toàn hợp lệ. Tuy nhiên, về lâu dài, việc tích hợp Compose vào toàn bộ mã nguồn dựa trên Khung hiển thị sẽ gây ra một thách thức. Các công cụ AI thường chọn con đường ít trở ngại nhất. Nếu bạn kết hợp mã giao diện người dùng khai báo và mệnh lệnh, thì AI có thể kết hợp chúng không chính xác, gây ra các lỗi nhỏ, nợ kỹ thuật và sự suy giảm hiệu suất. 

Xây dựng cấu trúc giao diện người dùng gốc AI

Ở quy mô của Instagram, không thể tránh khỏi một mức độ trừu tượng kiến trúc và đó là điều giúp ứng dụng duy trì được khi phát triển. Hãy xem xét một mẫu phổ biến, trong đó mọi loại mục RecyclerView đều được mô hình hoá dưới dạng một thành phần con của lớp cơ sở RecyclerViewItem tuỳ chỉnh, hiển thị các hook vòng đời thông thường, chẳng hạn như onBind.

Ví dụ 1

class ChatItem(
  val features: FeatureFlagProvider
) : RecyclerViewItem<ComposeViewHolder, ChatUiState> {

  // Imperative context:
  // AI could often take the path of least resistance and generate a mutable
  // state here, dispatched outside the ChatUiState. This class survives
  // re-bindings and is shared across multiple items, ultimately leading to
  // unexpected, hard-to-reproduce bugs.
  var isPinned: Boolean = false

  override fun onBind(holder: ComposeViewHolder, uiState: ChatUiState) {
      // Imperative context
      val isPinnedChatsEnabled = features.isEnabled("pinned_chats_feature")

      // Declarative context
      holder.composeView.setContent {

        // Blending imperative and declarative contexts
        if (isPinnedChatsEnabled) {
          Button(onClick = { isPinned = !isPinned }) {
            Text(if (isPinned) "Unpin" else "Pin")
          }
        }
        
        ...
      }
  }
}


Trong đoạn mã trên, có 2 vấn đề xuất hiện. Trước tiên, cờ isPinnedChatsEnabled được đọc trong mã mệnh lệnh, sau đó được ghi lại bên trong một lambda Compose, một sự kết hợp tinh tế giữa các mô hình. Thứ hai, isPinned tồn tại dưới dạng một trường có thể thay đổi trên chính mục đó thay vì trong ChatUiState, vì vậy, nó vẫn tồn tại sau khi liên kết lại và tái chế RecyclerView trên các hàng, rò rỉ và tạo ra các lỗi khó tái tạo.

Ngay cả khi mã được dọn dẹp bằng cách cung cấp cho mục một hàm @Composable chuyên dụng, các vấn đề tương tự vẫn tồn tại.

Ví dụ 2

class ChatItem(
  val features: FeatureFlagProvider
) : ComposeRecyclerViewItem<ChatUiState> {

  // Imperative context
  val isPinnedChatsEnabled = features.isEnabled("pinned_chats_feature")
  var isPinned: Boolean = false

  // Declarative context
  @Composable
  override fun Content(uiState: ChatUiState) {

 
    // Blending imperative and declarative contexts
    if (isPinnedChatsEnabled) {
      Button(onClick = { isPinned = !isPinned }) {
        Text(if (isPinned) "Unpin" else "Pin")
      }
    }

    ...
  }
}

Đây là một ví dụ đơn giản có chủ ý, nhưng nó minh hoạ một vấn đề rộng hơn – AI càng có ít ranh giới thì chất lượng mã mà AI tạo ra theo thời gian càng thấp. Các biện pháp bảo vệ và kỹ năng hỗ trợ, nhưng chúng không đủ để tự mình giải quyết vấn đề, vì khi gặp trở ngại, AI thường sẽ tìm cách vượt qua để tự giải quyết.

Để toàn bộ mã nguồn thân thiện với AI (trí tuệ nhân tạo), toàn bộ mã nguồn đó cần tuân thủ 2 quy tắc thực tế: 

  • Giảm thiểu sự phụ thuộc vào bối cảnh tuỳ chỉnh. Càng cần nhiều kiến thức riêng biệt, cụ thể về cơ sở mã để thực hiện thay đổi chính xác, thì chất lượng đầu ra của một tác nhân AI càng thấp. Toàn bộ mã nguồn càng gần với các phương pháp hay nhất đã biết, thì kết quả AI (trí tuệ nhân tạo) càng tốt.
  • Toàn bộ mã nguồn ưu tiên AI phải thực thi các ranh giới của riêng nó. Việc vá các lỗ hổng thiết kế bằng kỹ năng AI không mang lại hiệu quả, vì mọi kỹ năng được tải vào ngữ cảnh đều tốn mã thông báo và có thể làm giảm hiệu suất của tác nhân. Thay vào đó, chính kiến trúc phải đảm nhận vai trò đó. Các tác nhân AI thường đi theo con đường ít trở ngại nhất, vì vậy, thiết kế phải đảm bảo con đường đó dẫn đến mã chính xác, chất lượng cao, đồng thời khiến việc thể hiện các quyết định thiết kế kém trở nên khó khăn và tốn kém.

Một mục trong danh sách vẫn có thể được biểu thị bằng chính thành phần trừu tượng của nó, nhưng trong trường hợp này, tất cả mã Compose đều nằm trong hàm khởi tạo, nên không có quyền truy cập vào các thành phần hoặc trạng thái của lớp và nguồn đối số duy nhất là hàm khởi tạo. Điều này tương đương với một hàm @Composable đơn giản, đồng thời tuân thủ cấu trúc hiện có.

Ví dụ 3

class ChatItem(
  val features: FeatureFlagProvider,
  val onPin: (Boolean) -> Unit,
) : ComposeItem<ChatUiState>(

 
   // Compose UI
   content = { uiState: ChatUiState ->
    val isPinnedChatsEnabled = features.isEnabled("pinned_chats_feature")

    if (isPinnedChatsEnabled) {
      Button(onClick = { onPin(!uiState.isPinned) }) {
        Text(if (uiState.isPinned) "Unpin" else "Pin")
      }
    }
    
    ...
  },
)

Việc di chuyển một cơ sở mã có kích thước như vậy là một việc rất lớn. Trong một thời gian dài, hàng trăm thành phần giao diện người dùng tạo nên phần lớn Giao diện người dùng trực tiếp đã phải cùng tồn tại với các thành phần tương đương cũ, cả hai đều được duy trì song song. Các quy trình làm việc dựa trên AI đã giúp quá trình di chuyển song song này diễn ra suôn sẻ bằng cách tăng tốc quá trình viết một lượng lớn mã. Nhờ cách tiếp cận đó, nhóm Direct đã thực hiện quá trình di chuyển trong thời gian kỷ lục mà không làm gián đoạn hoạt động của các thành viên còn lại trong nhóm. Họ vẫn tiếp tục phát hành các tính năng giúp cải thiện trải nghiệm của hàng triệu người dùng mỗi ngày.

Nhiều kỹ sư đã chạy các tác nhân AI của riêng họ dựa trên cơ sở kiến thức dùng chung về các kỹ năng và quy ước có thể tái sử dụng được xây dựng trong quá trình di chuyển. Điều này giúp các quy trình và phương pháp hay nhất luôn đồng bộ trong nhóm, thay vì mỗi kỹ sư phải tự tìm hiểu lại. Trong mỗi nền tảng, nhóm đã thực hiện quy trình di chuyển theo các giai đoạn sau:

  • Viết tất cả mã Compose bằng AI.
  • Tinh chỉnh, xử lý các trường hợp đặc biệt và khắc phục các vấn đề về hiệu suất cho đến khi giao diện người dùng được triển khai cho người dùng thực tế trong một kiểm thử công khai.

Việc chia công việc thành 2 giai đoạn cho mỗi màn hình giúp một kỹ sư nhanh chóng hoàn thành toàn bộ giao diện, giải quyết kiến trúc và các trường hợp khó ngay từ đầu. Khi có nền tảng đó, những người khác có thể tập trung vào việc chuẩn bị giao diện người dùng cho quá trình sản xuất mà không cần dừng lại để tự đưa ra những quyết định kỹ thuật đó, giúp quá trình di chuyển diễn ra nhanh chóng.

Kết quả của quá trình di chuyển đã xác thực phương pháp này. Đối với các nền tảng Instagram Direct được di chuyển, Jetpack Compose đã giúp nhóm giảm tổng lượng mã giao diện người dùng xuống 50%. Càng ít mã thì AI càng tạo ra kết quả đầu ra chất lượng cao hơn và chi phí mã thông báo cho mỗi tác vụ càng thấp hơn. 

Quote-Pavlo-New.jpg

Một phân tích dữ liệu nội bộ về toàn bộ mã nguồn Android cho Instagram Direct đã so sánh các phiên của tác nhân AI làm việc trên giao diện người dùng Compose với các phiên của tác nhân AI làm việc trên cùng một nhiệm vụ bằng cách sử dụng Khung hiển thị Android. Hiệu quả tăng lên rõ rệt ở 2 khía cạnh:

  • Theo từng ký tự của mã được tạo: Compose giúp giảm 32% số lần trao đổi giữa kỹ sư và nhân viên hỗ trợ và giảm 35% thời gian thực hiện của nhân viên hỗ trợ(thời gian trôi qua kể từ khi nhân viên hỗ trợ bắt đầu xử lý yêu cầu của kỹ sư cho đến khi trả lời).
  • Mỗi phiên của tác nhân: Tổng chi phí mã thông báo giảm 33% khi dùng Compose so với Views.

Chúng tôi báo cáo cả hiệu suất đầu ra và số phiên điển hình vì đây là những kết quả hữu ích độc lập. Các số liệu về thời gian trao đổi và thực thi của kỹ sư-tác nhân so sánh mức sử dụng tài nguyên trên mỗi đơn vị đầu ra đã hoàn thành, trong khi số liệu về mã thông báo so sánh tổng chi phí cho một phiên hoạt động điển hình của tác nhân.

Dữ liệu cũng cho thấy sự khác biệt nhất quán về cách hai khung xử lý mã phức tạp hoặc dễ bị lỗi. Meta theo dõi điều này bằng cách sử dụng điểm số rủi ro của các thay đổi về mã, đánh giá chất lượng mã tổng thể và khả năng một thay đổi gây ra sự cố trong quá trình sản xuất. Phân tích này đo lường hiệu quả sử dụng tài nguyên của một tác nhân bằng cách kết hợp mức tiêu thụ mã thông báo, thời gian thực thi của tác nhân và mức độ tương tác giữa kỹ sư với tác nhân. Khi các tệp tích luỹ điểm số rủi ro cao hơn, các phiên của tác nhân AI sẽ tự nhiên trở nên ít hiệu quả về tài nguyên hơn. 

Khi điểm rủi ro tích luỹ của một tệp tăng gấp đôi, giao diện người dùng được triển khai bằng Android Views sẽ giảm 30%hiệu quả sử dụng tài nguyên của tác nhân (trên mỗi ký tự được đặt). Trong cùng điều kiện, mức giảm của giao diện người dùng Jetpack Compose chỉ là 9%

Thông qua mối quan hệ đối tác giữa Google và Meta, nhóm Instagram Direct đã mang đến một góc nhìn mới mẻ về việc áp dụng Compose – tiếp cận vấn đề này qua lăng kính về khả năng sẵn sàng sử dụng AI của cơ sở mã, chứ không chỉ là việc viết lại giao diện người dùng. Công việc này cho thấy sức mạnh của Compose trong việc đóng vai trò là nền tảng để xây dựng cơ sở mã và cấu trúc ưu tiên AI, đặc biệt là khi được áp dụng ở quy mô của các ứng dụng như Instagram.

Tối ưu hoá hiệu suất 

Instagram Direct là một trong những nền tảng không thể thiếu của ứng dụng và mọi người mong muốn nền tảng này luôn hoạt động nhanh chóng và phản hồi ngay lập tức. Việc áp dụng Jetpack Compose một cách hiệu quả có nghĩa là phải viết lại phần lớn giao diện người dùng và mục tiêu số một là duy trì trải nghiệm chất lượng cao mà không có sự hồi quy.

Nhiều năm lặp lại đã đẩy việc triển khai dựa trên Khung hiển thị cũ trên Instagram lên một tiêu chuẩn hiệu suất cực kỳ cao và nhóm cần đáp ứng tiêu chuẩn tương tự trong khi chuyển sang một khung giao diện người dùng hoàn toàn mới.

Instagram đo lường hàng trăm, thậm chí hàng nghìn chỉ số hiệu suất.  Đối với việc áp dụng Compose, 3 yếu tố sau đây là quan trọng nhất:

  • Thời gian tương tác – khoảng thời gian từ khi mở màn hình cho đến khi có thể sử dụng màn hình đó.
  • Thời gian tải đầy đủ – khoảng thời gian từ khi mở màn hình cho đến khi tất cả nội dung được tải đầy đủ (tức là hình ảnh).
  • Hiệu suất cuộn – mức độ mượt mà khi màn hình cuộn, không bị rớt khung hình.

Các chỉ số này được theo dõi trong thời gian chạy ở giai đoạn phát hành công khai, giúp bạn có thể chạy thử nghiệm A/B để so sánh giao diện người dùng Compose đã di chuyển với giao diện người dùng cũ và đánh giá tác động của nỗ lực này đến hiệu suất.

Một cách phổ biến để tiếp cận quá trình di chuyển như thế này là bắt đầu từ quy mô nhỏ, di chuyển một số thành phần giao diện người dùng, thu thập dữ liệu và nghiên cứu cách các thành phần này hoạt động. Mặc dù hữu ích, nhưng những kết quả ban đầu này chỉ phản ánh một phần, dẫn đến kết quả âm tính giả về việc áp dụng Compose vì:

  • Không mang tính đại diện – một thành phần giao diện người dùng được di chuyển có thể cung cấp dữ liệu hữu ích về hiệu suất tổng thể của thành phần đó trên một màn hình cụ thể. Tuy nhiên, các thành phần khác nhau sẽ hoạt động khác nhau vì những lý do không tổng quát, nên bạn không phải lúc nào cũng có thể ngoại suy từ đó.
  • Chi phí tương tác – một phần nhỏ của Compose bên trong toàn bộ mã nguồn Chế độ xem lớn phải trả một chi phí cầu nối không thể dự đoán giữa hai hệ thống. Chi phí này làm sai lệch kết quả đo lường, vì vậy, kết quả ban đầu ở quy mô nhỏ không phản ánh đúng những gì sẽ xảy ra khi di chuyển hoàn toàn.

Kết quả là các hoạt động di chuyển nhỏ, dù hữu ích, nhưng không phải lúc nào cũng phản ánh đầy đủ tác động của Compose. Càng có nhiều bề mặt được di chuyển toàn diện mà không bị gián đoạn, thì hình ảnh càng rõ ràng và hiệu quả hơn.

Các màn hình chính trong Instagram Direct được xây dựng dựa trên danh sách dài gồm nhiều loại mục, ban đầu được triển khai bằng RecyclerView. Cấu trúc này dựa vào các lớp trừu tượng tuỳ chỉnh để có khả năng mở rộng, nhưng vẫn bị ràng buộc với vòng đời của hệ thống dựa trên Khung hiển thị.

Diagram 1.png

Công việc chính của nhóm là di chuyển dần hàng trăm mục riêng lẻ trong danh sách sang Compose trong cấu trúc hiện có dựa trên RecyclerView, triển khai các mục đó trong quá trình sản xuất theo các nhóm nhỏ độc lập trong các thử nghiệm A/B – tất cả đều không có thay đổi nào đối với trải nghiệm nhắn tin của người dùng.

Nhược điểm lớn nhất của chế độ thiết lập này là sự phụ thuộc đáng kể vào hệ thống View cũ thông qua cấu trúc RecyclerView cốt lõi, ngay cả sau khi di chuyển hoàn toàn mọi mục trong danh sách sang Compose. Là bước tiếp theo tự nhiên, nhóm đã quyết định đầu tư vào việc thay thế cấu trúc cốt lõi dựa trên RecyclerView bằng giải pháp thay thế gốc Compose – LazyColumn.

Điều này có nghĩa là các thành phần giao diện người dùng Compose phải được tách biệt khỏi khung mà chúng nằm trong, nhưng vẫn tương thích với cả RecyclerView và LazyColumn cùng một lúc. Khả năng chuyển đổi giữa hai chế độ này tại thời gian chạy thông qua cờ tính năng cũng quan trọng không kém để bật thử nghiệm A/B.

Diagram 2.png

Mặc dù các mục Compose mới tương thích một cách tự nhiên với LazyColumn và có thể được cắm vào một cây thành phần không bị gián đoạn, nhưng một API tương tác cũng được tạo để đưa các mục đó vào RecyclerView. Nhờ đó, bạn có thể triển khai chế độ thiết lập LazyColumn trong thử nghiệm A/B song song với RecyclerView – sử dụng lại các mục Compose tương tự và cải thiện hiệu suất mà không làm gián đoạn quá trình xây dựng và tinh chỉnh các tính năng của những thành viên còn lại trong nhóm.

Quy mô, độ phức tạp và độ nhạy của Instagram đối với ngay cả những lỗi nhỏ nhất cũng đặt ra một thách thức riêng cho Jetpack Compose. Để giải quyết những vấn đề này, chúng tôi cần có một mối quan hệ đối tác lặp đi lặp lại và trực tiếp. Các kỹ sư của Google và Meta đã phối hợp chặt chẽ với nhau để phân tích các chỉ số nhằm xác định và thiết kế các chức năng mới của Compose để đáp ứng hoặc vượt quá các điểm chuẩn dựa trên View. Nhờ sự hợp tác này, Jetpack Compose có thêm những điểm nổi bật sau: Thành phần có thể tạm dừng bằng LazyLayoutCacheWindows và tính năng theo dõi chế độ hiển thị. 

Thành phần có thể tạm dừng bằng LazyLayoutCacheWindows

Thành phần kết hợp có thể tạm dừng (được bật theo mặc định trong Compose 1.10) cho phép các mục danh sách có độ trễ cao được kết hợp tăng dần trên các khung hình để ngăn hiện tượng giật. Khi kết hợp với LazyLayoutCacheWindow (được thêm vào Compose 1.9), sự kết hợp này giúp cải thiện đáng kể độ mượt khi cuộn. Trong thử nghiệm nội bộ gần đây tại Meta, việc kết hợp thành phần có thể tạm dừng với một khung hiển thị LazyLayoutCacheWindow đã giảm số lượng lớn khung hình bị rớt mỗi phút (LFD/m) khoảng 13% so với Compose thông thường. Bản thân Cache Window đã giảm khoảng 8% so với cùng một đường cơ sở. LFD/m là một chỉ số nội bộ mà Meta sử dụng để theo dõi các hiện tượng giật đáng chú ý trong khi người dùng cuộn.

Quote-Fabio.jpg


Việc sử dụng LazyLayoutCacheWindow trong ứng dụng sẽ chuẩn bị và giữ lại các mục ngoài màn hình trong một dải dựa trên pixel xung quanh khung hiển thị để cho phép thao tác hất nhanh. Để tận dụng LazyLayoutCacheWindows trong ứng dụng, bạn có thể sử dụng Compose 1.13.0-alpha03 mới nhất và thiết lập như minh hoạ trong ví dụ bên dưới:

val cacheWindow = LazyLayoutCacheWindow(ahead = 150.dp, behind = 100.dp)
// OR
val cacheWindow = LazyLayoutCacheWindow(aheadFraction = 0.5f, behindFraction = 0.3f)

LazyColumn(state = state, cacheWindow = cacheWindow) {
    ...
}

Có hai cách để định cấu hình cửa sổ bộ nhớ đệm. Cả hai đều mô tả cùng một điều: lượng nội dung ngoài màn hình cần giữ lại, nhưng theo các đơn vị khác nhau.

  • Dp: chiều dài tuyệt đối cố định. ahead = 150.dp giữ 150 dp nội dung được tạo thành ngoài cạnh hiển thị, bất kể thiết bị.
  • Float: phân số của khung nhìn. aheadFraction = 0.5f giữ trước một nửa màn hình, vì vậy số lượng tuyệt đối sẽ tỷ lệ thuận với chiều cao màn hình, hỗ trợ nhiều kiểu dáng: nhiều hơn trên máy tính bảng hoặc điện thoại gập ở trạng thái mở, ít hơn trên điện thoại nhỏ gọn. 

Nhóm Instagram đã tinh chỉnh phân số dấu phẩy động của cửa sổ lưu vào bộ nhớ đệm cho cấu trúc nội dung và kích thước mục của Direct. Vì các giá trị lý tưởng sẽ khác nhau tuỳ thuộc vào các tham số cụ thể của giao diện người dùng, nên bạn cần thử nghiệm để tìm ra điểm cân bằng phù hợp.

Ghi nhật ký lượt hiển thị bằng onVisibilityChanged


API onVisibilityChanged (được thêm vào Compose 1.9.0) là một kết quả quan trọng khác của mối quan hệ đối tác kỹ thuật giữa Google và Meta. API này cung cấp cho các thành phần Jetpack Compose quy mô lớn một cách nhất quán để biết khi nào một thành phần kết hợp thực sự hiển thị trên màn hình, thay thế các triển khai tuỳ chỉnh, tự tạo được dùng trong quá khứ. Chỉ riêng trong Instagram Direct, những tín hiệu về khả năng hiển thị này được dùng trong hàng trăm tệp để hỗ trợ các chỉ số về chất lượng sản phẩm, tuỳ thuộc vào việc các thành phần trên giao diện người dùng có thực sự hiển thị cho người dùng hay không.

Hiệu suất khởi động

Việc áp dụng Jetpack Compose cho Instagram Direct đã mang lại những cải thiện hiệu suất không ngờ trên các nền tảng khác của ứng dụng. Thời gian chạy Jetpack Compose có chi phí khởi động mà bạn chỉ phải trả một lần. Vì nhắn tin là một nền tảng có lưu lượng truy cập cao và thường được truy cập sớm trong phiên hoạt động của người dùng, nên các nền tảng khác trên Instagram dựa vào Compose đã nhận thấy những cải thiện đáng kể về hiệu suất.

Hiệu suất khởi động của giao diện người dùng Compose trong chính Instagram Direct đã được tối ưu hoá thông qua việc sử dụng Hồ sơ cơ sở. Nhờ đó, các đường dẫn mã nóng sẽ được biên dịch trước tại thời điểm cài đặt để Compose hiển thị nhanh chóng ngay từ lần khởi chạy đầu tiên.

Bài học từ quá trình di chuyển Instagram Direct sang Jetpack Compose 

  • Jetpack Compose mang lại lợi tức đầu tư ngay lập tức: Bạn không cần sử dụng quy trình làm việc AI nâng cao để hưởng lợi từ Compose. Với mức giảm khoảng 50% mã, điều này có nghĩa là bạn sẽ phải duy trì ít mã hơn và giảm diện tích bề mặt cho các lỗi.
  • Việc thiết kế một cấu trúc dựa trên AI đã mang lại những thành công đáng kể, bao gồm thời gian thực thi của tác nhân AI giảm 35%, số lần trao đổi giữa kỹ sư và tác nhân giảm 32% và chi phí mã thông báo giảm 33%.
  • Mặc dù có rất nhiều API tương tác và hỗ trợ kết hợp các thành phần View và Compose với nhau, hãy cố gắng di chuyển các thành phần lớn hơn thay vì các thành phần nhỏ riêng lẻ. Điều này giúp giao diện người dùng nằm trong một hệ phân cấp thành phần duy nhất, không bị gián đoạn và khai thác tất cả các điểm tối ưu hoá hiệu suất tốt nhất của Compose.
  • Ghép thành phần có thể tạm dừng với LazyLayoutCacheWindow: Việc ghép hai thành phần này với nhau sẽ mang lại kết quả tốt hơn so với chỉ dùng các cửa sổ lưu vào bộ nhớ đệm. Chỉ với cửa sổ bộ nhớ đệm, một mục có kích thước lớn vẫn có thể cố gắng tạo thành một lần, có khả năng vượt quá ngân sách khung hình.
  • Đóng góp cho chính Compose! Meta đã hợp tác với nhóm Jetpack Compose để hiện thực hoá ý tưởng và ý kiến phản hồi của họ trong Compose. Việc sử dụng một bộ công cụ nguồn mở có nghĩa là tất cả chúng ta đều được hưởng lợi khi các lỗi và điểm cải thiện hiệu suất được thực hiện tập trung. Vì vậy, hãy cho chúng tôi biết ý kiến phản hồi của bạn!

Việc sử dụng Jetpack Compose đã mang lại những lợi ích đáng kể trong quá trình phát triển có sự hỗ trợ của AI, đồng thời đơn giản hoá hoạt động thiết kế giao diện người dùng hằng ngày tại Instagram. Phương pháp khai báo giúp giảm mã nguyên mẫu, giúp bạn dễ dàng suy luận về trạng thái và cải thiện năng suất tổng thể của nhà phát triển. Nhóm kỹ thuật của Instagram đang mong muốn đưa Compose đến nhiều nền tảng hơn trong ứng dụng, đồng thời tiếp tục hợp tác giữa Google và Meta để mang lại nhiều điểm cải tiến hơn cho cả người dùng Instagram và Jetpack Compose. 

Nếu bạn chưa dùng thử Compose (nay có sự hỗ trợ của AI), thì việc di chuyển sang Jetpack Compose sẽ dễ dàng hơn bao giờ hết.

Xác nhận. Cảm ơn Michal Zielinski và Matthew Du của Meta, cũng như Andrei Shikov và George Mount của Google vì những nỗ lực của họ trong việc cải thiện hiệu suất của Compose thông qua sự hợp tác giữa Meta và Google! Cũng xin cảm ơn Gary Ye của Meta vì đã giúp đưa Compose vào Instagram Direct và Gopal Juneja của Meta vì đã hỗ trợ nỗ lực này thông qua khoa học dữ liệu!

Tác giả:
Đọc tiếp