Gezinme gecikmesi, kullanıcı deneyimi açısından kritik bir metriktir. WebView, geliştiricilerin bu gecikmeyi azaltmasına yardımcı olmak için tahmine dayalı içerik API'leri sağlar. Bu API'ler, kullanıcının açıkça gezinmesinden önce uygulamanızın içeriği getirmesine veya oluşturmasına olanak tanır.
WebView, üç temel tahmine dayalı içerik türünü destekler: önceden bağlanma, önceden getirme ve önceden oluşturma.
Tahmine dayalı içerik yükleme stratejisi uygulayarak aşağıdakileri elde edebilirsiniz:
- Web içeriği yükleme gecikmesinde önemli ölçüde azalma: Ağ başlatma süresini uygulama yaşam döngüsünde daha erkene taşıyın.
- Daha yüksek gezinme başarı oranları: Ağı ve önbelleği önceden ısıtarak gezinmelerin geçici ağ sorunları nedeniyle başarısız olma olasılığı azalır.
- Daha iyi algılanan yanıt verme hızı: Özellikle önceden işleme, uygulamanın önemli ölçüde daha hızlı hissedilmesini sağlayan anlık geçişlere olanak tanır.
Tahmine dayalı içerik stratejisi seçme
Bu stratejiler arasındaki temel fark kapsamlarıdır: Preconnect API, kaynak tabanlıdır. Bu nedenle yalnızca hedef alan gerektirir. Önceden getirme ve önceden işleme API'leri URL tabanlıdır. Bu nedenle, tam web sayfası yolu gerekir.
Ön bağlantı, kaynak düzeyinde çalıştığı için uygulama yaşam döngüsünde çok daha erken başlatılabilir. Hatta kullanıcının gideceği belirli içeriği veya sayfayı bilmeden bile başlatabilirsiniz.
Aşağıdaki tabloda, kullanım alanınız için doğru olanı seçmenize yardımcı olmak amacıyla bu üç strateji karşılaştırılmaktadır:
| Özellik | Önceden bağlama | Önceden getirme | Prerender |
|---|---|---|---|
| Birincil hedef | Bağlantıyı ısıtma | Yalnızca HTML'yi önbelleğe alma (JavaScript veya CSS olmadan) | Sayfanın tamamını önceden oluşturma |
| Kapsam | Profil düzeyi (WebView'larda paylaşılır) | Profil düzeyi (WebView'larda paylaşılır) | WebView düzeyi (belirli bir WebView'a bağlı) |
| Jetpack WebKit API'si | androidx.webkit.Profile |
androidx.webkit.Profile |
androidx.webkit.WebViewCompat |
| Temel API yöntemleri | preconnect(...) |
prefetchUrlAsync(...) |
prerenderUrlAsync(...) |
| Yapılandırma | Yok | PrefetchCache.setMaxPrefetches()PrefetchCache.setPrefetchTtlSeconds() |
setMaxPrerenders() |
| Kaynak kullanımı | Düşük (ağ) | Orta (ağ, bellek) | Yüksek (CPU, bellek, ağ) |
| Kullanılacağı zaman | Hedef kaynak biliniyor ancak belirli URL henüz belirlenmediğinde. | Tam URL bilindiğinde ve gezinme olasılığı yüksek olduğunda, önbelleğe alma işlemi WebView'lar arasında paylaşılır. | Tam URL bilindiğinde ve belirli bir WebView'da gezinme kesin olduğunda. |
| Avantajlar | Kaynakta bulunan tüm URL'ler için daha hızlı bağlantı kurulumu | Eşleşen URL'ler için daha hızlı ağ yükü | Etkinleştirildikten sonra anında gezinme |
Kaynaklara önceden bağlanma
Ön bağlantı, belirtilen bir kaynak için DNS aramaları ve TCP/TLS el sıkışmaları önceden yapılarak gelecekteki yüklemeleri hızlandırır.
Tam hedef URL gerektiren önceden getirme ve önceden oluşturma işlemlerinin aksine, ön bağlantı kesinlikle kaynak tabanlıdır. Bu sayede, önceden bağlama çağrısını önceden getirme ve önceden oluşturma işlemlerinden çok daha önce yapabilirsiniz.
Bu düşük kaynaklı, profil düzeyindeki strateji, kaynak daha önce ziyaret edilmemişse bu profili paylaşan tüm WebView'ler için ilk gecikmeyi azaltır. Bağlantı yaklaşık 30 saniye açık kalır. Bu sayede, el sıkışma ek yükünü ortadan kaldırarak sonraki tüm kaynaklar arası HTTP istekleri, gezinmeler veya alt kaynaklar avantaj sağlar.
Uygulama
Ön bağlantı başlatmak için Profile örneğinde preconnect(String url) hizmetini arayın. Bu API, kullanıcı arayüzü iş parçacığında çağrılmalı ve WebViewFeature.PRECONNECT'nın desteklenmesini gerektirir.
API, kaynak üzerinde çalışır ancak kolaylık sağlamak için tam bir URL (ör. https://www.example.com/index.html) sağlanabilir. Bu, otomatik olarak kaynağa yapılan bir çağrı (ör. https://www.example.com) olarak değerlendirilir. Bu API birden çok kez çağrılarak birden fazla kaynağa bağlanılabilir.
Kotlin
// Must be called on the @UiThread
if (WebViewFeature.isFeatureSupported(WebViewFeature.PRECONNECT)) {
profile.preconnect("https://www.example.com/index.html")
// This initiates a connection to the origin https://www.example.com
}
Java
// Must be called on the @UiThread
if (WebViewFeature.isFeatureSupported(WebViewFeature.PRECONNECT)) {
profile.preconnect("https://www.example.com/index.html");
// This initiates a connection to the origin https://www.example.com
}
Yaygın yapılandırma: PrefetchParameters ve PrerenderParameters
Hem önceden getirme hem de önceden oluşturma, isteği özelleştirmek için PrefetchParameters veya PrerenderParameters kullanır. Bu sınıflar, No-Vary-Search yapılandırmaları gibi URL eşleştirme için ek başlıklar ve ipuçları sağlamanıza olanak tanır.
Kotlin
// Isolated configuration specifically for Cache-Level Prefetching
val prefetchParams = PrefetchParameters.Builder()
.addAdditionalHeader("X-Custom-Client", "Android-App-V2")
.setExpectedNoVarySearchHeader(
NoVarySearchHeader.varyExcept(true, listOf("session_id", "click_ref"))
)
.build()
Java
PrefetchParameters prefetchParams = new PrefetchParameters.Builder()
.addAdditionalHeader("X-Custom-Header", "value")
/**
* Hint to ignore specific query parameters during cache matching.
* This allows the cache to match even if the tracking_id differs.
*/
.setExpectedNoVarySearchHeader(
NoVarySearchHeader.varyExcept(true, Arrays.asList("tracking_id"))
)
/**
* Determines if Client Hints are sent.
* NOTE: This is ignored for Prerendering API requests, which default to
* the WebView's WebSettings.getJavaScriptEnabled() value.
*/
.setJavaScriptEnabled(true)
.build();
İçeriği önceden getirme
Önceden getirme, bir URL'nin ana HTML kaynağını indirip profilin ağ önbelleğinde depolar. WebView'da Profile, çerezler, HTTP önbelleği ve hizmet çalışanları dahil olmak üzere tarayıcı verileri için kapsayıcı görevi görür. Önceden getirme, profil düzeyinde bir işlem olduğundan bu profille ilişkili tüm WebView, önbelleğe alınmış yanıttan yararlanabilir.
Uygulama
Önceden getirme başlatmak için bir Profile örneğinde prefetchUrlAsync() işlevini çağırın. Bu işlem yalnızca HTTPS şemasını destekler.
Kotlin
profile.prefetchUrlAsync(
url,
prefetchParams,
cancellationSignal,
executor,
object : WebViewOutcomeReceiver<PrefetchResult, PrefetchException> {
override fun onResult(result: PrefetchResult) {
if (result.wasDuplicate()) {
// URL and No-Vary-Search permutations already exist in the cache layer
} else {
// The HTML payload has been successfully secured in the HTTP cache
}
}
override fun onError(error: PrefetchException) {
when (error) {
is PrefetchNetworkException -> {
// Isolates network layer or server-side HTTP anomalies
val code = error.httpStatusCode
// Facilitates rapid diagnosis of 4xx or 5xx server responses
}
else -> {
// Catches generalized execution failures and system constraints
}
}
}
}
)
Java
profile.prefetchUrlAsync(
url,
prefetchParams,
cancellationSignal,
executor,
new WebViewOutcomeReceiver<PrefetchResult, PrefetchException>() {
@Override
public void onResult(PrefetchResult result) {
if (result.wasDuplicate()) {
// URL and No-Vary-Search permutations already exist in the cache layer
} else {
// The HTML payload has been successfully secured in the HTTP cache
}
}
@Override
public void onError(PrefetchException error) {
if (error instanceof PrefetchNetworkException) {
// Isolates network layer or server-side HTTP anomalies
int code = ((PrefetchNetworkException) error).httpStatusCode;
// Facilitates rapid diagnosis of 4xx or 5xx server responses
} else {
// Catches generalized execution failures and system constraints
}
}
}
);
Pas arası yaşam döngüsü
WebView önceden getirme isteği, shouldInterceptRequest()
geri çağırma işleminin ne zaman ve nasıl tetikleneceğini değiştirir. Bu durum, önceden getirilmiş içeriğinizin başarılı bir şekilde kullanılıp kullanılmayacağını doğrudan etkilediğinden iki adımlı yaşam döngüsünü anlamak çok önemlidir:
1. Spekülatif aşama (önceden getirme isteği)
prefetchUrlAsync() çağrıldığında WebView, ana HTML kaynağını arka planda indirir. shouldInterceptRequest(), bu arka plan isteği için tamamen atlanır. Genellikle kesicinizde işlenen özel mantıklar, yetkilendirme jetonları veya üstbilgi eklemeleri, önceden getirilmiş HTML kaynağına uygulanmaz.
2. Gezinme aşaması (kullanıcı etkinleştirme)
Uygulama açıkça URL'ye gittiğinde (örneğin, loadUrl() kullanarak) veya kullanıcı eşleşen bir bağlantıyı tıkladığında WebView, önceden getirilmiş önbelleği kullanıp kullanamayacağını belirler:
Ana HTML değerlendirmesi: WebView, bu noktada ana HTML için
shouldInterceptRequest()tetikleyecektir. Sayfayı önceden getirme önbelleğinden başarıyla sunmak için engelleyicinizinnulldeğerini döndürmesi gerekir. Özel birWebResourceResponsedöndürürseniz WebView, kesicinizin isteğini karşılar ve önceden getirme önbelleğini tamamen atlar.Alt kaynak değerlendirmesi: Önceden getirilmiş HTML'nin kullanıma uygun olduğu onaylandıktan sonra,
shouldInterceptRequest()sayfanın oluşturulmasını tamamlamak için gereken tüm sonraki alt kaynaklar (ör. resimler, komut dosyaları ve CSS) için normal şekilde tetiklenir.
Temel davranışlar
Aşağıdaki operasyonel özellikler ve uygunluk kontrolleri, WebView'ın önceden getirme isteklerini nasıl başlattığını ve yönettiğini belirler:
- İş parçacığı güvenliği: İstekler herhangi bir iş parçacığından başlatılabilir.
- Uygunluk: WebView, getirme işlemi başlatmadan önce aşağıdaki kontrolleri yaparak isteğin güvenli ve bağlama uygun olduğundan emin olur:
- Mevcut çerezler: WebView, kullanıcı gizliliğini korumak ve CSRF benzeri yan etkileri önlemek için istek, sunucuda durum değişikliğini tetikleyebilecek belirli kimliği doğrulanmış çerezler gerektiriyorsa önceden getirme işlemini atlayabilir.
- Hizmet çalışanı varlığı: Bir hizmet çalışanı URL'nin kapsamını zaten kontrol ediyorsa WebView, standart bir ağ önceden getirme işlemi başlatmak yerine hizmet çalışanının getirme işleyicisini kullanabilir.
- Proxy kullanılabilirliği: WebView, karmaşık ağ yapılandırmalarında spekülatif isteklerin başarısız olmasını önlemek için mevcut ağ yolunun (yapılandırılmış tüm proxy'ler dahil) kararlı olduğunu doğrular.
- Önceden getirme işlemi (geçerli parametrelerle bile) başlatılamazsa bunun nedeni genellikle WebView'ın, arka plan isteğinin kullanıcının mevcut oturumuna veya güvenlik durumuna müdahale edebileceğini belirlemesidir.
- İptal: Devam eden bir isteği sonlandırmak ve önbelleğe alınmasını önlemek için
CancellationSignalsimgesini kullanın.
Sayfaları önceden oluşturma
Önceden işleme, komut dosyası yürütme ve alt kaynak getirme dahil olmak üzere bir sayfayı arka planda tamamen oluşturmak için gizli "web içeriği" oluşturur. Önceden oluşturma, önceden getirme ile aynı temel altyapıyı kullanır. Bir uygulama önceden oluşturma işlemi başlatırsa WebView, önceden oluşturma navigasyonuna hizmet vermek için önce yanıtın önceden getirme işlemini gerçekleştirir ve gereksiz ağ etkinliğini önler.
Uygulama
Önceden oluşturma, WebView örneği düzeyinde bir işlemdir. Kullanıcı arayüzü iş parçacığından prerenderUrlAsync()
numaralı telefonu WebViewCompat kullanarak arayın.
Kotlin
WebViewCompat.prerenderUrlAsync(
webView,
url,
cancellationSignal,
executor,
params,
object : PrerenderOperationCallback {
override fun onPrerenderActivated() {
// Called when the user navigates to the URL and the hidden page is swapped in
}
override fun onError(exception: Throwable) {
// exception is an instance of PrerenderException
// Handle prerender failure (for example, memory pressure or disallowed JavaScript APIs)
}
}
)
Java
WebViewCompat.prerenderUrlAsync(webView, url, cancellationSignal, executor, params, new PrerenderOperationCallback() {
@Override
public void onPrerenderActivated() {
// Called when the user navigates to the URL and the hidden page is swapped in.
}
@Override
public void onError(@NonNull Throwable exception) {
// Handle prerender failure (for example, resource constraints or disallowed APIs).
}
});
Hem önceden getirme hem de önceden oluşturma tamamen eşzamansızdır. prefetchUrlAsync() herhangi bir iş parçacığından çağrılabilirken prerenderUrlAsync(), kullanıcı arayüzü iş parçacığından başlatılmalıdır.
Teknik kısıtlamalar
WebView, anında gezinme ile sistem sağlığı arasında denge kurmak için aşağıdaki çalışma zamanı kısıtlamalarını uygular:
- Bellek baskısı: Cihazın RAM'i düşükse WebView, önceden oluşturulmuş URL'leri iptal eder.
- İzin verilmeyen API'ler: JavaScript'in arka plan bağlamında belirli API'lere (ör. ses çalma, uyarılar) erişme girişimleri, önceden oluşturma işlemini anında sonlandırır.
- Örnek sınırı: WebView başına izin verilen etkin önceden oluşturulmuş URL'lerin sayısı sınırlıdır.
URL eşleştirme ve No-Vary-Search (NVS)
WebView, önceden yüklenmiş bir kaynağın yalnızca amaçlanan gezinme için yayınlanmasını sağlamak üzere güvenilir bir eşleştirme algoritması gerektirir.
Tam eşleme ve NVS eşleşmesi
Varsayılan olarak, önceden getirme ve önceden oluşturma için URL'nin tam olarak eşleşmesi gerekir. Gidilen URL, önceden yüklenen URL ile aynıysa hemen önbellekten sunulur. Sorgu parametreleri farklıysa WebView aşağıdaki No-Vary-Search (NVS) kurallarını kullanır:
- İpucu: Geliştiriciler, başlatma sırasında
setExpectedNoVarySearchHeader()ipucu verir. Gidilen URL, ipucu verilen parametreler hariç istek URL'siyle eşleşirse WebView, sunucunun gerçek başlıklarını beklemek için kısa bir süre engellenir. - Sunucu üstbilgisi: Sunucudan gelen NVS yanıt başlığı nihai yetkilidir. Sunucu, sorgu farklılıklarının yoksayılması gerektiğini onaylarsa eşleşme önbellekten sunulur. Aksi takdirde WebView, soğuk ağ yüklemesine geri döner.
No-Vary-Search (NVS), ileri düzey kullanım içindir ve çoğu geliştirici, hem önceden getirme hem de loadUrl() için tam olarak aynı URL'yi ilettiğinden bu özelliği kullanmak zorunda kalmayabilir. Bu yönergeler yalnızca önceden getirme URL'si ile loadUrl() URL'si arasında sorgu parametreleri açısından farklılıklar varsa gereklidir.
Genel yapılandırma
PrefetchCache sınırlarını ve maksimum önceden oluşturma sayısını yapılandırarak tahmine dayalı içerik yükleme davranışını profil düzeyinde ayarlayın. Özel önceden getirme sınırlarını sistem varsayılanlarına da sıfırlayabilirsiniz:
Kotlin
// Configure prefetch cache limits
profile.prefetchCache.setMaxPrefetches(10)
profile.prefetchCache.setPrefetchTtlSeconds(60)
// Reset to system defaults when needed
profile.prefetchCache.clearMaxPrefetches()
// Configure maximum active prerenders
profile.setMaxPrerenders(2)
Java
// Configure prefetch cache limits
PrefetchCache prefetchCache = profile.getPrefetchCache();
prefetchCache.setMaxPrefetches(10);
prefetchCache.setPrefetchTtlSeconds(60);
// Reset to system defaults when needed
prefetchCache.clearMaxPrefetches();
// Configure maximum active prerenders
profile.setMaxPrerenders(2);
Hata işleme ve istisnalar
Spekülatif işlemler, sonuçları bildirmek için OutcomeReceiverCompat veya PrerenderOperationCallback kullanır.
Birincil istisnalar
Tahmine dayalı içerik yükleme işlemi başarısız olduğunda hata işleyiciniz, belirli hata senaryolarını teşhis etmenize yardımcı olmak için aşağıdaki temel istisna türlerinden birini bildirir:
PrefetchException: Tüm eşzamansız önceden getirme hataları için temel sınıf.PrefetchNetworkException: Ağ veya sunucu düzeyinde bir hata olduğunu gösterir. Sunucu tarafındaki sorunların teşhis edilmesine yardımcı olmak içinhttpStatusCodealanı (ör. 404 veya 503) içerebilir.PrerenderException: Bellek baskısı veya arka planda izin verilmeyen API'lerin (ör. ses oynatma) kullanılması nedeniyle oluşan hatalar gibi önceden oluşturma ile ilgili tüm hataların üst sınıfı.
Optimizasyon stratejileri
Sistem kaynaklarını korurken tahmine dayalı içeriğin avantajlarından en iyi şekilde yararlanmak için aşağıdaki önerileri uygulayın:
- Erken başlatma: Uygulama başlatılırken veya bir gezinme hedefi olası olduğu anda önceden getirme işlemini başlatın.
- Entegre strateji: Önceden getirme önbelleğinde bulunan bir URL'yi önceden oluşturursanız önceden oluşturulan gezinme, bu önbellekten sunulur ve gereksiz ağ istekleri önlenir.
- Kotaları izleme: Önceden oluşturma, kaynak açısından yoğun bir işlemdir. Birkaç olası aday için önceden getirmeyi tercih edin ve önceden oluşturmayı en olası tek gezinme için ayırın.
- Şema desteği: Tüm URL'lerin zorunlu HTTPS şemasını kullandığından emin olun. Geçersiz şemalar veya boş girişler, senkronize bir
IllegalArgumentExceptiontetikler.
Ek kaynaklar
Web uygulamalarında hata ayıklama, WebView başlatma performansını optimize etme ve oluşturucu işlemi sonlandırmayı işleme hakkında daha fazla bilgi edinmek için aşağıdaki kaynaklara bakın:
- Web uygulamalarında hata ayıklama
- WebView başlatma işlemini optimize etme
- WebView oluşturucu işleminin sonlandırılmasını işleme