การโหลดแบบคาดเดาใน WebView

เวลาในการตอบสนองของการนำทางเป็นเมตริกที่สำคัญสำหรับประสบการณ์ของผู้ใช้ WebView มี API สำหรับการโหลดแบบคาดเดาและการเพิ่มประสิทธิภาพการเชื่อมต่อเพื่อช่วยให้นักพัฒนาแอป ลดเวลาในการตอบสนองนี้ได้ ซึ่งจะช่วยให้แอปของคุณดึงหรือแสดงเนื้อหาก่อนที่ผู้ใช้จะไปยังส่วนนั้นอย่างชัดเจน

WebView รองรับการโหลดแบบคาดเดา 3 ประเภทหลัก ได้แก่ Preconnect Prefetch และ Prerender พร้อมกับคำแนะนำ QUIC เพื่อเพิ่มประสิทธิภาพการเจรจาโปรโตคอล

การใช้กลยุทธ์การโหลดแบบคาดเดาจะช่วยให้คุณได้รับประโยชน์ต่อไปนี้

  • ลดเวลาในการตอบสนองของการโหลดเนื้อหาเว็บอย่างมาก: ย้ายเวลาเริ่มต้นของเครือข่ายไปไว้ในช่วงต้นของวงจรแอป และใช้โปรโตคอลที่เร็วกว่า เช่น HTTP/3
  • อัตราความสำเร็จในการไปยังส่วนต่างๆ สูงขึ้น: การอุ่นเครือข่ายและแคชล่วงหน้า จะช่วยลดโอกาสที่การไปยังส่วนต่างๆ จะล้มเหลวเนื่องจากปัญหาเครือข่ายชั่วคราว
  • การตอบสนองที่รับรู้ได้ดีขึ้น: การแสดงผลล่วงหน้าช่วยให้เปลี่ยนฉากได้ทันที ซึ่งทำให้แอปดูเร็วขึ้นอย่างเห็นได้ชัด

เลือกกลยุทธ์การโหลดแบบคาดเดา

ความแตกต่างที่สำคัญระหว่างกลยุทธ์เหล่านี้อยู่ที่ขอบเขตของกลยุทธ์ โดย API คำแนะนำ Preconnect และ QUIC จะอิงตามต้นทาง ซึ่งหมายความว่าต้องใช้โดเมนเป้าหมายเท่านั้น API การดึงข้อมูลล่วงหน้าและการแสดงผลล่วงหน้าเป็นแบบ URL ซึ่งหมายความว่าต้องใช้เส้นทางหน้าเว็บที่แน่นอน

เนื่องจากคำแนะนำ Preconnect และ QUIC ทำงานที่ระดับต้นทาง คุณจึงเริ่มใช้คำแนะนำเหล่านี้ได้เร็วกว่ามากในวงจรของแอป แม้กระทั่งก่อนที่จะทราบเนื้อหาหรือหน้าเว็บที่เฉพาะเจาะจงซึ่งผู้ใช้จะไปยังส่วนต่างๆ

ตารางต่อไปนี้เปรียบเทียบกลยุทธ์ทั้ง 3 เพื่อช่วยให้คุณเลือกกลยุทธ์ที่เหมาะสมกับกรณีการใช้งานของคุณได้

ฟีเจอร์ เชื่อมต่อล่วงหน้า ดึงข้อมูลล่วงหน้า Prerender
เป้าหมายหลัก วอร์มอัปการเชื่อมต่อ แคชเฉพาะ HTML (ไม่มี JavaScript หรือ CSS) แสดงหน้าเว็บทั้งหน้าล่วงหน้า
ขอบเขต ระดับโปรไฟล์ (แชร์ใน WebView) ระดับโปรไฟล์ (แชร์ใน WebView) ระดับ WebView (เชื่อมโยงกับ WebView ที่เฉพาะเจาะจง)
Jetpack WebKit API androidx.webkit.Profile androidx.webkit.Profile androidx.webkit.WebViewCompat
เมธอด API หลัก preconnect(...) prefetchUrlAsync(...) prerenderUrlAsync(...)
การกำหนดค่า ไม่มี PrefetchCache.setMaxPrefetches()
PrefetchCache.setPrefetchTtlSeconds()
setMaxPrerenders()
การใช้ทรัพยากร ต่ำ (เครือข่าย) ปานกลาง (เครือข่าย หน่วยความจำ) สูง (CPU, หน่วยความจำ, เครือข่าย)
กรณีที่ควรใช้ เมื่อทราบต้นทางเป้าหมาย แต่ยังไม่ได้กำหนด URL ที่เฉพาะเจาะจง เมื่อทราบ URL ที่แน่นอนและมีแนวโน้มที่จะมีการไปยังส่วนต่างๆ โดยมีการแชร์แคชใน WebView เมื่อทราบ URL ที่แน่นอนและมั่นใจได้ว่ามีการนำทางภายใน WebView ที่เฉพาะเจาะจง
ข้อดี ตั้งค่าการเชื่อมต่อได้เร็วขึ้นสำหรับ URL ใดก็ได้ในต้นทาง โหลดเครือข่ายได้เร็วขึ้นสำหรับ URL ที่ตรงกัน การนำทางที่รวดเร็วทันใจเมื่อเปิดใช้งาน

เชื่อมต่อกับต้นทางล่วงหน้า

การเชื่อมต่อล่วงหน้าจะช่วยให้การโหลดในอนาคตเร็วขึ้นด้วยการทำ DNS Lookup และ TCP/TLS หรือ QUIC Handshake สำหรับต้นทางที่ระบุไว้ล่วงหน้า

Preconnect จะอิงตามต้นทางอย่างเคร่งครัด ซึ่งต่างจาก Prefetch และ Prerender ที่ต้องใช้ URL ปลายทางที่แน่นอน ซึ่งช่วยให้คุณโทร Preconnect ได้เร็วกว่า Prefetch และ Prerender มาก

กลยุทธ์ระดับโปรไฟล์ที่ใช้ทรัพยากรต่ำนี้จะช่วยลดเวลาในการตอบสนองเริ่มต้นสำหรับการแชร์ WebView ใดๆ ที่โปรไฟล์นั้นๆ โดยมีเงื่อนไขว่ายังไม่ได้เข้าชมต้นทาง การเชื่อมต่อจะเปิดไว้ประมาณ 30 วินาที ซึ่งจะเป็นประโยชน์ต่อคำขอ HTTP, การไปยังส่วนต่างๆ หรือทรัพยากรย่อยแบบข้ามต้นทางในภายหลังโดยการลดค่าใช้จ่ายในการแฮนด์เชค

การใช้งาน

หากต้องการเริ่มการเชื่อมต่อล่วงหน้า ให้โทรหา preconnect(String url) ในอินสแตนซ์ Profile ต้องเรียก 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
}

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

HTTP/3 (ซึ่งทำงานผ่านโปรโตคอลการรับส่งข้อมูล QUIC) ช่วยปรับปรุงเวลาในการตอบสนองได้อย่างมากเมื่อเทียบกับ HTTP/2 ซึ่งรวมถึงการแฮนด์เชคแบบ 0-RTT, ความยืดหยุ่นในการเชื่อมต่อที่ดีขึ้น และการขจัดปัญหาการบล็อกส่วนหัวของบรรทัดระหว่างแพ็กเก็ตสูญหาย

โดยค่าเริ่มต้น WebView จะพยายามเชื่อมต่อ QUIC ก็ต่อเมื่อมีข้อบ่งชี้ว่าต้นทางรองรับ QUIC เช่น จากส่วนหัว Alt-Svc หรือระเบียน HTTPS DNS จากการโต้ตอบก่อนหน้า หากไม่มีความรู้เบื้องต้นนี้ WebView จะใช้ HTTP/2 หรือ HTTP/1.1 สำหรับการเชื่อมต่อครั้งแรก

การเรียกใช้ addQuicHints จะป้อนข้อมูลการรองรับโปรโตคอลนี้ล่วงหน้า ซึ่งจะช่วยให้ WebView เชื่อมต่อโดยใช้ QUIC ได้ทันทีในการเชื่อมต่อครั้งแรกกับต้นทางที่ระบุ

เชื่อมต่อล่วงหน้าด้วยคำแนะนำ QUIC

แม้ว่าทั้งคำแนะนำ Preconnect และ QUIC จะเป็นการเพิ่มประสิทธิภาพระดับต้นทางใน Profile แต่ก็มีบทบาทที่แตกต่างกันและเสริมซึ่งกันและกัน

  • preconnect: เปิดและรักษาการเชื่อมต่อเครือข่าย (การค้นหา DNS และการแฮนด์เชค TCP/TLS หรือ QUIC) เป็นเวลาประมาณ 30 วินาที เนื่องจาก มีการเชื่อมต่อเครือข่ายที่ใช้งานอยู่ จึงใช้ทรัพยากรของอุปกรณ์และเครือข่าย และควรสงวนไว้สำหรับต้นทางเป้าหมายที่มีโอกาสสูง
  • addQuicHints: ไม่ทำให้เกิดการรับส่งข้อมูลในเครือข่ายในทันที โดยจะอัปเดตพร็อพเพอร์ตี้เซิร์ฟเวอร์ในหน่วยความจำของ Profileสแต็กเครือข่ายเพื่อบันทึกการรองรับโปรโตคอล เนื่องจากมีค่าใช้จ่ายที่น้อยมาก คุณจึงกำหนดค่าคำแนะนำ QUIC ได้อย่างปลอดภัยในระหว่างการเริ่มต้นแอปสำหรับต้นทางที่ทราบทั้งหมดซึ่งรองรับ HTTP/3

หากต้องการประสิทธิภาพสูงสุด ให้เรียกใช้ addQuicHints ก่อนเรียกใช้ preconnect, prefetchUrlAsync หรือ loadUrl ซึ่งจะช่วยให้การเชื่อมต่อล่วงหน้าหรือคำขอหน้าเว็บในภายหลังเจรจา HTTP/3 ได้ตั้งแต่เริ่มต้น

การใช้งาน

หากต้องการกำหนดค่าคำแนะนำ QUIC ให้เรียกใช้ addQuicHints(Set<String> urls) ในอินสแตนซ์ Profile คุณต้องเรียก API นี้ในเทรด UI และตรวจสอบว่า WebView รองรับฟีเจอร์ WebViewFeature.ADD_QUIC_HINTS_V1

เช่นเดียวกับ preconnect addQuicHints จะทำงานในต้นทาง แต่สามารถระบุ URL แบบเต็มได้ (เช่น https://www.example.com/index.html) และระบบจะแปลง URL แบบเต็มให้เป็นต้นทางโดยอัตโนมัติ (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

ทั้ง Prefetch และ Prerender ใช้ 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()

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

การดึงข้อมูลเนื้อหาล่วงหน้า

การดึงข้อมูลล่วงหน้าจะดาวน์โหลดทรัพยากร HTML หลักของ URL และจัดเก็บไว้ในแคชเครือข่ายของโปรไฟล์ ใน WebView Profile จะทำหน้าที่เป็นคอนเทนเนอร์สำหรับข้อมูลเบราว์เซอร์ ซึ่งรวมถึงคุกกี้ แคช HTTP และ Service Worker เนื่องจากการดึงข้อมูลล่วงหน้าเป็นการดำเนินการระดับโปรไฟล์ WebView ใดๆ ที่เชื่อมโยงกับโปรไฟล์นั้นจะใช้ประโยชน์จากคำตอบที่แคชไว้ได้

การใช้งาน

หากต้องการเริ่มการดึงข้อมูลล่วงหน้า ให้เรียกใช้ prefetchUrlAsync() ในอินสแตนซ์ Profile การดำเนินการนี้รองรับเฉพาะรูปแบบ 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
                }
            }
        }
    }
)

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() การเรียกกลับ เนื่องจากขั้นตอนนี้ส่งผลโดยตรงต่อการใช้เนื้อหาที่ดึงข้อมูลล่วงหน้าได้สำเร็จหรือไม่ คุณจึงต้องทำความเข้าใจวงจร 2 ขั้นตอนต่อไปนี้

แผนภาพแสดงวงจรการสกัดกั้นการดึงข้อมูลล่วงหน้าของ WebView แบบ 2 ขั้นตอน
  ในระหว่างเฟสการคาดการณ์และการนำทาง
รูปที่ 1 วงจรการสกัดกั้น 2 ขั้นตอนสำหรับการดึงข้อมูลล่วงหน้าของ WebView คำขอและการนำทาง

1. ระยะการคาดการณ์ (คำขอ Prefetch)

เมื่อเรียกใช้ prefetchUrlAsync() WebView จะดาวน์โหลดทรัพยากร HTML หลัก ในเบื้องหลัง shouldInterceptRequest() จะข้ามไปโดยสมบูรณ์สำหรับคำขอในเบื้องหลังนี้ ตรรกะที่กำหนดเอง โทเค็นการให้สิทธิ์ หรือการแทรกส่วนหัว ซึ่งโดยปกติจะจัดการภายในอินเทอร์เซ็ปเตอร์จะไม่มีผลกับทรัพยากร HTML ที่ดึงข้อมูลล่วงหน้า

2. ระยะการนำทาง (การเปิดใช้งานผู้ใช้)

เมื่อแอปไปยัง URL อย่างชัดแจ้ง (เช่น ใช้ WebViewCompat.navigate หรือ loadUrl) หรือผู้ใช้คลิกลิงก์ที่ตรงกัน WebView จะพิจารณาว่าใช้แคชที่ดึงข้อมูลล่วงหน้าได้หรือไม่

  • การประเมิน HTML หลัก: WebView จะทริกเกอร์ shouldInterceptRequest() สำหรับ HTML หลักในขณะนี้ หากต้องการแสดงหน้าเว็บจากแคชการดึงข้อมูลล่วงหน้าให้สำเร็จ ตัวสกัดกั้นต้องแสดงผล null หากคุณส่งคืน Custom WebResourceResponse, WebView จะใช้ Interceptor และข้ามแคชการดึงข้อมูลล่วงหน้าทั้งหมด

  • การประเมินทรัพยากรย่อย: หลังจากล้าง HTML ที่ดึงข้อมูลล่วงหน้าเพื่อใช้งานแล้ว shouldInterceptRequest() จะทริกเกอร์ตามปกติสำหรับทรัพยากรย่อยทั้งหมดที่ตามมา (เช่น รูปภาพ สคริปต์ และ CSS) ที่จำเป็นต่อการแสดงผลหน้าเว็บให้เสร็จสมบูรณ์

ลักษณะการทำงานที่สำคัญ

ลักษณะการทำงานและการตรวจสอบการมีสิทธิ์ต่อไปนี้จะควบคุมวิธีที่ WebView เริ่มต้นและจัดการคำขอ Prefetch

  • ความปลอดภัยของเธรด: เริ่มคำขอได้จากเธรดใดก็ได้
  • การมีสิทธิ์: ก่อนเริ่มการดึงข้อมูล WebView จะตรวจสอบว่าคำขอมีความปลอดภัยและเหมาะสมตามบริบทโดยตรวจสอบสิ่งต่อไปนี้
    • คุกกี้ที่มีอยู่: เพื่อปกป้องความเป็นส่วนตัวของผู้ใช้และป้องกันผลข้างเคียงที่คล้ายกับ CSRF WebView อาจข้ามการดึงข้อมูลล่วงหน้าหากคำขอต้องใช้คุกกี้ที่ผ่านการตรวจสอบสิทธิ์ที่เฉพาะเจาะจงซึ่งอาจทริกเกอร์การเปลี่ยนสถานะในเซิร์ฟเวอร์
    • การมีอยู่ของ Service Worker: หาก Service Worker ควบคุมขอบเขตของ URL อยู่แล้ว WebView จะเลื่อนการดำเนินการไปยังตัวแฮนเดิลการดึงข้อมูลของ Service Worker แทนที่จะเริ่มการดึงข้อมูลล่วงหน้าในเครือข่ายมาตรฐาน
    • ความพร้อมใช้งานของพร็อกซี: WebView จะตรวจสอบว่าเส้นทางเครือข่ายปัจจุบัน (รวมถึงพร็อกซีที่กำหนดค่าไว้) มีความเสถียรเพื่อหลีกเลี่ยงไม่ให้คำขอแบบคาดการณ์ล้มเหลวภายใต้การกำหนดค่าเครือข่ายที่ซับซ้อน
  • หากการดึงข้อมูลล่วงหน้าเริ่มต้นไม่สำเร็จ (แม้จะมีพารามิเตอร์ที่ถูกต้อง) มักเป็นเพราะ WebView ระบุว่าคำขอในเบื้องหลังอาจรบกวนเซสชันปัจจุบันหรือสถานะความปลอดภัยของผู้ใช้
  • การยกเลิก: ใช้ CancellationSignal เพื่อสิ้นสุดคำขอระหว่างการส่ง และป้องกันไม่ให้แคชคำขอ

การแสดงหน้าเว็บล่วงหน้า

การแสดงผลล่วงหน้าจะสร้าง "เนื้อหาเว็บ" ที่ซ่อนไว้เพื่อแสดงผลหน้าเว็บอย่างเต็มรูปแบบในเบื้องหลัง รวมถึงการเรียกใช้สคริปต์และการดึงข้อมูลทรัพยากรย่อย การแสดงผลล่วงหน้า ใช้โครงสร้างพื้นฐานเดียวกันกับการดึงข้อมูลล่วงหน้า หากแอปเริ่มต้นการแสดงผลล่วงหน้า WebView จะทำการดึงข้อมูลล่วงหน้าของคำตอบก่อนเพื่อแสดงผลการนำทางที่แสดงผลล่วงหน้า ซึ่งจะช่วยหลีกเลี่ยงกิจกรรมเครือข่ายที่ซ้ำซ้อน

การใช้งาน

การแสดงผลล่วงหน้าเป็นการดำเนินการระดับอินสแตนซ์ WebView โทรหา prerenderUrlAsync() โดยใช้ WebViewCompat จากเธรด UI

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() ต้องเริ่มต้นจากเธรด UI

ข้อจำกัดทางเทคนิค

WebView จะบังคับใช้ข้อจำกัดรันไทม์ต่อไปนี้เพื่อรักษาสมดุลระหว่างการไปยังส่วนต่างๆ ทันทีกับสถานะของระบบ

  • หน่วยความจำเหลือน้อย: WebView จะยกเลิก URL ที่แสดงผลล่วงหน้าหากอุปกรณ์มี RAM เหลือน้อย
  • API ที่ไม่อนุญาต: ความพยายามใดๆ ของ JavaScript ในการเข้าถึง API บางอย่าง (เช่น การเล่นเสียง การแจ้งเตือน) ในบริบทเบื้องหลังจะสิ้นสุดการแสดงตัวอย่างทันที
  • ขีดจํากัดของอินสแตนซ์: มีการจํากัดจํานวน URL ที่แสดงผลล่วงหน้าที่ใช้งานอยู่ ที่อนุญาตต่อ WebView

การจับคู่ URL และ No-Vary-Search (NVS)

WebView ต้องใช้อัลกอริทึมการจับคู่ที่เชื่อถือได้เพื่อให้แน่ใจว่าระบบจะแสดงทรัพยากรที่โหลดล่วงหน้า สำหรับการนำทางที่ต้องการเท่านั้น

การจับคู่ที่ตรงกันทั้งหมดกับการจับคู่ NVS

โดยค่าเริ่มต้น การดึงข้อมูลล่วงหน้าและการแสดงผลล่วงหน้าต้องมี URL ที่ตรงกันทุกประการ หาก URL ที่ไปยังเหมือนกับ URL ที่โหลดล่วงหน้า ระบบจะแสดงจากแคชทันที หากพารามิเตอร์การค้นหาแตกต่างกัน WebView จะใช้กฎ No-Vary-Search (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)

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: คลาสหลักสำหรับข้อผิดพลาดทั้งหมดที่เกี่ยวข้องกับการแสดงผลล่วงหน้า เช่น ข้อผิดพลาดเนื่องจากหน่วยความจำเต็มหรือการใช้ API ที่ไม่อนุญาต (เช่น การเล่นเสียง) ในเบื้องหลัง

กลยุทธ์การเพิ่มประสิทธิภาพ

ทำตามคำแนะนำต่อไปนี้เพื่อรับประโยชน์สูงสุดจากการโหลดแบบคาดการณ์ พร้อมทั้งประหยัดทรัพยากรของระบบ

  • เริ่มล่วงหน้า: เริ่มดึงข้อมูลล่วงหน้าในระหว่างการเริ่มต้นแอปหรือทันทีที่ มีแนวโน้มว่าจะเป็นปลายทางการนำทาง
  • จับคู่คำแนะนำ QUIC กับการอุ่นเครื่องการเชื่อมต่อล่วงหน้า: เรียกใช้ addQuicHints() ก่อนเริ่มการนำทาง preconnect(), prefetchUrlAsync() หรือการนำทางมาตรฐาน เพื่อให้มั่นใจว่า WebView จะพยายามสร้างการเชื่อมต่อโดยใช้ HTTP/3
  • กลยุทธ์แบบผสานรวม: หากคุณแสดงผล URL ล่วงหน้าซึ่งอยู่ในแคชการดึงข้อมูลล่วงหน้าแล้ว ระบบจะแสดงผลการนำทางที่แสดงผลล่วงหน้าจากแคชนั้น ซึ่งจะช่วยหลีกเลี่ยงคำขอเครือข่ายที่ซ้ำซ้อน
  • ตรวจสอบโควต้า: การแสดงผลล่วงหน้าใช้ทรัพยากรจำนวนมาก ให้ใช้การดึงข้อมูลล่วงหน้าสำหรับ หลายๆ หน้าที่มีแนวโน้ม และสงวนการแสดงผลล่วงหน้าไว้สำหรับการนำทางที่มีแนวโน้มมากที่สุดเพียงรายการเดียว
  • การรองรับรูปแบบ: ตรวจสอบว่า URL ทั้งหมดใช้รูปแบบ HTTPS ที่จำเป็น รูปแบบที่ไม่ถูกต้องหรืออินพุตที่เป็นค่าว่างจะทริกเกอร์ IllegalArgumentException แบบซิงโครนัส

แหล่งข้อมูลเพิ่มเติม

ดูข้อมูลเพิ่มเติมเกี่ยวกับการแก้ไขข้อบกพร่องของเว็บแอป การเพิ่มประสิทธิภาพการเริ่มต้น WebView และการจัดการการสิ้นสุดกระบวนการของโปรแกรมแสดงผลได้ในแหล่งข้อมูลต่อไปนี้