Stories Render Journey Flow

Versiyon: 1.0 | Guncelleme: 2026-05-22


1. Yonetici Ozeti

PostPaid ana sayfa acildiginda stories iki asamada yuklenir: once static stories (ViewModel init), sonra AOM MVA tamamlandiktan sonra dynamic stories. Toplam sure cihaza gore 272ms - 8417ms arasi degisir.

Ozet Sureler:

Cihaz Toplam Sure Static Network Dynamic Network
Dusuk RAM (Device 1) 8417ms 1539ms 3598ms
Orta RAM (Device 3) 3760ms 221ms 911ms
Yuksek RAM (Device 2) 2923ms 348ms 226ms

2. Architecture Overview - Component Diagram

+----------------------------------------------------+
|            Yanimda App                              |
|                                                    |
|  +----------------------------------------------+  |
|  |  PostPaidHomeActivity (UI)                   |  |
|  |  - setLiveDatas() [LiveData observe]         |  |
|  |  - setCategorizedStaticStoriesData()         |  |
|  |  - setCategorizedDynamicStoriesData()        |  |
|  |  - sortStoriesAndSetList() [sort + render]   |  |
|  |  - rvStories RecyclerView (Horizontal)       |  |
|  |  - categorizedStoriesAdapter                 |  |
|  +------------------+---------------------------+  |
|                     v                              |
|  +----------------------------------------------+  |
|  |  PostPaidHomeViewModel                       |  |
|  |  - getCategorizedStaticStories() [init]      |  |
|  |  - getCategorizedDynamicStories() [post-AOM] |  |
|  |  - homeCategorizedStaticStoriesLiveData      |  |
|  |  - homeCategorizedDynamicStoriesLiveData     |  |
|  |  - isAomMvaSent (gate for dynamic stories)   |  |
|  +------------------+---------------------------+  |
|                     v                              |
|  +----------------------------------------------+  |
|  |  CommonRepository                            |  |
|  |  - responseFlowWrapper { rds.call() }        |  |
|  +------------------+---------------------------+  |
|                     v                              |
|  +----------------------------------------------+  |
|  |  CommonRemoteDataSource                      |  |
|  |  - getCategorizedStaticStories() [GET]       |  |
|  |  - getCategorizedDynamicStories() [POST]     |  |
|  |  - BaseRemoteDataSource.getResponse()        |  |
|  +------------------+---------------------------+  |
|                     v                              |
|           +---------------------+                  |
|           |  REST API Server    |                  |
|           +---------------------+                  |
+----------------------------------------------------+

3. Business Sequence Diagram

[Diagram]

4. Business Flow Chart

[Diagram]

5. Yukleme Fazlari

Faz 1: ViewModel Init — Static Stories Request

Faz 2: Activity Observer — Static Stories Render

Faz 3: AOM Gate — Dynamic Stories Tetikleme

Faz 4: Activity Observer — Dynamic Stories Merge & Render

Faz 5: sortStoriesAndSetList() — Siralama ve Render

Bu fonksiyon her iki fazda da calisir:

  1. isShown kontrolu: PreferenceHelper'dan her story'nin gorulup gorulmedigi kontrol edilir
  2. Siralama algoritmasi (priority weight system):
Kriter Puan Aciklama
anyLockedType 32 Kilitli icerikler en uste
countdown 16 Geri sayimli hikayeler
pinned 8 Sabitlenmis hikayeler
featured 4 One cikan hikayeler
!isShown 2 Gorulmemis hikayeler
priority ±1 Priority degeri tiebreaker
  1. Render: adapter.setList() + notifyDataSetChanged()
  2. Olcum: rvStories.post {} ile RecyclerView layout pass tamamlaninca sure olculur

6. API Envanteri

# API Metod Tetikleyici Thread Bagimlilik
1 getCategorizedStaticStories GET ViewModel init Dispatchers.IO Yok — aninda baslar
2 getCategorizedDynamicStories (V2) POST AOM MVA response + delay Dispatchers.IO isAomMvaSent = true

API Detaylari

getCategorizedStaticStories:

getCategorizedDynamicStories:


7. API Response Sureleri — Cihaz Bazli Production Verisi

Device 1 — Dusuk RAM

0ms       1539ms  1740ms  2138ms   4684ms       8282ms 8287ms 8417ms
|          |       |       |        |             |      |      |
Init     Static  Sort   Render   Dynamic       Dyn    Sort  Render
         Resp    Start  Done     Call          Resp   Start  Done
Metric Sure
getCategorizedStaticStories 1539ms
Data processing (response → render start) 201ms
Stories render (static) 399ms
Gap (static done → dynamic call) 2546ms
getCategorizedDynamicStories 3598ms
Data processing (response → render start) 5ms
Stories render (dynamic) 130ms
Toplam (first visible to final) 8417ms

Device 2 — Yuksek RAM

0ms   348ms 369ms 427ms  2669ms 2895ms 2912ms 2923ms
|      |     |     |       |      |      |      |
Init  Static Sort Render  Dyn   Dyn    Sort  Render
      Resp  Start Done    Call  Resp   Start  Done
Metric Sure
getCategorizedStaticStories 348ms
Data processing (response → render start) 21ms
Stories render (static) 58ms
Gap (static done → dynamic call) 2242ms
getCategorizedDynamicStories 226ms
Data processing (response → render start) 17ms
Stories render (dynamic) 11ms
Toplam (first visible to final) 2923ms

Device 3 — Orta RAM

0ms   221ms 238ms 272ms  2824ms  3735ms 3736ms 3760ms
|      |     |     |       |       |      |      |
Init  Static Sort Render  Dyn    Dyn    Sort  Render
      Resp  Start Done    Call   Resp   Start  Done
Metric Sure
getCategorizedStaticStories 221ms
Data processing (response → render start) 17ms
Stories render (static) 34ms
Gap (static done → dynamic call) 2552ms
getCategorizedDynamicStories 911ms
Data processing (response → render start) 1ms
Stories render (dynamic) 24ms
Toplam (first visible to final) 3760ms

Karsilastirma Tablosu

Metric Dusuk RAM Orta RAM Yuksek RAM
Static network 1539ms 221ms 348ms
Static render 399ms 34ms 58ms
Gap (AOM wait) 2546ms 2552ms 2242ms
Dynamic network 3598ms 911ms 226ms
Dynamic render 130ms 24ms 11ms
Toplam 8417ms 3760ms 2923ms
Static items 13 12 14
Final items 14 14 16

8. Log Yerlestirme Haritasi

Performans loglarinin yerlestirilme noktalari:

Log Dosya Satir Thread
getCategorizedStaticStories: Request PostPaidHomeViewModel.kt 379 IO
getCategorizedStaticStories: Response PostPaidHomeViewModel.kt 392 IO
getCategorizedDynamicStories: Request PostPaidHomeViewModel.kt 462 IO
getCategorizedDynamicStories: Response PostPaidHomeViewModel.kt 475 IO
Stories render started at: PostPaidHomeActivity.kt 1585 Main
Stories render finished at: PostPaidHomeActivity.kt 1635 Main
Stories render duration: PostPaidHomeActivity.kt 1636 Main

9. Threading Modeli

ViewModel init (Main Thread)
  |
  +---> viewModelScope.launch(Dispatchers.IO)
  |       |
  |       +---> CommonRepository.getCategorizedStaticStories()
  |       +---> CommonRemoteDataSource.getCategorizedStaticStories() [Network I/O]
  |       +---> homeCategorizedStaticStoriesLiveData.postValue() [thread-safe bridge to Main]
  |
  +---> Main Thread: LiveData observer fires
          |
          +---> setCategorizedStaticStoriesData() [Main Thread]
          +---> sortStoriesAndSetList() [Main Thread]
                |
                +---> PreferenceHelper.isStoryIdShown() [SharedPreferences read - Main Thread]
                +---> categorizedStories.sortWith() [CPU sort - Main Thread]
                +---> adapter.setList() + notifyDataSetChanged() [Main Thread]
                +---> rvStories.post {} → measure render done [Main Thread, after layout]

Activity (Main Thread)
  |
  +---> isAomMvaSent observer fires
  +---> lifecycleScope.launch(Dispatchers.Main)
  |       +---> delay(getStoryDelay()) [Main Thread suspend]
  |       +---> getCategorizedDynamicStories() → same IO flow as static

Potansiyel sorun: sortStoriesAndSetList() tamamen Main Thread'de calisir — siralama, SharedPreferences okuma ve RecyclerView guncelleme hepsi Main Thread'de.


10. Delay ve Timer Envanteri

Timer/Delay Sure Kaynak Amac
AOM MVA wait ~2000-4700ms isAomMvaSent observer Dynamic stories AOM'dan sonra tetiklenir
getStoryDelay() delaySn * 1000ms ConfigManager.homeAdobeTargetStoryDelay UI settle / target delay
STORY_DEFAULT_DELAY Fallback PostPreCommonUtils Config null ise default
rvStories.post {} 1 frame Android View system Layout pass tamamlanma olcumu
Shimmer API response'a kadar showShimmerAdapter() Kullanici beklerken placeholder

11. RecyclerView Konfigurasyonu

with(binding.rvStories) {
    layoutManager = LinearLayoutManager(context, HORIZONTAL, false)
    isNestedScrollingEnabled = false
    adapter = categorizedStoriesAdapter
    setHasFixedSize(true)
    setItemViewCacheSize(20)
    isDrawingCacheEnabled = true
    showShimmerAdapter()  // Shimmer gosterilir ta ki API response gelene kadar
}
Config Deger Etki
Direction HORIZONTAL Yatay kaydirma
NestedScrolling false Scroll performansi
HasFixedSize true Layout optimizasyonu
ItemViewCacheSize 20 Extra cache (default 2)
DrawingCache true Drawing cache aktif

12. Mimari Notlar ve Cikarimlar

Kritik Path (Dusuk RAM)

ViewModel Init → Static API (1539ms) → Sort+Render (399ms) → AOM Wait (2546ms) → Dynamic API (3598ms) → Sort+Render (130ms)
Toplam: 8417ms

Kritik Path (Yuksek RAM)

ViewModel Init → Static API (348ms) → Sort+Render (58ms) → AOM Wait (2242ms) → Dynamic API (226ms) → Sort+Render (11ms)
Toplam: 2923ms

Bottleneck Analizi

Rank Bottleneck Etki Oran
1 AOM MVA wait gap ~2200-2550ms tum cihazlarda %30-60 of total
2 Dynamic stories network 226-3598ms (cihaza bagli) %8-43 of total
3 Static stories network 221-1539ms (cihaza bagli) %7-18 of total
4 Static render 34-399ms (cihaza bagli) %1-5 of total
5 Dynamic render 11-130ms (cihaza bagli) <2% of total

Onemli Bulgular

  1. AOM bagimlilik en buyuk bottleneck: Dynamic stories AOM MVA response'a bagimli. Bu ~2.2-2.5s'lik sabit bir gap olusturuyor — network veya render optimizasyonundan bagimsiz.

  2. Render performansi iyi: Ikinci render (dynamic) her zaman ilk renderdan hizli — RecyclerView cache calisiyror (399ms → 130ms, 58ms → 11ms, 34ms → 24ms).

  3. Dusuk RAM farki dramatik: Static network 7x yavaş (221ms vs 1539ms), dynamic network 16x yavaş (226ms vs 3598ms).

  4. sortStoriesAndSetList() Main Thread riski: Siralama + SharedPreferences okuma + RecyclerView guncelleme hepsi Main Thread'de. Dusuk RAM cihazlarda 399ms render suresi bunu dogruluyor.

  5. notifyDataSetChanged() kullanimi: Tum liste yeniden render ediliyor — DiffUtil kullanilmiyor. Dynamic stories geldiginde sadece yeni eklenen items render edilebilir.

  6. Gap tutarliligi: AOM wait gap (2242-2552ms) tum cihazlarda benzer — bu network/cihaz degil, AOM pipeline'in kendi suresi.

Bagimlilik Grafigi

ViewModel Init
  |
  +---> getCategorizedStaticStories() ----response---+
  |                                                   |
  |     setCategorizedStaticStoriesData() <-----------+
  |       |
  |       +---> sortStoriesAndSetList() → STATIC STORIES VISIBLE
  |
  +---> AOM MVA pipeline (paralel)
          |
          +---> isAomMvaSent = true
                  |
                  +---> delay(getStoryDelay())
                  |
                  +---> getCategorizedDynamicStories() ----response---+
                                                                      |
                        setCategorizedDynamicStoriesData() <----------+
                          |
                          +---> merge static + dynamic
                          +---> sortStoriesAndSetList() → FINAL STORIES VISIBLE