07. Layout Engine va Responsiveness
⚡ Server-Driven UI (SDUI) — Mukammal Enterprise & System Design
07. Layout Dvigateli va Ekran Moslashuvchanligi (Responsiveness)
"Agar siz serverdan 'width: 375' deb qat'iy piksel bersangiz, iPhone SE da ekran kesilib ketadi, iPad Pro da esa 80% bo'shliq behuda qoladi. Haqiqiy enterprise SDUI qurilma o'lchamini bilmaydi, u moslashuvchan qoidalar va proporsiyalarni biladi."
1. Apple Ekranlari Xilma-Xilligi va Hardcoded Piksellar Xatosi
Apple ekotizimida o'nlab turli xil ekran o'lchamlari mavjud:
- Kichik ekranlar: iPhone SE (375 × 667 pt)
- Standart ekranlar: iPhone 15 / 16 (393 × 852 pt)
- Katta ekranlar: iPhone 16 Pro Max (440 × 956 pt)
- Planshetlar: iPad mini, iPad Air va iPad Pro 13" (1024 × 1366 pt)
- Multitasking: iPad Stage Manager va Split View (ekranning 1/3, 1/2 yoki 2/3 qismi)
Quyidagi diagrammada moslashuvchan (Adaptive) tartibning ishlashi ko'rsatilgan:
flowchart TD
ScreenPayload["Server Layout Qoidasi\n{ columns: { compact: 2, regular: 4 }, aspectRatio: 1.5 }"] --> DeviceDetect{"Qurilma Size Class'ini Tekshirish"}
DeviceDetect -->|"iPhone (Compact Size Class)"| PhoneLayout["2 Ustunli Grid\n(Har bir kartochka ekranning 50% kengligida)"]
DeviceDetect -->|"iPad (Regular Size Class)"| TabletLayout["4 Ustunli Katta Grid\n(Har bir kartochka ekranning 25% kengligida)"]
DeviceDetect -->|"iPad Split View (1/3 o'lcham)"| SplitLayout["1 Ustunli Ixcham Ro'yxat (Avtomatik moslashuv!)"]
style ScreenPayload fill:#131720,stroke:#bef264,stroke-width:2px
style DeviceDetect fill:#181d26,stroke:#7da2ce,stroke-width:1px
style PhoneLayout fill:#181d26,stroke:#60a5fa,stroke-width:1px
style TabletLayout fill:#181d26,stroke:#4ade80,stroke-width:1px
2. Layout Dvigatellari Taqqoslovi: Stacks vs Flexbox (Yoga)
SDUI arxitekturasida komponentlarni joylashtirishning 3 xil usuli mavjud:
| Layout Dvigateli | Qanday Ishlaydi? | Qayerda Ishlatiladi? | Tezlik & CPU Yuklamasi |
|---|---|---|---|
| Native SwiftUI Stacks | VStack, HStack, ZStack, LazyVGrid | Zamonaviy iOS-first ilovalar | Maksimal Native (0 ms) |
| Flexbox (Facebook Yoga) | CSS Flexbox qoidalarini C++ dvigatelida hisoblaydi | Airbnb (Epoxy), React Native | O'rtacha (C++ xotira ko'prigi bor) |
| Dinamik Auto Layout | Serverdan NSLayoutConstraint qoidalari keladi | Eski UIKit tizimlari | Sekin (Cassowary algoritmi CPU ni qizdiradi) |
[Layout Hisoblash Vaqti (100 ta murakkab kartochka)]
Dinamik Auto Layout: ████████████████████ 34 ms (Katta CPU yuklamasi!)
Flexbox (YogaKit): ████████ 12 ms
SwiftUI Stacks: █ 2.1 ms (15x tezroq!)
3. Cumulative Layout Shift (CLS) Muammosi va Yechimi
Rasm yuklanishidan oldin kartochka 0 piksel bo'lib turib, rasm yuklangach to'satdan pastga sakrashi foydalanuvchi tajribasini (UX) buzadi.
flowchart TD
subgraph Bad["❌ CLS Bilan: Sahifa Sakrashi"]
direction TB
B1["1. Matn yuklandi (Rasm joyi 0 px)"] --> B2["2. Foydalanuvchi o'qiyotgan paytda rasm keldi"]
B2 --> B3["💥 Sahifa 300 px pastga sakradi! Foydalanuvchi adashib boshqa tugmani bosib yubordi!"]
end
subgraph Good["✅ AspectRatio va Skeleton Bilan (Zero Shift)"]
direction TB
G1["1. Server 'aspectRatio: 1.77' (16:9) yubordi"] --> G2["2. Ilova darhol 300x169 px li bo'sh joy (Skeleton Shimmer) zaxiraladi"]
G2 --> G3["3. Rasm kelganda joyiga silliq o'tirdi. Sakrash 0%!"]
end
style Bad fill:#251014,stroke:#f87171,stroke-width:1px
style Good fill:#0d1f14,stroke:#4ade80,stroke-width:1px
4. Swift 6 Kodi: Dynamic Responsive Grid va AspectRatio Image
import SwiftUI
// MARK: - 1. Responsive Grid Konteyneri
public struct SDUIResponsiveGrid: View {
public let items: [ComponentNode]
public let compactColumns: Int
public let regularColumns: Int
public let spacing: CGFloat
@Environment(\.horizontalSizeClass) private var sizeClass
public init(
items: [ComponentNode],
compactColumns: Int = 2,
regularColumns: Int = 4,
spacing: CGFloat = 12
) {
self.items = items
self.compactColumns = compactColumns
self.regularColumns = regularColumns
self.spacing = spacing
}
private var currentColumns: Int {
sizeClass == .regular ? regularColumns : compactColumns
}
private var gridLayout: [GridItem] {
Array(repeating: GridItem(.flexible(), spacing: spacing), count: currentColumns)
}
public var body: some View {
LazyVGrid(columns: gridLayout, spacing: spacing) {
ForEach(items) { item in
ComponentRegistry.shared.resolve(node: item)
}
}
.padding(.horizontal, spacing)
}
}
// MARK: - 2. Sakrashsiz Rasm Konteyneri (Zero CLS)
public struct SDUIDynamicImage: View {
public let urlString: String
public let aspectRatio: CGFloat // Masalan: 16.0 / 9.0
public var body: some View {
Color.clear
.aspectRatio(aspectRatio, contentMode: .fit)
.overlay(
AsyncImage(url: URL(string: urlString)) { phase in
switch phase {
case .empty:
// Skeleton yuklanish joyi (sakrash bo'lmaydi!)
Rectangle()
.fill(Color(uiColor: .tertiarySystemFill))
case .success(let image):
image
.resizable()
.scaledToFill()
case .failure:
Image(systemName: "photo")
.foregroundColor(.secondary)
@unknown default:
EmptyView()
}
}
)
.clipped()
.cornerRadius(12)
}
}
5. Interaktiv Savol-Javob (Self-Check Quiz)
<details> <summary><b>1-Savol: Nega iPad'da SDUI ekranni shunchaki iPhone o'lchamidan 2 barobar kattalashtirib (stretch) ko'rsatish yomon dizayn hisoblanadi?</b> (Yechimni ko'rish uchun bosing)</summary>
Tahlil va Yechim: Chunki katta ekranda piksellarni shunchaki cho'zish orqali axborot zichligi (Information Density) yo'qoladi, rasmlar xiralashadi va bo'sh joylar samarasiz sarflanadi. Professional yondashuv — ustunlar sonini ko'paytirish (iPhone'da 2 ta ustun, iPad'da 4 yoki 5 ta ustun) va Master-Detail ko'rinishiga o'tishdir. </details>
<details> <summary><b>2-Savol: Nega Flexbox (YogaKit) o'rniga zamonaviy iOS loyihalarda SwiftUI Stacks va Grid afzal ko'riladi?</b> (Yechimni ko'rish uchun bosing)</summary>
Tahlil va Yechim: YogaKit C++ tilida yozilgan bo'lib, Swift va C++ o'rtasida xotira ko'prigi (bridging) orqali ishlaydi va ilovaga ~3-4 MB qo'shimcha hajm yuklaydi. SwiftUI esa to'g'ridan-to'g'ri Apple'ning GPU va metallurgiya tezlatgichlari bilan integratsiya qilingan bo'lib, 120 FPS ProMotion displeylarda xotirani tejaydi va batareyani yeb qo'ymaydi. </details>
6. Amaliy Topshiriq (Senior Challenge)
SDUIResponsiveGrid komponentini ishga tushiring. Ekranni iPhone SE va iPad Pro 13" simulyatorlarida ochib ko'ring. iPhone'da 2 ta ustun, iPad'da esa avtomatik ravishda 4 ta ustun hosil bo'lishini va bitta ham layout xatosi (Constraint conflict) chiqmasligini tekshiring!