WebView में अनुमान के हिसाब से यूआरएल लोड होने की सुविधा

नेविगेशन में लगने वाला समय, उपयोगकर्ता अनुभव के लिए एक अहम मेट्रिक है. डेवलपर को इस इंतज़ार के समय को कम करने में मदद करने के लिए, WebView, अनुमान के हिसाब से यूआरएल लोड होने की सुविधा और कनेक्शन ऑप्टिमाइज़ेशन के लिए एपीआई उपलब्ध कराता है. इससे आपका ऐप्लिकेशन, उपयोगकर्ता के कॉन्टेंट पर साफ़ तौर पर नेविगेट करने से पहले ही, कॉन्टेंट को फ़ेच या रेंडर कर सकता है.

WebView में तीन तरह की अनुमान के हिसाब से यूआरएल लोड होने की सुविधा मिलती है: प्रीकनेक्ट, प्रीफ़ेच, और प्रीरेंडर. साथ ही, प्रोटोकॉल नेगोशिएशन को ऑप्टिमाइज़ करने के लिए QUIC हिंट की सुविधा भी मिलती है.

अनुमान के हिसाब से यूआरएल लोड होने की सुविधा की रणनीति लागू करके, ये काम किए जा सकते हैं:

  • वेब कॉन्टेंट लोड होने में लगने वाले समय में काफ़ी कमी: नेटवर्क शुरू होने के समय को ऐप्लिकेशन के लाइफ़साइकल में पहले ले जाएं. साथ ही, HTTP/3 जैसे तेज़ प्रोटोकॉल का इस्तेमाल करें.
  • नेविगेशन के बेहतर नतीजे: नेटवर्क और कैश मेमोरी को पहले से तैयार करने से, नेटवर्क की कुछ समय के लिए होने वाली समस्याओं की वजह से नेविगेशन के नतीजे खराब होने की आशंका कम हो जाती है.
  • बेहतर रिस्पॉन्सिवनेस: खास तौर पर, प्रीरेंडरिंग की मदद से तुरंत ट्रांज़िशन किए जा सकते हैं. इससे ऐप्लिकेशन काफ़ी तेज़ी से काम करता है.

अनुमान के हिसाब से यूआरएल लोड होने की सुविधा की रणनीति चुनें

इन रणनीतियों के बीच मुख्य अंतर, इनके स्कोप में है: प्रीकनेक्ट और QUIC हिंट एपीआई, ऑरिजिन पर आधारित होते हैं. इसका मतलब है कि इनके लिए सिर्फ़ टारगेट डोमेन की ज़रूरत होती है. प्रीफ़ेच और प्रीरेंडर एपीआई, यूआरएल पर आधारित होते हैं. इसका मतलब है कि इनके लिए, वेबपेज का सटीक पाथ ज़रूरी होता है.

प्रीकनेक्ट और QUIC के सुझाव, ऑरिजिन लेवल पर काम करते हैं. इसलिए, इन्हें ऐप्लिकेशन के लाइफ़साइकल में बहुत पहले शुरू किया जा सकता है. यहां तक कि इससे पहले कि आपको यह पता चले कि उपयोगकर्ता किस कॉन्टेंट या पेज पर जाएगा.

यहां दी गई टेबल में, इन तीनों रणनीतियों की तुलना की गई है. इससे आपको अपने इस्तेमाल के उदाहरण के लिए सही रणनीति चुनने में मदद मिलेगी:

सुविधा प्रीकनेक्ट प्रीफ़ेच पहले से रेंडर करना
प्राइमरी लक्ष्य कनेक्शन को वॉर्म अप करना सिर्फ़ एचटीएमएल को कैश मेमोरी में सेव करें (JavaScript या सीएसएस के बिना) पूरे पेज को पहले से रेंडर करना
स्कोप प्रोफ़ाइल लेवल (सभी वेबव्यू में शेयर की जाती है) प्रोफ़ाइल लेवल (सभी वेबव्यू में शेयर की जाती है) वेबव्यू लेवल (किसी खास वेबव्यू से जुड़ा हुआ)
Jetpack WebKit API androidx.webkit.Profile androidx.webkit.Profile androidx.webkit.WebViewCompat
मुख्य एपीआई के तरीके preconnect(...) prefetchUrlAsync(...) prerenderUrlAsync(...)
कॉन्फ़िगरेशन लागू नहीं PrefetchCache.setMaxPrefetches()
PrefetchCache.setPrefetchTtlSeconds()
setMaxPrerenders()
संसाधन का इस्तेमाल कम (नेटवर्क) मीडियम (नेटवर्क, मेमोरी) ज़्यादा (सीपीयू, मेमोरी, नेटवर्क)
कब इस्तेमाल करें जब टारगेट ऑरिजिन का पता हो, लेकिन यूआरएल का पता न हो. जब सटीक यूआरएल पता हो और नेविगेशन की संभावना हो. साथ ही, WebViews के बीच कैश मेमोरी शेयर की गई हो. जब सटीक यूआरएल पता हो और किसी खास वेबव्यू में नेविगेशन की संभावना ज़्यादा हो.
फ़ायदे ऑरिजिन पर मौजूद किसी भी यूआरएल के लिए, कनेक्शन को तेज़ी से सेटअप किया जा सकता है मैच किए गए यूआरएल के लिए, नेटवर्क को तेज़ी से लोड करना ऐक्टिवेट करने पर, तुरंत नेविगेशन की सुविधा मिलती है

ऑरिजिन से पहले से कनेक्ट करना

प्रीकनेक्ट करने से, आने वाले समय में लोड होने की प्रोसेस तेज़ हो जाती है. ऐसा इसलिए होता है, क्योंकि यह किसी तय किए गए ऑरिजिन के लिए, डीएनएस लुकअप और टीसीपी/टीएलएस या क्विक हैंडशेक पहले से ही कर लेता है.

प्रीफ़ेच और प्रीरेंडर के उलट, प्रीकनेक्ट पूरी तरह से ऑरिजिन पर आधारित होता है. प्रीफ़ेच और प्रीरेंडर के लिए, डेस्टिनेशन का सटीक यूआरएल ज़रूरी होता है. इससे प्रीफ़ेच और प्रीरेंडर की तुलना में, प्रीकनेक्ट कॉल को बहुत पहले किया जा सकता है.

प्रोफ़ाइल-लेवल की यह रणनीति, कम संसाधनों का इस्तेमाल करती है. इससे किसी भी ऐसी प्रोफ़ाइल के लिए शुरुआती लेटेन्सी कम हो जाती है जो WebView शेयर करती है. हालांकि, इसके लिए ज़रूरी है कि ओरिजिन पर पहले कभी न जाया गया हो. कनेक्शन करीब 30 सेकंड तक खुला रहता है. इससे बाद के किसी भी क्रॉस-ऑरिजिन एचटीटीपी अनुरोधों, नेविगेशन या सब-रिसोर्स को फ़ायदा मिलता है. ऐसा हैंडशेक के ओवरहेड को कम करके किया जाता है.

लागू करना

प्रीकनेक्शन शुरू करने के लिए, preconnect(String url) को Profile इंस्टेंस पर कॉल करें. इस एपीआई को यूज़र इंटरफ़ेस (यूआई) थ्रेड पर कॉल किया जाना चाहिए. साथ ही, इसके लिए WebViewFeature.PRECONNECT का इस्तेमाल किया जाना चाहिए.

एपीआई, ऑरिजिन पर काम करता है. हालांकि, आसानी के लिए पूरा यूआरएल दिया जा सकता है. जैसे, https://www.example.com/index.html. इसे अपने-आप ऑरिजिन पर कॉल माना जाता है. जैसे, https://www.example.com. इस एपीआई को कई बार कॉल करके, कई ऑरिजिन कनेक्ट किए जा सकते हैं.

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
}

QUIC प्रोटोकॉल के बारे में जानकारी देने वाले QUIC हिंट की मदद से, QUIC प्रोटोकॉल के साथ काम करने की सुविधा के बारे में बताएं

एचटीटीपी/3, क्यूयूआईसी ट्रांसपोर्ट प्रोटोकॉल पर काम करता है. यह एचटीटीपी/2 की तुलना में, लेटेंसी को काफ़ी कम करता है. इसमें 0-आरटीटी हैंडशेक, कनेक्शन की बेहतर रीसिलियंस, और पैकेट लॉस के दौरान हेड-ऑफ़-लाइन ब्लॉकिंग को खत्म करना शामिल है.

डिफ़ॉल्ट रूप से, WebView सिर्फ़ तब QUIC कनेक्शन बनाने की कोशिश करता है, जब उसे यह पता हो कि ऑरिजिन, QUIC के साथ काम करता है. जैसे, पिछले इंटरैक्शन से मिले Alt-Svc हेडर या डीएनएस HTTPS रिकॉर्ड से. इस जानकारी के बिना, WebView शुरुआती कनेक्शन के लिए HTTP/2 या HTTP/1.1 का इस्तेमाल करता है.

कॉल करने पर, addQuicHints इस प्रोटोकॉल के साथ काम करने की जानकारी पहले से भर जाती है. इससे WebView, बताए गए ऑरिजिन से पहली बार कनेक्ट होने पर ही QUIC का इस्तेमाल करके कनेक्ट हो जाता है.

QUIC के बारे में जानकारी देने वाले हेडर की मदद से पहले से कनेक्ट करना

प्रीकनेक्ट और QUIC, दोनों ही Profile पर ऑरिजिन-लेवल के ऑप्टिमाइज़ेशन हैं. हालांकि, ये दोनों अलग-अलग और एक-दूसरे के साथ काम करने वाली भूमिकाएं निभाते हैं:

  • preconnect: यह कुकी, नेटवर्क कनेक्शन (डीएनएस लुकअप और टीसीपी/टीएलएस या क्विक हैंडशेक) को करीब 30 सेकंड तक चालू रखती है. यह चालू नेटवर्क कनेक्शन को खुला रखता है. इसलिए, यह डिवाइस और नेटवर्क के संसाधनों का इस्तेमाल करता है. इसे उन टारगेट ऑरिजिन के लिए रिज़र्व किया जाना चाहिए जिनके लिए हिट होने की संभावना ज़्यादा होती है.
  • addQuicHints: इससे नेटवर्क पर तुरंत कोई असर नहीं पड़ता. यह Profile नेटवर्क स्टैक की इन-मेमोरी सर्वर प्रॉपर्टी को अपडेट करता है, ताकि प्रोटोकॉल सपोर्ट को रिकॉर्ड किया जा सके. इसमें बहुत कम ओवरहेड होता है. इसलिए, ऐप्लिकेशन के स्टार्टअप के दौरान, एचटीटीपी/3 की सुविधा वाले सभी जाने-पहचाने ओरिजन के लिए, QUIC hints को सुरक्षित तरीके से कॉन्फ़िगर किया जा सकता है.

बेहतर परफ़ॉर्मेंस के लिए, preconnect, prefetchUrlAsync या loadUrl को कॉल करने से पहले, addQuicHints को कॉल करें. इससे यह पक्का होता है कि बाद के सभी प्रीकनेक्ट या पेज के अनुरोध, शुरू से ही HTTP/3 पर बातचीत करें.

लागू करना

QUIC के बारे में जानकारी कॉन्फ़िगर करने के लिए, Profile इंस्टेंस पर addQuicHints(Set<String> urls) को कॉल करें. आपको इस एपीआई को यूज़र इंटरफ़ेस (यूआई) थ्रेड पर कॉल करना होगा. साथ ही, यह पुष्टि करनी होगी कि WebView, WebViewFeature.ADD_QUIC_HINTS_V1 सुविधा के साथ काम करता है.

preconnect की तरह, addQuicHints भी ऑरिजिन पर काम करता है. हालांकि, पूरे यूआरएल (जैसे कि https://www.example.com/index.html) दिए जा सकते हैं. साथ ही, इन्हें अपने-आप ऑरिजिन (https://www.example.com) में बदल दिया जाता है.

यह तरीका ऐडिटिव है: इसे कई बार कॉल करने पर, दिए गए ऑरिजिन Profile में मर्ज हो जाते हैं.

Kotlin

// Must be called on the @UiThread
@OptIn(Profile.ExperimentalAddQuicHints::class)
if (WebViewFeature.isFeatureSupported(WebViewFeature.ADD_QUIC_HINTS_V1)) {
    val quicOrigins = setOf(
        "https://www.example.com",
        "https://api.example.com"
    )
    profile.addQuicHints(quicOrigins)
    // WebView now prioritizes HTTP/3 over QUIC for connections to these origins
}

Java

// Must be called on the @UiThread
// Requires @Profile.ExperimentalAddQuicHints annotation or suppression
if (WebViewFeature.isFeatureSupported(WebViewFeature.ADD_QUIC_HINTS_V1)) {
    Set<String> quicOrigins = new HashSet<>(Arrays.asList(
        "https://www.example.com",
        "https://api.example.com"
    ));
    profile.addQuicHints(quicOrigins);
    // WebView now prioritizes HTTP/3 over QUIC for connections to these origins
}

सामान्य कॉन्फ़िगरेशन: PrefetchParameters और PrerenderParameters

प्रीफ़ेच और प्रीरेंडर, दोनों ही अनुरोध को पसंद के मुताबिक बनाने के लिए PrefetchParameters या PrerenderParameters का इस्तेमाल करते हैं. इन क्लास की मदद से, यूआरएल मैचिंग के लिए अतिरिक्त हेडर और हिंट दिए जा सकते हैं. जैसे, No-Vary-Search कॉन्फ़िगरेशन.

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();

कॉन्टेंट को प्रीफ़ेच करना

प्रीफ़ेचिंग, किसी यूआरएल के मुख्य एचटीएमएल रिसॉर्स को डाउनलोड करती है और उसे प्रोफ़ाइल के नेटवर्क कैश में सेव करती है. वेबव्यू में, Profile ब्राउज़र डेटा के लिए कंटेनर के तौर पर काम करता है. इसमें कुकी, एचटीटीपी कैश मेमोरी, और सर्विस वर्कर शामिल हैं. प्रीफ़ेच, प्रोफ़ाइल-लेवल का ऑपरेशन है. इसलिए, उस प्रोफ़ाइल से जुड़ा कोई भी WebView, कैश मेमोरी में सेव किए गए जवाब का इस्तेमाल कर सकता है.

लागू करना

प्रीफ़ेच शुरू करने के लिए, Profile इंस्टेंस पर prefetchUrlAsync() को कॉल करें. यह ऑपरेशन, सिर्फ़ एचटीटीपीएस स्कीम के साथ काम करता है.

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
            }
        }
    }
);

इंटरसेप्ट करने की प्रोसेस

प्रीफ़ेच करने के लिए WebView के अनुरोध से, shouldInterceptRequest() कॉलबैक के ट्रिगर होने का समय और तरीका बदल जाता है. इससे सीधे तौर पर यह तय होता है कि प्रीफ़ेच किए गए कॉन्टेंट का इस्तेमाल किया जा सकता है या नहीं. इसलिए, दो चरणों वाले लाइफ़साइकल को समझना ज़रूरी है:

डायग्राम में, स्पेकुलेटिव और नेविगेशन फ़ेज़ के दौरान, WebView प्रीफ़ेच इंटरसेप्शन के दो चरणों वाला लाइफ़साइकल दिखाया गया है.
पहली इमेज. WebView प्रीफ़ेच के अनुरोधों और नेविगेशन के लिए, दो चरणों वाला इंटरसेप्शन लाइफ़साइकल.

1. अनुमानित फ़ेज़ (प्रीफ़ेच करने का अनुरोध)

prefetchUrlAsync() को चालू करने पर, WebView बैकग्राउंड में मुख्य एचटीएमएल रिसॉर्स डाउनलोड करता है. इस बैकग्राउंड अनुरोध के लिए, shouldInterceptRequest() को पूरी तरह से छोड़ दिया गया है. कस्टम लॉजिक, अनुमति देने वाले टोकन या हेडर इंजेक्शन, आम तौर पर इंटरसेप्टर में हैंडल किए जाते हैं. हालांकि, इन्हें पहले से फ़ेच किए गए एचटीएमएल संसाधन पर लागू नहीं किया जाता.

2. नेविगेशन फ़ेज़ (उपयोगकर्ता की ओर से चालू किया जाना)

जब ऐप्लिकेशन, यूआरएल पर साफ़ तौर पर नेविगेट करता है (उदाहरण के लिए, WebViewCompat.navigate या loadUrl का इस्तेमाल करके) या उपयोगकर्ता मिलते-जुलते लिंक पर क्लिक करता है, तो WebView यह तय करता है कि क्या वह पहले से फ़ेच की गई कैश मेमोरी का इस्तेमाल कर सकता है:

  • मुख्य एचटीएमएल का आकलन: इस समय, WebView मुख्य एचटीएमएल के लिए shouldInterceptRequest() को ट्रिगर करेगा. प्रीफ़ेच कैश मेमोरी से पेज को सही तरीके से दिखाने के लिए, आपके इंटरसेप्टर को null वैल्यू दिखानी होगी. कस्टम WebResourceResponse को वापस करने पर, WebView आपके इंटरसेप्टर का पालन करता है और प्रीफ़ेच कैश को पूरी तरह से बायपास कर देता है.

  • सब-रिसॉर्स का आकलन: प्रीफ़ेच किए गए एचटीएमएल का इस्तेमाल करने की अनुमति मिलने के बाद, shouldInterceptRequest() आम तौर पर उन सभी सब-रिसॉर्स के लिए ट्रिगर होता है जिनकी ज़रूरत पेज को रेंडर करने के लिए होती है. जैसे, इमेज, स्क्रिप्ट, और सीएसएस.

मुख्य व्यवहार

यहां दी गई परिचालन से जुड़ी विशेषताएं और ज़रूरी शर्तें तय करती हैं कि WebView, प्रीफ़ेच करने के अनुरोधों को कैसे शुरू करता है और उन्हें कैसे मैनेज करता है:

  • थ्रेड सेफ़्टी: अनुरोध किसी भी थ्रेड से शुरू किए जा सकते हैं.
  • ज़रूरी शर्तें: फ़ेच करने की प्रोसेस शुरू करने से पहले, WebView यह पक्का करता है कि अनुरोध सुरक्षित है और कॉन्टेक्स्ट के हिसाब से सही है. इसके लिए, वह इन बातों की जांच करता है:
    • मौजूदा कुकी: उपयोगकर्ता की निजता की सुरक्षा करने और सीएसआरएफ़ जैसे साइड इफ़ेक्ट को रोकने के लिए, WebView प्रीफ़ेच करने की सुविधा को बंद कर सकता है. ऐसा तब होता है, जब अनुरोध के लिए पुष्टि की गई खास कुकी की ज़रूरत होती है. इससे सर्वर पर स्थिति में बदलाव हो सकता है.
    • सर्विस वर्कर की मौजूदगी: अगर कोई सर्विस वर्कर पहले से ही यूआरएल के स्कोप को कंट्रोल कर रहा है, तो WebView, स्टैंडर्ड नेटवर्क प्रीफ़ेच शुरू करने के बजाय, सर्विस वर्कर के फ़ेच हैंडलर को कॉल कर सकता है.
    • प्रॉक्सी की उपलब्धता: WebView यह पुष्टि करता है कि मौजूदा नेटवर्क पाथ (इसमें कॉन्फ़िगर की गई कोई भी प्रॉक्सी शामिल है) स्थिर है, ताकि जटिल नेटवर्क कॉन्फ़िगरेशन के तहत अनुमानित अनुरोध पूरे किए जा सकें.
  • अगर मान्य पैरामीटर होने के बावजूद प्रीफ़ेच शुरू नहीं होता है, तो इसकी वजह यह हो सकती है कि WebView ने यह तय किया है कि बैकग्राउंड अनुरोध, उपयोगकर्ता के मौजूदा सेशन या सुरक्षा की स्थिति में रुकावट डाल सकता है.
  • रद्द करना: फ़्लाइट में किए गए अनुरोध को बंद करने और उसे कैश मेमोरी में सेव होने से रोकने के लिए, CancellationSignal का इस्तेमाल करें.

पेजों को पहले से रेंडर करना

प्रीरेंडरिंग, छिपे हुए "वेब कॉन्टेंट" बनाती है, ताकि पेज को बैकग्राउंड में पूरी तरह से रेंडर किया जा सके. इसमें स्क्रिप्ट को लागू करना और सब-रिसोर्स फ़ेच करना शामिल है. प्रीरेंडरिंग, प्रीफ़ेचिंग के लिए इस्तेमाल किए जाने वाले इन्फ़्रास्ट्रक्चर पर ही काम करती है. अगर कोई ऐप्लिकेशन प्रीरेंडर शुरू करता है, तो WebView पहले जवाब को प्रीफ़ेच करता है, ताकि प्रीरेंडर नेविगेशन को दिखाया जा सके. इससे नेटवर्क की गैर-ज़रूरी गतिविधि से बचा जा सकता है.

लागू करना

प्रीरेंडरिंग, WebView इंस्टेंस-लेवल की कार्रवाई है. यूज़र इंटरफ़ेस (यूआई) थ्रेड से, prerenderUrlAsync() का इस्तेमाल करके WebViewCompat पर कॉल करें.

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).
    }
});

प्रीफ़ेच और प्रीरेंडर, दोनों पूरी तरह से एसिंक्रोनस होते हैं. prefetchUrlAsync() को किसी भी थ्रेड से कॉल किया जा सकता है, जबकि prerenderUrlAsync() को यूज़र इंटरफ़ेस (यूआई) थ्रेड से शुरू किया जाना चाहिए.

तकनीकी सीमाएं

सिस्टम की परफ़ॉर्मेंस को बेहतर बनाए रखने के साथ-साथ, तुरंत नेविगेट करने की सुविधा देने के लिए, WebView रनटाइम के दौरान इन शर्तों को लागू करता है:

  • मेमोरी प्रेशर: अगर डिवाइस में रैम कम है, तो WebView पहले से रेंडर किए गए यूआरएल रद्द कर देता है.
  • अनुमति नहीं दिए गए एपीआई: अगर JavaScript, बैकग्राउंड कॉन्टेक्स्ट में कुछ एपीआई (जैसे, ऑडियो चलाने, सूचनाएं पाने) को ऐक्सेस करने की कोशिश करती है, तो प्रीरेंडरिंग तुरंत बंद हो जाएगी.
  • इंस्टेंस की सीमा: हर WebView के लिए, पहले से रेंडर किए गए यूआरएल की संख्या सीमित होती है.

यूआरएल मैचिंग और No-Vary-Search (NVS)

वेबव्यू को भरोसेमंद मैचिंग एल्गोरिदम की ज़रूरत होती है, ताकि यह पक्का किया जा सके कि प्रीलोड की गई कोई संसाधन सिर्फ़ उसके तय किए गए नेविगेशन के लिए दिखाया जाए.

एग्ज़ैक्ट मैच बनाम एनवीएस मैच

डिफ़ॉल्ट रूप से, प्रीफ़ेच और प्रीरेंडर के लिए, यूआरएल का सटीक मिलान होना ज़रूरी है. अगर नेविगेट किया गया यूआरएल, पहले से लोड किए गए यूआरएल से मेल खाता है, तो उसे तुरंत कैश मेमोरी से दिखाया जाता है. अगर क्वेरी पैरामीटर अलग-अलग हैं, तो WebView, No-Vary-Search (NVS) के इन नियमों का इस्तेमाल करता है:

  • सुझाव: डेवलपर, शुरुआत में setExpectedNoVarySearchHeader() सुझाव देते हैं. अगर नेविगेट किया गया यूआरएल, अनुरोध किए गए यूआरएल से मेल खाता है, तो WebView कुछ समय के लिए ब्लॉक हो जाता है. ऐसा इसलिए होता है, ताकि सर्वर के असली हेडर का इंतज़ार किया जा सके. हालांकि, अनुरोध किए गए यूआरएल में से सुझाई गई जानकारी वाले पैरामीटर हटा दिए जाते हैं.
  • सर्वर हेडर: सर्वर से मिला NVS रिस्पॉन्स हेडर, सबसे ज़्यादा भरोसेमंद होता है. अगर सर्वर पुष्टि करता है कि क्वेरी में अंतर को अनदेखा किया जाना चाहिए, तो मैच को कैश मेमोरी से दिखाया जाता है. अगर ऐसा नहीं होता है, तो WebView, कोल्ड नेटवर्क लोड पर वापस आ जाता है.

No-Vary-Search (NVS) का इस्तेमाल सिर्फ़ खास मामलों में किया जाता है. ज़्यादातर डेवलपर को इसकी ज़रूरत नहीं पड़ती, क्योंकि वे प्रीफ़ेच और नेविगेशन (WebViewCompat.navigate या loadUrl) के लिए एक ही यूआरएल पास करते हैं. यह दिशा-निर्देश सिर्फ़ तब ज़रूरी होता है, जब प्रीफ़ेच यूआरएल और नेविगेट किए गए यूआरएल के क्वेरी पैरामीटर में अंतर हो.

ग्लोबल कॉन्फ़िगरेशन

प्रोफ़ाइल लेवल पर, अनुमान के हिसाब से यूआरएल लोड होने की सुविधा को बेहतर बनाएं. इसके लिए, PrefetchCache सीमाएं और ज़्यादा से ज़्यादा प्रीरेंडर कॉन्फ़िगर करें. कस्टम प्रीफ़ेच की सीमाओं को सिस्टम की डिफ़ॉल्ट सेटिंग पर भी रीसेट किया जा सकता है:

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);

गड़बड़ी ठीक करना और अपवाद

अनुमानित कार्रवाइयों के नतीजे दिखाने के लिए, OutcomeReceiverCompat या PrerenderOperationCallback का इस्तेमाल किया जाता है.

मुख्य अपवाद

जब अनुमान के हिसाब से यूआरएल लोड होने की सुविधा की प्रोसेस पूरी नहीं होती है, तो गड़बड़ी हैंडल करने वाला आपका प्रोग्राम, यहां दिए गए मुख्य अपवादों में से किसी एक के बारे में बताता है. इससे आपको गड़बड़ी की खास वजहों का विश्लेषण करने में मदद मिलती है:

  • PrefetchException: यह एसिंक्रोनस प्रीफ़ेच से जुड़ी सभी गड़बड़ियों के लिए बेस क्लास है.
  • PrefetchNetworkException: इससे नेटवर्क या सर्वर लेवल पर होने वाली गड़बड़ी का पता चलता है. इसमें httpStatusCode फ़ील्ड (जैसे, 404 या 503) शामिल हो सकता है, ताकि सर्वर-साइड की समस्याओं का पता लगाने में मदद मिल सके.
  • PrerenderException: यह प्रीरेंडरिंग से जुड़ी सभी गड़बड़ियों के लिए सुपरक्लास है. जैसे, मेमोरी पर ज़्यादा दबाव पड़ने या बैकग्राउंड में अनुमति न दिए गए एपीआई (जैसे, ऑडियो चलाने की सुविधा) का इस्तेमाल करने की वजह से प्रीरेंडरिंग में होने वाली गड़बड़ियां.

ऑप्टिमाइज़ेशन की रणनीतियां

सिस्टम के संसाधनों को बचाते हुए, अनुमान के हिसाब से यूआरएल लोड होने की सुविधा के फ़ायदों को ज़्यादा से ज़्यादा पाने के लिए, इन सुझावों का पालन करें:

  • जल्द शुरू करें: ऐप्लिकेशन के चालू होने के दौरान या नेविगेशन डेस्टिनेशन के जल्द ही दिखने की संभावना होने पर, प्रीफ़ेचिंग शुरू करें.
  • QUIC के सुझावों को कनेक्शन प्री-वार्मिंग के साथ जोड़ें: preconnect(), prefetchUrlAsync() या स्टैंडर्ड नेविगेशन शुरू करने से पहले addQuicHints() को कॉल करें, ताकि यह पक्का किया जा सके कि WebView, HTTP/3 का इस्तेमाल करके कनेक्शन बनाने की कोशिश करे.
  • इंटिग्रेटेड रणनीति: अगर आपने प्रीफ़ेच कैश में मौजूद किसी यूआरएल को पहले से ही प्रीरेंडर किया है, तो प्रीरेंडर नेविगेशन को उस कैश से दिखाया जाता है. इससे नेटवर्क के गैर-ज़रूरी अनुरोध नहीं किए जाते.
  • कोटा पर नज़र रखें: प्रीरेंडरिंग में बहुत ज़्यादा संसाधनों का इस्तेमाल होता है. कई संभावित उम्मीदवारों के लिए प्रीफ़ेचिंग को प्राथमिकता दें और सबसे संभावित नेविगेशन के लिए प्रीरेंडरिंग को रिज़र्व करें.
  • स्कीम का इस्तेमाल: पक्का करें कि सभी यूआरएल में, एचटीटीपीएस स्कीम का इस्तेमाल किया गया हो. अमान्य स्कीम या शून्य इनपुट से, सिंक्रोनस IllegalArgumentException ट्रिगर होता है.

अन्य संसाधन

वेब ऐप्लिकेशन को डीबग करने, WebView के स्टार्टअप की परफ़ॉर्मेंस को ऑप्टिमाइज़ करने, और रेंडरर प्रोसेस के बंद होने की समस्या को ठीक करने के बारे में ज़्यादा जानने के लिए, यहां दिए गए संसाधन देखें: