การปรับเปลี่ยนให้เหมาะกับผู้ใช้โดยให้คำใบ้กับไคลเอ็นต์

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

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

ทุกอย่างเกี่ยวกับการเจรจาต่อรองเนื้อหา

คำแนะนำไคลเอ็นต์เป็นอีกวิธีหนึ่งของการเจรจาต่อรองเนื้อหา ซึ่งหมายถึงการเปลี่ยนการตอบสนองเนื้อหาตามส่วนหัวคำขอของเบราว์เซอร์

ตัวอย่างหนึ่งของการจัดการเนื้อหาเกี่ยวข้องกับส่วนหัวของคำขอ Accept ซึ่งจะอธิบายประเภทเนื้อหาที่เบราว์เซอร์เข้าใจ ซึ่งเซิร์ฟเวอร์สามารถใช้เพื่อเจรจาต่อรองการตอบกลับ สำหรับคำขอรูปภาพ เนื้อหาของส่วนหัว Accept ของ Chrome จะเป็นดังนี้

Accept: image/webp,image/apng,image/*,*/*;q=0.8

แม้ว่าเบราว์เซอร์ทุกรุ่นจะรองรับรูปแบบรูปภาพอย่าง JPEG, PNG และ GIF แต่ในกรณีนี้ Accept จะระบุว่าเบราว์เซอร์ยังรองรับ WebP และ APNG ด้วย ข้อมูลนี้ช่วยให้เราเจรจาต่อรองประเภทรูปภาพที่ดีที่สุดสำหรับแต่ละเบราว์เซอร์ได้ ดังนี้

<?php
// Check Accept for an "image/webp" substring.
$webp = stristr($_SERVER["HTTP_ACCEPT"], "image/webp") !== false ? true : false;

// Set the image URL based on the browser's WebP support status.
$imageFile = $webp ? "whats-up.webp" : "whats-up.jpg";
?>
<img src="<?php echo($imageFile); ?>" alt="I'm an image!">

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

การเลือกใช้

คำแนะนำไคลเอ็นต์จะไม่ปรากฏขึ้นโดยอัตโนมัติ (ยกเว้น Save-Data ซึ่งเราจะพูดถึงในภายหลัง) ซึ่งแตกต่างจากส่วนหัว Accept คุณจะต้องเลือกใช้คำแนะนำไคลเอ็นต์ที่ต้องการรับโดยส่งส่วนหัว Accept-CH เมื่อผู้ใช้ขอทรัพยากร เพื่อลดจำนวนส่วนหัวคำขอให้เหลือน้อยที่สุด

Accept-CH: Viewport-Width, Downlink

ค่าของ Accept-CH คือรายการคำแนะนำที่ขอซึ่งคั่นด้วยคอมมา ซึ่งเว็บไซต์จะใช้ในการกำหนดผลลัพธ์สำหรับคำขอทรัพยากรที่ตามมา เมื่อไคลเอ็นต์อ่านส่วนหัวนี้ จะมีการบอกให้ไคลเอ็นต์ทราบว่า "เว็บไซต์นี้ต้องการคำแนะนำไคลเอ็นต์ Viewport-Width และ Downlink" ไม่ต้องกังวลเกี่ยวกับคำแนะนำที่เฉพาะเจาะจง เราจะพูดถึงเรื่องนี้ในอีกสักครู่

คุณตั้งค่าส่วนหัวการเลือกใช้เหล่านี้เป็นภาษาใดก็ได้ในแบ็กเอนด์ เช่น คุณอาจใช้ฟังก์ชัน header ของ PHP คุณยังตั้งค่าส่วนหัวการเลือกใช้เหล่านี้ด้วยแอตทริบิวต์ http-equiv บนแท็ก <meta> ได้ด้วย

<meta http-equiv="Accept-CH" content="Viewport-Width, Downlink" />

คำแนะนำสำหรับไคลเอ็นต์ทั้งหมด

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

คำแนะนำอุปกรณ์

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

ก่อนดูรายการนี้ คุณอาจต้องทบทวนคำศัพท์สำคัญ 2-3 คำที่ใช้อธิบายหน้าจอและความละเอียดของสื่อ

ขนาดภายใน: ขนาดจริงของทรัพยากรสื่อ เช่น หากคุณเปิดรูปภาพใน Photoshop มิติข้อมูลที่แสดงในกล่องโต้ตอบขนาดรูปภาพจะอธิบายขนาดเดิมของรูปภาพ

ขนาดตามจริงที่ปรับความหนาแน่นแล้ว: ขนาดของทรัพยากรสื่อหลังจากปรับความหนาแน่นของพิกเซลแล้ว นั่นคือขนาดเดิมของรูปภาพหารด้วยอัตราส่วนพิกเซลของอุปกรณ์ ตัวอย่างเช่น มาลองดูมาร์กอัปนี้กัน

<img
  src="whats-up-1x.png"
  srcset="whats-up-2x.png 2x, whats-up-1x.png 1x"
  alt="I'm that image you wanted."
/>

สมมติว่าขนาดตามจริงของรูปภาพ 1x ในกรณีนี้คือ 320x240 และขนาดตามจริงของรูปภาพ 2x คือ 640x480 หากมีการใช้ไคลเอ็นต์ในอุปกรณ์ที่มีสัดส่วนพิกเซลของอุปกรณ์หน้าจอ 2 (เช่น หน้าจอ Retina) เพื่อทำการวิเคราะห์มาร์กอัปนี้ ระบบจะขอรูปภาพ 2x ขนาดจริงที่แก้ไขความหนาแน่นของรูปภาพ 2x คือ 320x240 เนื่องจาก 640x480 หารด้วย 2 เท่ากับ 320x240

ขนาดภายนอก: ขนาดของทรัพยากรสื่อหลังจากมีการใช้ CSS และปัจจัยอื่นๆ ของเลย์เอาต์ (เช่น แอตทริบิวต์ width และ height) สมมติว่าคุณมีองค์ประกอบ <img> ที่โหลดรูปภาพขนาด 320x240 ที่มีการแก้ไขความหนาแน่น แต่ก็มีพร็อพเพอร์ตี้ CSS width และ height ที่มีค่า 256px และ 192px ที่ใช้กับองค์ประกอบดังกล่าวด้วย ในตัวอย่างนี้ ขนาดภายนอกขององค์ประกอบ <img> นั้นจะเป็น 256x192

ภาพขนาดภายในเทียบกับขนาดภายนอก กล่องขนาด 320x240 พิกเซลจะแสดงพร้อมป้ายกํากับ INTRINSIC
SIZE ภายในกล่องมีกล่องขนาดเล็กกว่าขนาด 256x192 พิกเซล ซึ่งแสดงถึงองค์ประกอบ img ของ HTML ที่มีการใช้ CSS ช่องนี้มีป้ายกำกับว่า EXTRINSIC
SIZE ทางด้านขวาคือช่องที่มี CSS ที่ใช้กับองค์ประกอบ ซึ่งจะแก้ไขเลย์เอาต์ขององค์ประกอบ img เพื่อให้ขนาดภายนอกแตกต่างจากขนาดภายใน
รูปที่ 1 ภาพขนาดที่แท้จริงเทียบกับขนาดภายนอก รูปภาพจะมีขนาดภายนอกหลังจากที่ใช้ปัจจัยเลย์เอาต์กับรูปภาพแล้ว ในกรณีนี้ การใช้กฎ CSS ของ width: 256px; และ height: 192px; จะเปลี่ยนรูปภาพขนาด 320x240 ที่เป็นขนาดตามเนื้อหาเป็นขนาด 256x192

เมื่อทราบคำศัพท์บางส่วนแล้ว เรามาเริ่มดูรายการคำแนะนำสำหรับไคลเอ็นต์เฉพาะอุปกรณ์ที่คุณใช้ได้

Viewport-Width

Viewport-Width คือความกว้างของวิวพอร์ตของผู้ใช้ในพิกเซล CSS

Viewport-Width: 320

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

DPR

DPR ซึ่งเป็นชื่อย่อของอัตราส่วนพิกเซลของอุปกรณ์จะรายงานอัตราส่วนของพิกเซลจริงต่อพิกเซล CSS ของหน้าจอผู้ใช้

DPR: 2

คำแนะนำนี้มีประโยชน์เมื่อเลือกแหล่งที่มาของรูปภาพที่สอดคล้องกับความหนาแน่นพิกเซลของหน้าจอ (เช่นเดียวกับที่คำอธิบาย x ใช้ในแอตทริบิวต์ srcset)

ความกว้าง

คำแนะนำ Width จะปรากฏในคำขอทรัพยากรรูปภาพที่เรียกใช้โดยแท็ก <img> หรือ <source> โดยใช้แอตทริบิวต์ sizes sizes บอกเบราว์เซอร์ว่าทรัพยากรจะมีขนาดภายนอกเท่าใด Width ใช้ขนาดภายนอกนั้นเพื่อขอรูปภาพที่มีขนาดภายในซึ่งเหมาะสําหรับเลย์เอาต์ปัจจุบัน

ตัวอย่างเช่น สมมติว่าผู้ใช้ขอหน้าเว็บที่มีหน้าจอกว้าง 320 พิกเซล CSS โดยมี DPR เท่ากับ 2 อุปกรณ์โหลดเอกสารที่มีองค์ประกอบ <img> ซึ่งมีค่าแอตทริบิวต์ sizes เป็น 85vw (เช่น 85% ของความกว้างวิวพอร์ตสำหรับหน้าจอทุกขนาด) หากเลือกใช้คำแนะนำ Width แล้ว ไคลเอ็นต์จะส่งคำแนะนำ Width นี้ไปยังเซิร์ฟเวอร์พร้อมกับคำขอ src ของ <img>

Width: 544

ในกรณีนี้ ไคลเอ็นต์บอกใบ้ให้เซิร์ฟเวอร์ทราบว่าความกว้างตามจริงที่เหมาะสมที่สุดสำหรับรูปภาพที่ขอคือ 85% ของความกว้างของวิวพอร์ต (272 พิกเซล) คูณด้วย DPR ของหน้าจอ (2) ซึ่งเท่ากับ 544 พิกเซล

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

Content-DPR

แม้ว่าคุณจะทราบอยู่แล้วว่าหน้าจอมีอัตราส่วนพิกเซลของอุปกรณ์ แต่ทรัพยากรก็มีอัตราส่วนพิกเซลของตัวเองด้วย ใน Use Case การเลือกทรัพยากรที่ง่ายที่สุด อัตราส่วนพิกเซลระหว่างอุปกรณ์กับทรัพยากรอาจเหมือนกัน แต่ ในกรณีที่มีการใช้ทั้งส่วนหัว DPR และ Width ขนาดภายนอกของทรัพยากรอาจทำให้เกิดสถานการณ์ที่ทั้ง 2 รายการแตกต่างกัน Content-DPR คำแนะนำจึงเข้ามามีบทบาท

Content-DPR ไม่ได้เป็นส่วนหัวคําขอที่เซิร์ฟเวอร์จะใช้ ต่างจากคำแนะนำไคลเอ็นต์อื่นๆ แต่เป็นส่วนหัวการตอบกลับที่เซิร์ฟเวอร์ต้องส่งทุกครั้งที่มีการใช้คำแนะนำ DPR และ Width เพื่อเลือกทรัพยากร ค่าของ Content-DPR ควรเป็นผลลัพธ์ของสมการนี้

Content-DPR = [ขนาดทรัพยากรรูปภาพที่เลือก] / ([Width] / [DPR])

เมื่อส่งส่วนหัวของคำขอ Content-DPR เบราว์เซอร์จะทราบวิธีปรับขนาดรูปภาพที่ระบุสำหรับอัตราส่วนพิกเซลของอุปกรณ์และเลย์เอาต์ของหน้าจอ หากไม่มี รูปภาพอาจปรับขนาดไม่ถูกต้อง

Device-Memory

Device-Memory เป็นส่วนหนึ่งของ Device Memory API ซึ่งจะแสดงปริมาณโดยประมาณของหน่วยความจำที่อุปกรณ์ปัจจุบันมีเป็น GiB ดังนี้

Device-Memory: 2

Use Case ที่เป็นไปได้สําหรับคำแนะนำนี้คือการลดจํานวน JavaScript ที่ส่งไปยังเบราว์เซอร์ในอุปกรณ์ที่มีหน่วยความจําจํากัด เนื่องจาก JavaScript เป็นประเภทเนื้อหาที่เบราว์เซอร์มักจะโหลดซึ่งใช้ทรัพยากรมากที่สุด หรือจะส่งรูปภาพที่มี DPR ต่ำลงก็ได้เนื่องจากใช้หน่วยความจำในการถอดรหัสน้อยกว่า

คำแนะนำเกี่ยวกับเครือข่าย

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

RTT

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

RTT: 125

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

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

Downlink: 2.5

เมื่อใช้ร่วมกับ RTT Downlink จะมีประโยชน์ในการเปลี่ยนวิธีนำส่งเนื้อหาไปยังผู้ใช้ตามคุณภาพของการเชื่อมต่อเครือข่าย

ECT

คำแนะนำ ECT หมายถึงประเภทการเชื่อมต่อที่มีประสิทธิภาพ ค่าของพารามิเตอร์นี้คือรายการประเภทการเชื่อมต่อที่ระบุ ซึ่งแต่ละรายการจะอธิบายการเชื่อมต่อภายในช่วงที่กำหนดของทั้งค่า RTT และ Downlink

ส่วนหัวนี้ไม่ได้อธิบายประเภทการเชื่อมต่อจริง เช่น ไม่รายงานว่าเกตเวย์ของคุณเป็นเสาสัญญาณหรือจุดเข้าใช้งาน Wi-Fi แต่ระบบจะวิเคราะห์เวลาในการตอบสนองและแบนด์วิดท์ของการเชื่อมต่อปัจจุบัน แล้วพิจารณาว่าโปรไฟล์เครือข่ายใดตรงกับการเชื่อมต่อมากที่สุด เช่น หากคุณเชื่อมต่อผ่าน Wi-Fi กับเครือข่ายที่ช้า ระบบอาจป้อนค่า ECT เป็น 2g ซึ่งเป็นค่าใกล้เคียงที่สุดของการเชื่อมต่อที่มีประสิทธิภาพ

ECT: 2g

ค่าที่ใช้ได้สำหรับ ECT คือ 4g, 3g, 2g และ slow-2g คำแนะนำนี้ใช้เป็นจุดเริ่มต้นในการประเมินคุณภาพการเชื่อมต่อได้ จากนั้นจึงปรับแต่งโดยใช้คำแนะนำ RTT และ Downlink

Save-Data

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

เราขอจัดประเภท Save-Data เป็นคำแนะนำเครือข่าย เนื่องจากสิ่งที่คุณทํากับ Save-Data นั้นคล้ายกับคําแนะนําเครือข่ายอื่นๆ หลายอย่าง นอกจากนี้ ผู้ใช้ยังอาจเปิดใช้ในสภาพแวดล้อมที่มีเวลาในการตอบสนองสูง/แบนด์วิดท์ต่ำด้วย คำแนะนำนี้ (หากมี) จะมีลักษณะดังนี้เสมอ

Save-Data: on

เราได้พูดคุยเกี่ยวกับสิ่งที่คุณทำได้เมื่อใช้ Save-Data กับ Google แล้ว ผลกระทบที่อาจเกิดขึ้นกับประสิทธิภาพอาจรุนแรง นี่เป็นสัญญาณที่ผู้ใช้ขอให้คุณส่งข้อมูลให้น้อยลง ผู้ใช้จะขอบคุณหากคุณรับฟังและดำเนินการตามสัญญาณนั้น

ลองนำทุกอย่างมารวมกัน

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

รูปภาพที่ปรับเปลี่ยนตามอุปกรณ์

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

แม้ว่า <picture> และ srcset จะเป็นเครื่องมือที่ยอดเยี่ยมอย่างปฏิเสธไม่ได้ แต่การพัฒนาและดูแลรักษาสำหรับกรณีการใช้งานที่ซับซ้อนอาจใช้เวลานาน เราสามารถสร้างมาร์กอัปโดยอัตโนมัติได้ แต่การดำเนินการดังกล่าวก็มีความซับซ้อนเช่นกัน เนื่องจากฟังก์ชันการทำงานที่ <picture> และ srcset มีให้นั้นมีความซับซ้อนมากพอที่การสร้างอัตโนมัติจะต้องดำเนินการในลักษณะที่คงความยืดหยุ่นของฟังก์ชันการทำงานเหล่านั้นไว้

คำแนะนำสำหรับไคลเอ็นต์ช่วยให้การดำเนินการนี้ง่ายขึ้น การเจรจาการตอบสนองด้วยรูปภาพกับไคลเอ็นต์ คำแนะนำอาจมีลักษณะดังนี้

  1. หากเวิร์กโฟลว์ของคุณใช้การจัดการรูปภาพ (ภาพที่มีการจัดวางอาร์ตเวิร์ก) ให้ตรวจสอบคำแนะนำ Viewport-Width ก่อน
  2. เลือกความละเอียดของรูปภาพโดยดูที่คำบอกใบ้ Width และคำบอกใบ้ DPR แล้วเลือกแหล่งที่มาที่เหมาะกับขนาดเลย์เอาต์ของรูปภาพและความหนาแน่นของหน้าจอ (คล้ายกับวิธีการทำงานของคําบอกใบ้ x และ w ใน srcset)
  3. เลือกรูปแบบไฟล์ที่เบราว์เซอร์รองรับมากที่สุด (ซึ่ง Acceptช่วยเราดำเนินการในเบราว์เซอร์ส่วนใหญ่ได้)

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

<picture>
  <source
    srcset="
      company-photo-256w.webp   256w,
      company-photo-512w.webp   512w,
      company-photo-768w.webp   768w,
      company-photo-1024w.webp 1024w,
      company-photo-1280w.webp 1280w
    "
    type="image/webp"
  />
  <img
    srcset="
      company-photo-256w.jpg   256w,
      company-photo-512w.jpg   512w,
      company-photo-768w.jpg   768w,
      company-photo-1024w.jpg 1024w,
      company-photo-1280w.jpg 1280w
    "
    src="company-photo-256w.jpg"
    sizes="(min-width: 560px) 251px, 88.43vw"
    alt="The Sconnie Timber Staff!"
  />
</picture>

เราลดจำนวนรายการได้ดังนี้โดยอิงตามการรองรับของเบราว์เซอร์แต่ละรายการ

<img
  src="/image/sizes:true/company-photo.jpg"
  sizes="(min-width: 560px) 251px, 88.43vw"
  alt="SAY CHEESY PICKLES."
/>

ในตัวอย่างนี้ URL /image คือสคริปต์ PHP ตามด้วยพารามิเตอร์ที่เขียนใหม่โดย mod_rewrite โดยจะใช้ชื่อไฟล์รูปภาพและพารามิเตอร์เพิ่มเติมเพื่อช่วยสคริปต์แบ็กเอนด์เลือกรูปภาพที่ดีที่สุดในเงื่อนไขที่กำหนด

เราเข้าใจว่าคำถามแรกของคุณคือ"แต่นี่ไม่ใช่แค่การติดตั้ง <picture> และ srcset อีกครั้งในแบ็กเอนด์ใช่ไหม"

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

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

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

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

การช่วยเหลือผู้ใช้ในเครือข่ายที่ช้า

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

สำหรับเว็บไซต์ของ Sconnie Timber เราได้ดำเนินการเพื่อลดภาระเมื่อเครือข่ายทำงานช้า โดยตรวจสอบส่วนหัว Save-Data, ECT, RTT และ Downlink ในโค้ดแบ็กเอนด์ เมื่อดำเนินการเสร็จแล้ว เราจะสร้างคะแนนคุณภาพเครือข่ายซึ่งใช้เพื่อพิจารณาว่าควรแทรกแซงเพื่อให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ดีขึ้นหรือไม่ คะแนนเครือข่ายนี้อยู่ระหว่าง 0 ถึง 1 โดยที่ 0 เป็นคุณภาพเครือข่ายที่แย่ที่สุดที่เป็นไปได้ และ 1 เป็นคุณภาพเครือข่ายที่ดีที่สุด

ขั้นแรก เราจะตรวจสอบว่ามี Save-Data หรือไม่ หากใช่ ระบบจะตั้งค่าคะแนนเป็น 0 เนื่องจากเราถือว่าผู้ใช้ต้องการให้เราทําทุกอย่างที่จําเป็นเพื่อทำให้ประสบการณ์การใช้งานเบาและเร็วขึ้น

อย่างไรก็ตาม หากไม่มี Save-Data เราจะข้ามไปและพิจารณาค่าของคำแนะนำ ECT, RTT และ Downlink เพื่อคำนวณคะแนนที่อธิบายคุณภาพการเชื่อมต่อเครือข่าย ซอร์สโค้ดการสร้างคะแนนเครือข่ายมีอยู่ใน GitHub สิ่งที่ได้คือหากเราใช้คำแนะนำที่เกี่ยวข้องกับเครือข่ายในบางรูปแบบ เราจะมอบประสบการณ์การใช้งานที่ดีขึ้นให้แก่ผู้ที่ใช้เครือข่ายช้า

การเปรียบเทียบเว็บไซต์ที่ไม่ได้ใช้คำแนะนำไคลเอ็นต์เพื่อปรับตัวให้เข้ากับการเชื่อมต่อเครือข่ายที่ช้า (ซ้าย) กับเว็บไซต์เดียวกันที่ใช้คำแนะนำ (ขวา)
รูปที่ 2 หน้า "เกี่ยวกับเรา" สำหรับเว็บไซต์ธุรกิจในพื้นที่ ประสบการณ์พื้นฐานประกอบด้วยแบบอักษรเว็บ, JavaScript เพื่อขับเคลื่อนลักษณะการทํางานของภาพสไลด์และ Accordion รวมถึงรูปภาพเนื้อหา สิ่งเหล่านี้เป็นสิ่งที่เราอาจละเว้นได้เมื่อเครือข่ายทำงานช้าเกินไปที่จะโหลดอย่างรวดเร็ว

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

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

Waterfall ของ WebPagetest สำหรับเว็บไซต์ SconnieTimber ที่โหลดทรัพยากรทั้งหมดในการเชื่อมต่อเครือข่ายที่ช้า
รูปที่ 3 เว็บไซต์ที่มีทรัพยากรมากซึ่งโหลดรูปภาพ สคริปต์ และแบบอักษรในการเชื่อมต่อที่ช้า

และนี่คือการแสดงโฆษณาสื่อกลางตามลำดับขั้นสําหรับเว็บไซต์เดียวกันในการเชื่อมต่อที่ช้าเดียวกัน แต่ครั้งนี้เว็บไซต์ใช้คำแนะนำไคลเอ็นต์เพื่อนำทรัพยากรของหน้าเว็บที่ไม่สําคัญออก

Waterfall ของ WebPagetest สำหรับเว็บไซต์ SconnieTimber ที่ใช้คำแนะนำไคลเอ็นต์เพื่อตัดสินใจไม่โหลดทรัพยากรที่ไม่สําคัญในการเชื่อมต่อเครือข่ายที่ช้า
รูปที่ 4 เว็บไซต์เดียวกันในการเชื่อมต่อเดียวกัน ระบบจะยกเว้นเฉพาะทรัพยากรที่ "ควรมี" เพื่อช่วยให้โหลดเร็วขึ้น

คำแนะนำไคลเอ็นต์ช่วยลดเวลาในการโหลดหน้าเว็บจากกว่า 45 วินาทีเป็นน้อยกว่า 1 ใน 10 ของเวลาดังกล่าว ประโยชน์ของคำแนะนำไคลเอ็นต์ในสถานการณ์นี้เป็นสิ่งที่ไม่ควรมองข้าม และอาจเป็นประโยชน์อย่างมากต่อผู้ใช้ที่ต้องการข้อมูลสำคัญผ่านเครือข่ายที่ช้า

นอกจากนี้ คุณยังใช้คำแนะนำไคลเอ็นต์ได้โดยไม่ทำให้ประสบการณ์การใช้งานของเบราว์เซอร์ที่ไม่รองรับคำแนะนำดังกล่าวเสีย ตัวอย่างเช่น หากต้องการปรับการแสดงทรัพยากรโดยใช้ค่าของคำแนะนำ ECT ในขณะที่ยังคงแสดงประสบการณ์การใช้งานแบบเต็มสําหรับเบราว์เซอร์ที่ไม่รองรับ เราสามารถตั้งค่าการแทนที่เป็นค่าเริ่มต้นได้ดังนี้

// Set the ECT value to "4g" by default.
$ect = isset($_SERVER["HTTP_ECT"]) ? $_SERVER["HTTP_ECT"] : "4g";

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

ระวังแคชเหล่านั้น

ทุกครั้งที่คุณเปลี่ยนการตอบกลับตามส่วนหัว HTTP คุณต้องคำนึงถึงวิธีที่แคชจะจัดการการดึงข้อมูลทรัพยากรนั้นในอนาคต ส่วนหัว Vary เป็นสิ่งที่ขาดไม่ได้ในส่วนนี้ เนื่องจากจะกุญแจรายการแคชไปยังค่าของส่วนหัวคำขอที่ระบุ กล่าวโดยย่อคือ หากคุณแก้ไขการตอบกลับตามส่วนหัวคำขอ HTTP หนึ่งๆ คุณควรใส่คำขอส่วนหัวนั้นใน Vary เกือบทุกครั้ง ดังนี้

Vary: DPR, Width

แต่มีข้อควรระวังสำคัญอย่างหนึ่งคือ คุณไม่ควรVaryแคชคำตอบในส่วนหัวที่มีการเปลี่ยนแปลงบ่อย (เช่น Cookie) เนื่องจากทรัพยากรเหล่านั้นจะแคชไม่ได้ เมื่อทราบเช่นนี้ คุณอาจต้องหลีกเลี่ยงVaryการใช้ส่วนหัวคำแนะนำไคลเอ็นต์ เช่น RTT หรือ Downlink เนื่องจากเป็นปัจจัยการเชื่อมต่อที่อาจเปลี่ยนแปลงบ่อยครั้ง หากต้องการแก้ไขการตอบกลับในส่วนหัวเหล่านั้น ให้พิจารณาป้อนเฉพาะส่วนหัว ECT ซึ่งจะช่วยลดการไม่พบแคช

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

คำแนะนำสำหรับไคลเอ็นต์ใน Service Worker

การเจรจาต่อรองเนื้อหาไม่ได้มีไว้สำหรับเซิร์ฟเวอร์เท่านั้นอีกต่อไป เนื่องจาก Service Worker ทําหน้าที่เป็นพร็อกซีระหว่างไคลเอ็นต์กับเซิร์ฟเวอร์ คุณจึงควบคุมวิธีนําส่งทรัพยากรผ่าน JavaScript ได้ ซึ่งรวมถึงคำแนะนำไคลเอ็นต์ ในเหตุการณ์ fetch ของ Service Worker คุณสามารถใช้เมธอด request.headers.get ของออบเจ็กต์ event เพื่ออ่านส่วนหัวคำขอของทรัพยากรได้ ดังนี้

self.addEventListener('fetch', (event) => {
  let dpr = event.request.headers.get('DPR');
  let viewportWidth = event.request.headers.get('Viewport-Width');
  let width = event.request.headers.get('Width');

  event.respondWith(
    (async function () {
      // Do what you will with these hints!
    })(),
  );
});

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

คำแนะนำสำหรับไคลเอ็นต์ เทียบเท่า JS
`ECT` `navigator.connection.effectiveType`
`RTT` `navigator.connection.rtt`
`Save-Data` `navigator.connection.saveData`
`Downlink` `navigator.connection.downlink`
`Device-Memory` `navigator.deviceMemory`
ปลั๊กอิน Imagemin สำหรับประเภทไฟล์

เนื่องจาก API เหล่านี้ไม่พร้อมใช้งานในทุกที่ คุณจึงต้องตรวจสอบฟีเจอร์กับโอเปอเรเตอร์ in

if ('connection' in navigator) {
  // Work with netinfo API properties in JavaScript!
}

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

สรุป

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

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

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

แหล่งข้อมูล

ขอขอบคุณ Ilya Grigorik, Eric Portis, Jeff Posnick, Yoav Weiss และ Estelle Weyl ที่ให้ความคิดเห็นและแก้ไขบทความนี้