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

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

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

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

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

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

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

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

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

ฟีเจอร์ เชื่อมต่อล่วงหน้า การดึงข้อมูลล่วงหน้า แสดงผลล่วงหน้า
เป้าหมายหลัก อุ่นเครื่องการเชื่อมต่อ แคชเฉพาะ 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 สำหรับต้นทางที่ระบุไว้ล่วงหน้า

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

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

การใช้งาน

หากต้องการเริ่มการเชื่อมต่อล่วงหน้า ให้โทรหา 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

แม้ว่าทั้งคำแนะนำในการเชื่อมต่อล่วงหน้าและ 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

addQuicHints ทำงานในต้นทางเช่นเดียวกับ preconnect แต่สามารถระบุ 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
            }
        }
    }
);

วงจรการสกัดกั้น

คำขอ Prefetch ของ 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 เริ่มต้นและจัดการคำขอการดึงข้อมูลล่วงหน้า

  • ความปลอดภัยของเธรด: เริ่มคำขอได้จากเธรดใดก็ได้
  • การมีสิทธิ์: ก่อนเริ่มการดึงข้อมูล 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 ที่จำเป็น รูปแบบที่ไม่ถูกต้องหรืออินพุตที่เป็น Null จะทริกเกอร์ IllegalArgumentException แบบซิงโครนัส

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

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