การดึงข้อมูลล่วงหน้ามี 2 วิธี ได้แก่ แท็ก <ลิงก์> และส่วนหัว HTTP

Demián Renzulli
Demián Renzulli

ในโค้ดแล็บนี้ คุณจะได้ใช้การดึงข้อมูลล่วงหน้า 2 วิธี ได้แก่ ใช้ <link rel="prefetch"> และใช้ส่วนหัว Link ของ HTTP

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

วัดประสิทธิภาพ

ก่อนอื่นให้กำหนดประสิทธิภาพพื้นฐาน

  1. กด `Control+Shift+J` (หรือ `Command+Option+J` ใน Mac) เพื่อเปิด DevTools
  2. คลิกแท็บเครือข่าย

  3. ในรายการแบบเลื่อนลงการควบคุมอัตรา ให้เลือก 3G เร็ว เพื่อจำลองประเภทการเชื่อมต่อที่ช้า

  4. หากต้องการโหลดหน้าผลิตภัณฑ์ ให้คลิกซื้อเลยในแอปตัวอย่าง

หน้า product-details.html ใช้เวลาโหลดประมาณ 600 มิลลิวินาที

แผงเครือข่ายแสดงเวลาในการโหลดสำหรับ product-details.html

หากต้องการปรับปรุงการนำทาง ให้แทรกแท็ก prefetch ในหน้า Landing Page เพื่อดึงข้อมูลหน้า product-details.html ล่วงหน้า

  • เพิ่มองค์ประกอบ <link> ต่อไปนี้ลงในส่วนหัวของไฟล์ views/index.html
<!doctype html>
  <html>
    <head>
       <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">

      <link rel="prefetch" href="/product-details.html" as="document">
      ...
</head>

แอตทริบิวต์ as จะระบุหรือไม่ก็ได้ แต่ขอแนะนำให้ระบุเพื่อช่วยให้เบราว์เซอร์ตั้งค่าส่วนหัวที่ถูกต้องและพิจารณาว่าทรัพยากรอยู่ในแคชแล้วหรือไม่ ค่าตัวอย่างสำหรับแอตทริบิวต์นี้ ได้แก่ document, script, style, font, image และอื่นๆ

วิธียืนยันว่าการดึงข้อมูลล่วงหน้าทำงานอยู่

  1. กด `Control+Shift+J` (หรือ `Command+Option+J` ใน Mac) เพื่อเปิด DevTools
  2. คลิกแท็บเครือข่าย

  3. ในรายการแบบเลื่อนลงการควบคุมอัตรา ให้เลือก 3G เร็ว เพื่อจำลองประเภทการเชื่อมต่อที่ช้า

  4. ล้างช่องทำเครื่องหมาย "ปิดใช้แคช"

  5. โหลดแอปอีกครั้ง

ตอนนี้เมื่อหน้า Landing Page โหลด product-details.html หน้าเว็บก็จะโหลดด้วย แต่มีลำดับความสำคัญต่ำสุด

แผงเครือข่ายแสดง product-details.html ที่ดึงข้อมูลล่วงหน้า

ระบบจะเก็บหน้าไว้ในแคช HTTP เป็นเวลา 5 นาที หลังจากนั้นกฎ Cache-Control ปกติสำหรับเอกสารจะมีผล ในกรณีนี้ product-details.html มีส่วนหัว cache-control ที่มีค่าเป็น public, max-age=0 ซึ่งหมายความว่าระบบจะเก็บหน้าเว็บไว้เป็นเวลา 5 นาที

ประเมินประสิทธิภาพอีกครั้ง

  1. โหลดแอปอีกครั้ง
  2. หากต้องการโหลดหน้าผลิตภัณฑ์ ให้คลิกซื้อเลยในแอปตัวอย่าง

ดูแผงเครือข่าย มีความแตกต่าง 2 อย่างเมื่อเทียบกับการติดตามเครือข่ายครั้งแรก ดังนี้

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

ซึ่งลดลงประมาณ 98% เมื่อเทียบกับเวอร์ชันก่อนหน้าซึ่งใช้เวลาประมาณ 600 มิลลิวินาที

แผงเครือข่ายแสดง product-details.html ที่ดึงมาจากแคชที่ดึงข้อมูลล่วงหน้า

คะแนนพิเศษ: ใช้ prefetch เป็นการเพิ่มประสิทธิภาพแบบต่อเนื่อง

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

หากต้องการใช้การดึงข้อมูลล่วงหน้าแบบปรับอัตโนมัติ ให้นำแท็ก <link rel="prefetch"> ออกจาก views/index.html ก่อน โดยทำดังนี้

<!doctype html>
  <html>
    <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
       <link rel="prefetch" href="/product-details.html" as="document">
       ...
    </head>

จากนั้นเพิ่มโค้ดต่อไปนี้ลงใน public/script.js เพื่อประกาศฟังก์ชันที่จะแทรกแท็ก prefetch แบบไดนามิกเมื่อผู้ใช้มีการเชื่อมต่อที่รวดเร็ว

function injectLinkPrefetchIn4g(url) {
    if (window.navigator.connection.effectiveType === '4g') {
        //generate link prefetch tag
        const linkTag = document.createElement('link');
        linkTag.rel = 'prefetch';
        linkTag.href = url;
        linkTag.as = 'document';

        //inject tag in the head of the document
        document.head.appendChild(linkTag);
    }
}

ฟังก์ชันนี้ทำงานดังนี้

  • โดยจะตรวจสอบพร็อพเพอร์ตี้ effectiveType ของ Network Information API เพื่อดูว่าผู้ใช้ใช้การเชื่อมต่อ 4G (หรือเร็วกว่า) หรือไม่
  • หากตรงตามเงื่อนไขดังกล่าว ระบบจะสร้างแท็ก <link> โดยมี prefetch เป็นประเภทคำแนะนำ ส่ง URL ที่จะดึงข้อมูลล่วงหน้าในแอตทริบิวต์ href และระบุว่าทรัพยากรเป็น HTML document ในแอตทริบิวต์ as
  • สุดท้าย ระบบจะแทรกสคริปต์แบบไดนามิกลงใน head ของหน้าเว็บ

จากนั้นเพิ่ม script.js ลงใน views/index.html ก่อนแท็กปิด </body> ดังนี้

<body>
      ...
      <script src="/script.js"></script>
</body>

การขอ script.js ที่ส่วนท้ายของหน้าเว็บจะช่วยให้มั่นใจได้ว่าระบบจะโหลดและเรียกใช้หลังจากแยกวิเคราะห์และโหลดหน้าเว็บแล้ว

หากต้องการให้มั่นใจว่าการดึงข้อมูลล่วงหน้าจะไม่รบกวนทรัพยากรที่สําคัญสําหรับหน้าปัจจุบัน ให้เพิ่มข้อมูลโค้ดต่อไปนี้เพื่อเรียกใช้ injectLinkPrefetchIn4g() ในเหตุการณ์ window.load

<body>
      ...
      <script src="/script.js"></script>
      <script>
           window.addEventListener('load', () => {
                injectLinkPrefetchIn4g('/product-details.html');
           });
      </script>
</body>

ตอนนี้หน้า Landing Page จะดึงข้อมูลล่วงหน้า product-details.html เฉพาะในการเชื่อมต่อที่รวดเร็ว วิธียืนยันมีดังนี้

  1. กด `Control+Shift+J` (หรือ `Command+Option+J` ใน Mac) เพื่อเปิด DevTools
  2. คลิกแท็บเครือข่าย
  3. ในรายการแบบเลื่อนลงการควบคุมอัตรา ให้เลือกออนไลน์
  4. โหลดแอปอีกครั้ง

คุณควรเห็น product-details.html ในแผงเครือข่าย

แผงเครือข่ายแสดง product-details.html ที่ดึงข้อมูลล่วงหน้า

วิธียืนยันว่าระบบไม่ได้ดึงข้อมูลหน้าผลิตภัณฑ์ล่วงหน้าในการเชื่อมต่อที่ช้า

  1. ในรายการแบบเลื่อนลงของการควบคุมอัตรา ให้เลือก 3G ช้า
  2. โหลดแอปอีกครั้ง

แผงเครือข่ายควรมีเฉพาะทรัพยากรสำหรับหน้า Landing Page ที่ไม่มี product-details.html ดังนี้

แผงเครือข่ายแสดงว่าไม่ได้ดึงข้อมูลล่วงหน้าสำหรับ product-details.html

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

เพิ่มส่วนหัว HTTP Link สำหรับ style-product.css ในการตอบกลับของเซิร์ฟเวอร์สำหรับหน้า Landing Page ดังนี้

  1. เปิดไฟล์ server.js แล้วมองหาตัวแฮนเดิล get() สำหรับ URL รูท: /
  2. เพิ่มบรรทัดต่อไปนี้ที่จุดเริ่มต้นของตัวแฮนเดิล
app.get('/', function(request, response) {
    response.set('Link', '</style-product.css>; rel=prefetch');
    response.sendFile(__dirname + '/views/index.html');
});
  1. กด `Control+Shift+J` (หรือ `Command+Option+J` ใน Mac) เพื่อเปิด DevTools
  2. คลิกแท็บเครือข่าย
  3. โหลดแอปอีกครั้ง

ตอนนี้ระบบจะดึงข้อมูล style-product.css ล่วงหน้าที่ลำดับความสำคัญต่ำสุดหลังจากที่หน้า Landing Page โหลดแล้ว

แผงเครือข่ายแสดง style-product.css ที่ดึงข้อมูลล่วงหน้า

หากต้องการไปที่หน้าผลิตภัณฑ์ ให้คลิกซื้อเลย ดูแผงเครือข่าย

แผงเครือข่ายแสดง style-product.css ที่ดึงมาจากแคชที่ดึงข้อมูลล่วงหน้า

ระบบดึงไฟล์ style-product.css จาก "แคชการดึงข้อมูลล่วงหน้า" และใช้เวลาโหลดเพียง 12 มิลลิวินาที