Başarılı bir Minimum Ürün (MVP) geliştirirken, her şey genellikle sorunsuz ilerler. Kullanıcı sayısı azdır, veritabanı boştur, sunucu hızlıdır. Kullanıcı bir düğmeye tıklar, ön uç bir istek gönderir, arka uç yanıt verir ve arayüz anında güncellenir. Bu ilk aşamada, mimarinin gelecekte de iyi ölçekleneceğine dair bir güven oluşur. Sorgu hızlıdır, tablolar küçüktür ve kullanıcı akışları basittir. Her form saniyenin onda biri içinde kaydedilir. Listeler anında açılır.
Ancak ürün büyüdükçe, her şey değişmeye başlar. Listeler uzar, filtreler karmaşıklaşır, analitik raporlar eklenir, tablo ilişkileri dağılır ve kullanıcı sayısı artar. Bu durum, Finsight gibi finansal izleme araçları geliştirirken özellikle belirginleşti. Bu tür uygulamalarda, işlemler, kategoriler, filtreler, toplamlar ve aylık görünümler gibi çok sayıda okuma işlemi gerçekleşir. Her ekranın sunucudan veri beklemesi gerektiğinde, ürün kullanıcıya ağırlaşmaya başlar.
Başlangıçta, performansı artırmak için klasik yöntemlere başvuruldu. PostgreSQL dizinleri optimize edildi, sayfalama eklendi, uç noktalar önbelleğe alındı ve gereksiz JOIN işlemleri kaldırıldı. Ancak kısa süre içinde, asıl sorunun sadece yavaş bir arka uç olmadığı anlaşıldı. Gerçek sorun, istek ve bekleme döngüsünün kendisiydi.
Geleneksel mimari şu şekilde çalışıyordu:
- Kullanıcı bir eylem gerçekleştirir (örneğin bir düğmeye tıklar).
- Ön uç, sunucuya bir istek gönderir.
- Sunucu yanıt verir (veya yanıt veremez).
- Ön uç arayüzü günceller.
Bu döngü, ağ ve sunucu hızlı olduğu sürece sorunsuz çalışır. Ancak mobil internetin zayıf olduğu durumlarda, sunucu geciktiğinde veya veritabanı ağır bir sorgu üzerinde çalıştığında, kullanıcı arayüzü donmaya başlar. Her eylem, kullanıcının ağla pazarlık yaptığı bir bekleyişe dönüşür.
Bu durumda, farklı bir yaklaşım benimsemeye karar verildi: yerel ilkeli mimariye geçiş.
Yerel Veri Kaynağı: Veriler Kullanıcıya Daha Yakın
Yeni mimaride, arayüzün ana veri kaynağı kullanıcının cihazındaki yerel bir SQLite veritabanı haline geldi. Önemli bir nokta: arka uç ortadan kalkmadı. Arka uç, kimlik doğrulama, yetkilendirme, iş kuralları ve doğrulama gibi kritik görevleri üstlenmeye devam etti. PostgreSQL, merkezi veritabanı olarak görev yapmaya devam ederken, React artık her listeleme veya alan güncellemesi için API çağırmak zorunda kalmadı.
Yeni akış şu şekilde çalışıyor:
- React UI, yerel SQLite veritabanına doğrudan erişir.
- PowerSync, yerel veritabanını arka uçla senkronize eder.
- Arka uç, PostgreSQL’e verileri kaydeder.
Bu yaklaşımda, kullanıcı bir kaydetme işlemi gerçekleştirdiğinde, veri önce yerel veritabanına yazılır ve arayüz hemen güncellenir. PowerSync, arka planda bu değişikliği sunucuya iletir. Kullanıcı artık ağın tepkisini beklemek zorunda kalmaz.
Yeni akış şu şekilde özetlenebilir:
- Kullanıcı eylemi (örneğin kaydetme).
- Yerel veritabanına yazma.
- Arayüzün hemen güncellenmesi.
- Arka planda senkronizasyon.
Bu değişiklik, sadece bir sorguyu hızlandırmaktan çok daha fazlasını ifade ediyor. Ağın kullanıcı ile arayüz arasındaki bekleyişini ortadan kaldırıyor.
Teknik Detaylar: PowerSync Nasıl Çalışıyor?
PowerSync, yerel SQLite veritabanını ön uçla entegre eder. Bileşenler, her ekran için ayrı bir API çağırmak zorunda kalmaz. Bunun yerine, yerel veritabanına doğrudan SQL sorguları gönderirler. Bu sorgular, yerel veritabanından veri okur veya yazar.
Arka uç da rol değiştirir. Artık her render için JSON yanıtı döndüren katman olmaktan çıkar. Bunun yerine, izinleri, varlıklar arasındaki ilişkileri ve gelen işlemleri doğrulayan bir katmana dönüşür. PowerSync ise senkronizasyon katmanını yönetir. Verileri istemciye dağıtır, yerel SQLite’yi senkronize eder ve yerel değişiklikleri sunucuya gönderir.
Yerel veritabanına tüm veritabanının indirilip indirilmediği sıkça sorulan bir sorudur. Cevap: hayır. PowerSync, kısmi replikasyon özelliği sunar. İstemciye yalnızca kullanıcının erişimine izin verilen satırlar gönderilir. Örneğin, bir kullanıcı birden fazla çalışma alanına sahipse, yalnızca kendi çalışma alanına ait veriler cihazına indirilir. Diğer tüm veriler sistemden hariç tutulur.
Aşağıda, sync_rules.yaml dosyasında yer alan basitleştirilmiş bir senkronizasyon kuralı örneği bulunmaktadır:
bucket_definitions:
by_workspace:
parameters: |
SELECT workspace_id
FROM workspace_memberships
WHERE user_id = request.user_id()
data:
- SELECT * FROM records WHERE workspace_id = bucket.workspace_id
- SELECT * FROM categories WHERE workspace_id = bucket.workspace_idBu yapılandırma sayesinde, kullanıcıya ait olmayan veriler asla cihazına indirilmez. Bu da iki önemli avantaj sağlar:
- Veri güvenliği: Kullanıcı, başkalarına ait verileri fiziksel olarak almaz.
- Sunucu yükünün azalması: Arka uç ve PostgreSQL, rutin okuma işlemlerinde daha az yer alır. Listeler, sıralama, filtreleme ve analitik işlemlerin birçoğu yerel olarak gerçekleştirilebilir.
Örneğin, bir liste ekranı aşağıdaki SQL sorgusunu yerel veritabanında çalıştırarak anında açılabilir:
SELECT * FROM records
WHERE workspace_id = ?
ORDER BY created_at DESC
LIMIT 50;Gerekirse, yerel veritabanına bir dizin de eklenebilir:
CREATE INDEX records_workspace_created_at_idx
ON records (workspace_id, created_at);Bu, kullanıcının yanındaki normal bir veritabanıdır. Sadece bir önbellek değil, arayüzün gerçek bir veri kaynağıdır.
Sonuç: Daha Akıcı Bir Kullanıcı Deneyimi
Yapılan resmi karşılaştırmalı testler olmasa da, kullanıcıların algıladığı performans artışı oldukça belirgindi. Gerçek sorun, arka ucun yanıt süresi değil, arayüzün her zaman ağın tepkisini beklemek zorunda olmasıydı. Artık ekranlar anında açılıyor, geçişler daha akıcı oluyor ve yükleme göstergeleri neredeyse kayboluyor.
Bu yaklaşımın en büyük avantajı, kullanıcının deneyimini doğrudan iyileştirmesi. Yerel veritabanı ve PowerSync’in senkronizasyon yetenekleri sayesinde, uygulama artık ağ koşullarından bağımsız olarak çalışabiliyor. Kullanıcı, internet bağlantısı zayıf olsa bile veri girişi yapabilir ve arayüz anında yanıt verir. Arka planda gerçekleşen senkronizasyon ise kullanıcıya hiçbir şekilde hissettirilmez.
Gelecekte, bu mimariye dayalı olarak daha da optimize edilmiş senkronizasyon stratejileri geliştirilebilir. Örneğin, kullanıcının sık kullandığı verilerin önbelleğe alınması veya çevrimdışı modda çalışabilme yeteneğinin genişletilmesi gibi iyileştirmeler, kullanıcı deneyimini daha da ileriye taşıyabilir. Yerel ilkeli mimariler, modern uygulamaların performans ve kullanıcı memnuniyeti açısından gelecekteki standartlarını belirleyecek gibi görünüyor.
Yapay zeka özeti
Yerel ilkeli mimariye geçişle uygulama performansını artırın. PowerSync ve SQLite kullanarak kullanıcı arayüzündeki beklemeleri ortadan kaldırın ve ağ bağımsızlığı sağlayın.