ব্যবহারকারীর অভিজ্ঞতার জন্য নেভিগেশন ল্যাটেন্সি একটি গুরুত্বপূর্ণ মেট্রিক। এই লেটেন্সি কমাতে ডেভেলপারদের সাহায্য করতে, WebView, স্পেকুলেটিভ লোডিং ও কানেকশন অপ্টিমাইজেশনের জন্য API প্রদান করে। এর ফলে, ব্যবহারকারী স্পষ্টভাবে নেভিগেট করার আগেই আপনার অ্যাপ কন্টেন্ট ফেচ বা রেন্ডার করতে পারে।
WebView-তে তিন ধরনের প্রাথমিক স্পেকুলেটিভ লোডিং কাজ করে: প্রিকানেক্ট, প্রিফেচ ও প্রি-রেন্ডার। এর পাশাপাশি, প্রোটোকল নেগোসিয়েশন অপ্টিমাইজ করার জন্য QUIC হিন্টও কাজ করে।
স্পেকুলেটিভ লোডিং কৌশল প্রয়োগ করে, আপনি নিম্নলিখিত বিষয়গুলি অর্জন করতে পারবেন:
- ওয়েব কন্টেন্ট লোড হওয়ার লেটেন্সি উল্লেখযোগ্যভাবে কমে যাওয়া: নেটওয়ার্ক শুরু হওয়ার সময়কে অ্যাপ লাইফসাইকেলে আরও আগে নিয়ে যান এবং HTTP/3-এর মতো আরও দ্রুত প্রোটোকল ব্যবহার করুন।
- নেভিগেশন সাফল্যের হার বেশি: নেটওয়ার্ক ও ক্যাশে আগে থেকে গরম করার মাধ্যমে, ক্ষণস্থায়ী নেটওয়ার্ক সমস্যার কারণে নেভিগেশন ব্যর্থ হওয়ার সম্ভাবনা কমে যায়।
- আরও ভালো রেসপন্সিভনেস: বিশেষ করে, প্রি-রেন্ডারিংয়ের মাধ্যমে ইনস্ট্যান্ট ট্রানজিশন চালু করা যায়, যার ফলে অ্যাপ অনেক বেশি দ্রুত মনে হয়।
স্পেকুলেটিভ লোডিং স্ট্র্যাটেজি বেছে নিন
এইসব কৌশলগুলির মধ্যে মূল পার্থক্য হল তাদের স্কোপ: প্রি-কানেক্ট এবং QUIC হিন্ট API হল অরিজিন-ভিত্তিক, যার অর্থ হল এগুলির জন্য শুধুমাত্র টার্গেট ডোমেন প্রয়োজন। প্রিফেচ ও প্রিরেন্ডার API হল URL-ভিত্তিক, যার অর্থ হল এগুলির জন্য ওয়েবপেজের সঠিক পাথ প্রয়োজন।
প্রিকানেক্ট ও QUIC হিন্ট অরিজিন লেভেলে কাজ করে বলে, ব্যবহারকারী কোন নির্দিষ্ট কন্টেন্ট বা পৃষ্ঠায় নেভিগেট করবেন তা জানার আগেই আপনি এগুলিকে কল করতে পারবেন।
নিচের টেবিলে এই তিনটি কৌশল তুলনা করে দেখানো হয়েছে, যাতে আপনি নিজের ব্যবহারের ক্ষেত্রে সঠিক কৌশল বেছে নিতে পারেন:
| ফিচার | প্রিকানেক্ট | প্রিফেচ | প্রিরেন্ডার |
|---|---|---|---|
| প্রাথমিক লক্ষ্য | কানেকশন ওয়ার্ম-আপ করা | শুধুমাত্র HTML ক্যাশে করা (JavaScript বা CSS ছাড়া) | সম্পূর্ণ পৃষ্ঠা প্রি-রেন্ডার করা |
| স্কোপ | প্রোফাইল লেভেল (WebView জুড়ে শেয়ার করা হয়) | প্রোফাইল লেভেল (WebView জুড়ে শেয়ার করা হয়) | WebView লেভেল (নির্দিষ্ট WebView-এর সাথে আবদ্ধ) |
| Jetpack WebKit API | androidx.webkit.Profile |
androidx.webkit.Profile |
androidx.webkit.WebViewCompat |
| কোর API পদ্ধতি | preconnect(...) |
prefetchUrlAsync(...) |
prerenderUrlAsync(...) |
| কনফিগারেশন | N/A | PrefetchCache.setMaxPrefetches()PrefetchCache.setPrefetchTtlSeconds() |
setMaxPrerenders() |
| রিসোর্স ব্যবহার | কম (নেটওয়ার্ক) | মাঝারি (নেটওয়ার্ক, মেমরি) | হাই (সিপিইউ, মেমরি, নেটওয়ার্ক) |
| কখন ব্যবহার করতে হবে | টার্গেট অরিজিন জানা থাকলে, কিন্তু নির্দিষ্ট URL এখনও নির্ধারণ করা না থাকলে। | নির্দিষ্ট URL জানা থাকলে এবং নেভিগেশন সম্ভব হলে, WebView জুড়ে ক্যাশিং শেয়ার করা হয়। | যখন সঠিক URL জানা থাকে এবং নির্দিষ্ট WebView-এর মধ্যে নেভিগেশন অত্যন্ত নিশ্চিত হয়। |
| সুবিধা | অরিজিনে থাকা যেকোনও URL-এর জন্য দ্রুত কানেকশন সেট-আপ করা | ম্যাচ করা URL-এর জন্য দ্রুত নেটওয়ার্ক লোড | চালু করার সাথে সাথেই নেভিগেশন শুরু করা যায় |
অরিজিনের সাথে আগে থেকে কানেক্ট করা
প্রি-কানেক্ট করা হলে, নির্দিষ্ট অরিজিনের জন্য DNS লুক-আপ এবং TCP/TLS বা QUIC হ্যান্ডশেক আগে থেকেই পারফর্ম করার মাধ্যমে ভবিষ্যতে লোড করার প্রসেস দ্রুততর হয়।
প্রিফেচ ও প্রিরেন্ডারের ক্ষেত্রে গন্তব্যের URL হুবহু হতে হয়, কিন্তু প্রিকানেক্টের ক্ষেত্রে শুধু অরিজিন URL হলেই চলে। এর ফলে আপনি সঠিক URL জানার আগেই Preconnect-এ কল করতে পারবেন। কখন কল করতে হবে সেই বিষয়ে নির্দেশিকা পেতে, প্রয়োগ বিভাগে পরামর্শ দেখুন।
এই কম-রিসোর্স, প্রোফাইল-লেভেল স্ট্র্যাটেজি, সেই প্রোফাইল শেয়ার করা যেকোনও WebView-এর জন্য প্রাথমিক লেটেন্সি কমায়, যদি অরিজিন আগে থেকেই ভিজিট করা না হয়ে থাকে। কানেকশনটি আনুমানিক ৩০ সেকেন্ড খোলা থাকে, এর ফলে হ্যান্ডশেক ওভারহেড বাদ দিয়ে পরবর্তী ক্রস-অরিজিন HTTP অনুরোধ, নেভিগেশন বা সাবরিসোর্স উপকার পায়। DNS লুক-আপ ফলাফল কানেকশনের চেয়ে বেশি সময় ধরে ক্যাশে করা হয়, তাই কানেকশন বন্ধ হয়ে যাওয়ার পরেও পরবর্তী অনুরোধে অরিজিন লুক-আপ এখনও এড়িয়ে যাওয়া যেতে পারে।
প্রয়োগ
প্রিকানেকশন শুরু করতে, Profile
ইনস্ট্যান্সে preconnect(String url) কল করুন। এই API-কে UI থ্রেডে কল করতে হবে এবং এর জন্য
WebViewFeature.PRECONNECT কাজ করতে হবে।
API অরিজিনে কাজ করে, তবে সুবিধার জন্য সম্পূর্ণ URL প্রদান করা যেতে পারে
(যেমন https://www.example.com/index.html)। এটি অটোমেটিক অরিজিনে কল করা হিসেবে
বিবেচনা করা হয় (যেমন, https://www.example.com)। এই API একাধিকবার কল করে একাধিক অরিজিন
কানেক্ট করা যেতে পারে।
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
}
জাভা
// 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 প্রোটোকল কাজ করে বলে ইঙ্গিত দেওয়া
HTTP/3 (যা QUIC ট্রান্সপোর্ট প্রোটোকলের উপর চলে) HTTP/2-এর তুলনায় উল্লেখযোগ্যভাবে লেটেন্সি উন্নত করে, যার মধ্যে রয়েছে ০-RTT হ্যান্ডশেক, উন্নত কানেকশন রেজিলিয়েন্স এবং প্যাকেট লস চলাকালীন হেড-অফ-লাইন ব্লকিংয়ের এলিমিনেশন।
সাধারণত, WebView তখনই QUIC কানেকশন করার চেষ্টা করে যখন এটি বুঝতে পারে যে
অরিজিন QUIC-এ কাজ করে, যেমন Alt-Svc হেডার বা DNS HTTPS রেকর্ড
থেকে আগের ইন্টার্যাকশন। এই পূর্ব জ্ঞান না থাকলে, WebView প্রাথমিক কানেকশনের জন্য HTTP/2
বা HTTP/1.1 ব্যবহার করে।
কলিং addQuicHints এই প্রোটোকল সংক্রান্ত তথ্য আগে থেকেই পূরণ করে দেয়, এর ফলে
নির্দিষ্ট অরিজিনের সাথে প্রথম কানেকশনের সময়েই WebView QUIC ব্যবহার করে কানেক্ট
করতে পারে।
QUIC হিন্টের মাধ্যমে আগে থেকে কানেক্ট করা
প্রিকানেক্ট ও QUIC হিন্ট, দুটিই হল
Profile-এ অরিজিন-লেভেল অপ্টিমাইজেশন, তবে এগুলি আলাদা আলাদা, পরিপূরক ভূমিকা পালন করে:
preconnect: প্রায় ৩০ সেকেন্ডের জন্য অ্যাক্টিভভাবে নেটওয়ার্ক কানেকশন (DNS লুক-আপ এবং TCP/TLS বা QUIC হ্যান্ডশেক) খোলে ও বজায় রাখে। কারণ এটি চালু থাকা অ্যাক্টিভ নেটওয়ার্ক কানেকশন ধরে রাখে, এটি ডিভাইস ও নেটওয়ার্ক সম্পদ ব্যবহার করে এবং বেশি সম্ভাবনাযুক্ত টার্গেট অরিজিনের জন্য রিজার্ভ করা উচিত।addQuicHints: কোনও তাৎক্ষণিক নেটওয়ার্ক ট্রাফিক তৈরি করে না। এটি প্রোটোকল সাপোর্ট রেকর্ড করতেProfileনেটওয়ার্ক স্ট্যাকের ইন-মেমরি সার্ভার প্রপার্টি আপডেট করে। কারণ, এতে খুব কম ওভারহেড থাকে, তাই আপনি সব পরিচিত HTTP/3-এর উপযুক্ত অরিজিনের জন্য অ্যাপ চালু করার সময় নিরাপদে QUIC হিন্ট কনফিগার করতে পারবেন।
সবথেকে ভালো পারফর্ম্যান্সের জন্য, preconnect,
prefetchUrlAsync বা loadUrl-এ কল করার আগে addQuicHints-এ কল করুন। এর ফলে, পরবর্তীকালে কোনও প্রিকানেক্ট বা
পৃষ্ঠার অনুরোধ শুরু থেকেই HTTP/3-এর মাধ্যমে নেগোশিয়েট করা হয়।
প্রয়োগ
QUIC ইঙ্গিত কনফিগার করতে, Profile
ইনস্ট্যান্সে addQuicHints(Set<String> urls) কল করুন। আপনাকে UI থ্রেডে এই API কল করতে হবে এবং WebView
WebViewFeature.ADD_QUIC_HINTS_V1 ফিচার কাজ করে কিনা তা যাচাই করতে হবে।
preconnect-এর মতো, addQuicHints অরিজিনে কাজ করে, কিন্তু সম্পূর্ণ URL প্রদান করা
যায় (যেমন 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
}
জাভা
// 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 ব্যবহার করে। এইসব ক্লাস আপনাকে URL ম্যাচিংয়ের জন্য
অতিরিক্ত হেডার ও ইঙ্গিত প্রদান করতে দেয়, যেমন 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()
জাভা
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();
কন্টেন্ট প্রিফেচ করা
প্রিফেচিং কোনও URL-এর মূল HTML রিসোর্স ডাউনলোড করে এবং সেটি
প্রোফাইলের নেটওয়ার্ক ক্যাশে সেভ করে। WebView-তে, Profile ব্রাউজার
ডেটার কন্টেনার হিসেবে কাজ করে, যার মধ্যে কুকি, HTTP ক্যাশে ও সার্ভিস ওয়ার্কার অন্তর্ভুক্ত। কারণ প্রিফেচ হল একটি
প্রোফাইল-লেভেল অপারেশন, সেই প্রোফাইলের সাথে যুক্ত যেকোনও WebView ক্যাশে করা উত্তরকে
ব্যবহার করতে পারে।
প্রয়োগ
প্রিফেচ শুরু করতে, Profile ইনস্ট্যান্সে prefetchUrlAsync() কল করুন। এই
অপারেশন শুধুমাত্র HTTPS স্কিম সাপোর্ট করে।
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
}
}
}
}
)
জাভা
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()
কলব্যাক কখন ও কীভাবে ট্রিগার করা হবে তা পরিবর্তন করে। কারণ, আপনার
প্রিফেচ করা কন্টেন্ট সফলভাবে ব্যবহার করা যাবে কিনা, তার উপর এটি সরাসরি প্রভাব ফেলে। তাই, এই
দুটি ধাপের লাইফসাইকেল বোঝা অত্যন্ত গুরুত্বপূর্ণ:
১. অনুমানমূলক ফেজ (প্রিফেচ অনুরোধ)
prefetchUrlAsync() ইনভোক করা হলে, WebView ব্যাকগ্রাউন্ডে মূল HTML রিসোর্স
ডাউনলোড করে। এই ব্যাকগ্রাউন্ড অনুরোধের জন্য shouldInterceptRequest() সম্পূর্ণভাবে এড়িয়ে যাওয়া হয়েছে। সাধারণত আপনার ইন্টারসেপ্টরের মধ্যে হ্যান্ডেল করা হয় এমন কোনও কাস্টম লজিক, অনুমোদন টোকেন বা হেডার ইনজেকশন
প্রিফেচ করা HTML
রিসোর্সে প্রয়োগ করা হয় না।
২. নেভিগেশন ফেজ (ব্যবহারকারী অ্যাক্টিভেশন)
অ্যাপটি যখন স্পষ্টভাবে URL-এ নেভিগেট করে (যেমন, WebViewCompat.navigate বা loadUrl ব্যবহার করে) অথবা ব্যবহারকারী মিলে যাওয়া
লিঙ্কে ক্লিক করেন, তখন WebView নির্ধারণ করে যে এটি প্রিফেচ করা ক্যাশে ব্যবহার করতে পারবে কিনা:
মূল HTML মূল্যায়ন: WebView এই মুহূর্তে মূল HTML-এর জন্য
shouldInterceptRequest()ট্রিগার করবে। প্রিফেচ ক্যাশে থেকে পৃষ্ঠাটি সঠিকভাবে পরিবেশন করতে, আপনার ইন্টারসেপ্টরকে অবশ্যইnullরিটার্ন করতে হবে। আপনি কাস্টমWebResourceResponseফেরত দিলে, WebView আপনার ইন্টারসেপ্টরকে সম্মান করে এবং প্রিফেচ ক্যাশে সম্পূর্ণভাবে বাইপাস করে।সাব-রিসোর্স মূল্যায়ন: প্রিফেচ করা HTML ব্যবহারের জন্য পরিষ্কার করার পরে,
shouldInterceptRequest()পৃষ্ঠা রেন্ডার করা সম্পূর্ণ করার জন্য প্রয়োজনীয় পরবর্তী সব সাব-রিসোর্সের (যেমন, ছবি, স্ক্রিপ্ট ও CSS) জন্য স্বাভাবিকভাবে ট্রিগার করে।
গুরুত্বপূর্ণ আচরণ
WebView কীভাবে প্রিফেচ অনুরোধ শুরু ও ম্যানেজ করে তা নিম্নলিখিত অপারেশনাল বৈশিষ্ট্য ও যোগ্যতা যাচাইকরণ দ্বারা পরিচালিত হয়:
- থ্রেড নিরাপত্তা: যেকোনও থ্রেড থেকে অনুরোধ শুরু করা যেতে পারে।
- উপযুক্ততা: কোনও ফেচ শুরু করার আগে, WebView নিম্নলিখিত বিষয়গুলি চেক করে দেখে নেয় যে অনুরোধটি
নিরাপদ এবং প্রাসঙ্গিক দিক থেকে উপযুক্ত কিনা:
- আগে থেকে থাকা কুকি: ব্যবহারকারীর গোপনীয়তা রক্ষা করতে এবং CSRF-এর মতো সাইড ইফেক্ট আটকাতে, WebView প্রিফেচিং এড়িয়ে যেতে পারে যদি অনুরোধের জন্য নির্দিষ্ট প্রমাণিত কুকি প্রয়োজন হয় যা সার্ভারে স্টেট পরিবর্তন ট্রিগার করতে পারে।
- সার্ভিস ওয়ার্কারের উপস্থিতি: কোনও সার্ভিস ওয়ার্কার যদি আগে থেকেই URL-এর স্কোপ কন্ট্রোল করে থাকে, তাহলে WebView, স্ট্যান্ডার্ড নেটওয়ার্ক প্রিফেচ শুরু করার পরিবর্তে, সার্ভিস ওয়ার্কারের ফেচ হ্যান্ডলারকে ডিফার করতে পারে।
- প্রক্সি উপলভ্যতা: WebView যাচাই করে যে বর্তমান নেটওয়ার্ক পাথ (এর মধ্যে কনফিগার করা যেকোনও প্রক্সি অন্তর্ভুক্ত) স্থিতিশীল আছে কিনা যাতে জটিল নেটওয়ার্ক কনফিগারেশনের অধীনে অনুমানমূলক অনুরোধ ব্যর্থ না হয়।
- কোনও প্রিফেচ শুরু করা না গেলে (এমনকি সঠিক প্যারামিটার সহ), এটি প্রায়ই এই কারণে হয় যে WebView নির্ধারণ করেছে যে ব্যাকগ্রাউন্ড অনুরোধ ব্যবহারকারীর বর্তমান সেশন বা সুরক্ষা সংক্রান্ত অবস্থার সাথে ইন্টারফেয়ার করতে পারে।
- বাতিল করা: কোনও ইন-ফ্লাইট
অনুরোধ বাতিল করতে এবং সেটি ক্যাশে হওয়া আটকাতে
CancellationSignalব্যবহার করুন।
পৃষ্ঠা প্রি-রেন্ডার করা
প্রিরেন্ডারিং, স্ক্রিপ্ট এক্সিকিউশন ও সাব-রিসোর্স ফেচিং সহ কোনও পৃষ্ঠা সম্পূর্ণভাবে রেন্ডার করার জন্য ব্যাকগ্রাউন্ডে লুকানো "ওয়েব কন্টেন্ট" তৈরি করে। প্রিরেন্ডারিং প্রিফেচিংয়ের মতো একই পরিকাঠামোর উপর নির্ভর করে। কোনও অ্যাপ প্রিরেন্ডার শুরু করলে, WebView প্রথমে প্রিরেন্ডার নেভিগেশন পরিবেশন করার জন্য উত্তরের একটি প্রিফেচ পারফর্ম করে, এর ফলে অপ্রয়োজনীয় নেটওয়ার্ক অ্যাক্টিভিটি এড়ানো যায়।
প্রয়োগ
প্রিরেন্ডারিং হল WebView ইনস্ট্যান্স-লেভেল অপারেশন। UI থ্রেড থেকে WebViewCompat ব্যবহার করে prerenderUrlAsync()-কে কল করুন
।
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)
}
}
)
জাভা
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() অবশ্যই UI থ্রেড থেকে
শুরু করতে হবে।
প্রযুক্তিগত সীমাবদ্ধতা
সিস্টেমের হেল্থের সাথে সাথে ইনস্ট্যান্ট নেভিগেশন ব্যালেন্স করতে, WebView নিম্নলিখিত রানটাইম সীমাবদ্ধতা প্রয়োগ করে:
- মেমরি প্রেসার: ডিভাইসে RAM কম থাকলে WebView আগে থেকে রেন্ডার করা URL বাতিল করে দেয়।
- অননুমোদিত API: ব্যাকগ্রাউন্ড কনটেক্সটে JavaScript-এর মাধ্যমে নির্দিষ্ট API (যেমন, অডিও প্লেব্যাক, অ্যালার্ট) অ্যাক্সেস করার চেষ্টা করা হলে, প্রি-রেন্ডার করার প্রসেস সঙ্গে সঙ্গে বন্ধ করে দেওয়া হবে।
- ইনস্ট্যান্সের সীমা: প্রতিটি WebView-তে অনুমোদিত অ্যাক্টিভ প্রি-রেন্ডার করা URL-এর সংখ্যার একটি সীমা আছে।
URL ম্যাচিং ও নো-ভ্যারি-সার্চ (NVS)
প্রিলোড করা রিসোর্স যাতে শুধুমাত্র তার উদ্দেশ্যপূর্ণ নেভিগেশনের জন্য পরিবেশন করা হয় তা নিশ্চিত করতে WebView-এর একটি নির্ভরযোগ্য ম্যাচিং অ্যালগরিদম প্রয়োজন।
সম্পূর্ণ ম্যাচ বনাম NVS ম্যাচ
ডিফল্ট হিসেবে, প্রিফেচ ও প্রি-রেন্ডারের জন্য URL-এর হুবহু মিল থাকতে হবে। নেভিগেট করা URL, প্রিলোড করা URL-এর মতো হলে, সেটি সঙ্গে সঙ্গে ক্যাশে থেকে পরিবেশন করা হয়। কোয়েরি প্যারামিটার আলাদা হলে, WebView নিম্নলিখিত নো-ভ্যারি-সার্চ (NVS) নিয়ম ব্যবহার করে:
- ইঙ্গিত: শুরু করার সময় ডেভেলপাররা একটি
setExpectedNoVarySearchHeader()ইঙ্গিত প্রদান করেন। নেভিগেট করা URL, অনুরোধ করা URL-এর সাথে মিলে গেলে, তবে সাজেস্ট করা প্যারামিটার বাদ দিয়ে, WebView কিছুক্ষণের জন্য ব্লক হয়ে যায়, যাতে সার্ভারের আসল হেডার পাওয়া যায়। - সার্ভার হেডার: সার্ভার থেকে পাওয়া NVS রেসপন্স হেডারই হল চূড়ান্ত কর্তৃপক্ষ। সার্ভার যদি নিশ্চিত করে যে কোয়েরির পার্থক্য উপেক্ষা করা উচিত, তাহলে ক্যাশে থেকে ম্যাচ পরিবেশন করা হয়। তা না হলে, WebView একটি কোল্ড নেটওয়ার্ক লোডে ফিরে যায়।
No-Vary-Search (NVS) হল উন্নত ব্যবহারের জন্য এবং বেশিরভাগ ডেভেলপারদের এটির প্রয়োজন নাও হতে পারে
কারণ তারা প্রিফেচ ও নেভিগেশন, দু'টির ক্ষেত্রেই একই URL পাস করেন
(WebViewCompat.navigate বা loadUrl)। এই নির্দেশিকা তখনই
প্রয়োজনীয় হয় যখন প্রিফেচ URL
ও নেভিগেট করা URL-এর মধ্যে কোয়েরি প্যারামিটারের পার্থক্য থাকে।
গ্লোবাল কনফিগারেশন
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)
জাভা
// 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: প্রি-রেন্ডার সংক্রান্ত সব সমস্যার সুপারক্লাস, যেমন মেমরি প্রেসার বা ব্যাকগ্রাউন্ডে নিষিদ্ধ API (যেমন অডিও প্লেব্যাক) ব্যবহারের কারণে হওয়া সমস্যা।
অপ্টিমাইজেশন স্ট্র্যাটেজি
সিস্টেম রিসোর্স বাঁচিয়ে রেখে স্পেকুলেটিভ লোডিংয়ের সুবিধা সবচেয়ে বেশি পেতে এইসব সাজেশন অনুসরণ করুন:
- শীঘ্র শুরু করা: অ্যাপ স্টার্ট-আপের সময় বা নেভিগেশন গন্তব্য সম্ভাব্য হওয়ার সাথে সাথেই প্রিফেচিং শুরু করুন।
- কানেকশন প্রি-ওয়ার্মিংয়ের সাথে QUIC হিন্ট পেয়ার করা:
preconnect(),prefetchUrlAsync()বা সাধারণ নেভিগেশন শুরু করার আগেaddQuicHints()কল করুন, যাতে WebView HTTP/3 ব্যবহার করে কানেকশন তৈরি করার চেষ্টা করে। - ইন্টিগ্রেটেড স্ট্র্যাটেজি: আপনি যদি প্রিফেচ ক্যাশে থাকা কোনও URL আগে থেকেই প্রি-রেন্ডার করেন, তাহলে প্রি-রেন্ডার নেভিগেশন সেই ক্যাশে থেকে পরিবেশন করা হয়, এর ফলে অপ্রয়োজনীয় নেটওয়ার্ক অনুরোধ এড়ানো যায়।
- কোটা মনিটর করা: প্রি-রেন্ডারিংয়ের জন্য প্রচুর রিসোর্স প্রয়োজন হয়। একাধিক সম্ভাব্য ক্যান্ডিডেটের জন্য প্রিফেচিং এবং সবচেয়ে বেশি সম্ভাব্য নেভিগেশনের জন্য প্রি-রেন্ডারিং রিজার্ভ করে রাখাকে অগ্রাধিকার দিন।
- স্কিম সাপোর্ট: সব URL যাতে বাধ্যতামূলক HTTPS স্কিম ব্যবহার করে তা নিশ্চিত করুন। ভুল
স্কিম বা নাল ইনপুট সিঙ্ক্রোনাস
IllegalArgumentExceptionট্রিগার করে।
অতিরিক্ত রিসোর্স
ওয়েব অ্যাপ ডিবাগ করা, WebView স্টার্ট-আপ পারফর্ম্যান্স অপ্টিমাইজ করা এবং রেন্ডারার প্রসেস বন্ধ করা ম্যানেজ করা সম্পর্কে আরও জানতে, নিম্নলিখিত রিসোর্স দেখুন:
WebViewCompat.navigateপদ্ধতির মাধ্যমে উন্নত পৃষ্ঠা নেভিগেশন- ওয়েব অ্যাপ ডিবাগ করা
- WebView স্টার্ট-আপ অপ্টিমাইজ করা
- WebView রেন্ডারার প্রসেস বন্ধ করা ম্যানেজ করা