ชอบแคชของคุณ ❤️

ผู้ใช้ที่โหลดเว็บไซต์ของคุณเป็นครั้งที่ 2 จะใช้แคช HTTP ของตัวเอง ดังนั้นตรวจสอบว่าเว็บไซต์ทำงานได้ดี

โพสต์นี้เป็นวิดีโอที่แสดงร่วมกันกับวิดีโอชอบแคชของคุณ ซึ่งเป็นส่วนหนึ่งของเนื้อหาขยายที่งาน Chrome Dev Summit 2020 อย่าลืมรับชมวิดีโอ

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

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

เป้าหมาย

เมื่อเว็บไซต์โหลดเป็นครั้งที่ 2 คุณจะมีเป้าหมาย 2 ประการ ได้แก่

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

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

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

ที่มา

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

ผู้ใช้ขาประจำบนอินเทอร์เน็ตไม่ได้มีของหรูขนาดนั้นหรอก ดังนั้นแม้ว่าเราจะมีเป้าหมายหลักๆ เพื่อให้ผู้ใช้มีช่วงเวลาที่ดีในการโหลดครั้งที่ 2 แต่ก็เป็นสิ่งสำคัญเช่นกันที่จะตรวจสอบว่าผู้ใช้ไม่มีช่วงเวลาอันเลวร้ายหรือเกิดติดขัด (ดูวิดีโอหากคุณต้องการฟังฉันพูดถึงสาเหตุต่างๆ ที่ทำให้เว็บไซต์ web.dev/live ของเราขัดข้อง)

ด้วยเหตุผลเบื้องต้น เหตุผลที่พบได้บ่อยจริงๆ ที่ทำให้ "แคชไม่มีอัปเดต" คือค่าเริ่มต้นของการแคชในยุค 1999 โดยใช้ส่วนหัว Last-Modified:

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

ทุกไฟล์ที่คุณโหลดจะถูกเก็บไว้อีก 10% ของอายุการใช้งานปัจจุบันตามแต่เบราว์เซอร์เห็น ตัวอย่างเช่น หาก index.html สร้างขึ้นเมื่อ 1 เดือนที่ผ่านมา เบราว์เซอร์จะถูกแคชไว้อีกประมาณ 3 วัน

แนวคิดนี้เกิดขึ้นได้เป็นอย่างดีในช่วงวันนั้น แต่เนื่องจากเว็บไซต์ในปัจจุบันมีลักษณะที่ผสานรวมอย่างเหนียวแน่น พฤติกรรมเริ่มต้นเช่นนี้จึงเป็นไปได้ที่ผู้ใช้มีไฟล์ที่ออกแบบมาเพื่อเว็บไซต์รุ่นต่างๆ ของคุณ (เช่น JS ตั้งแต่การเผยแพร่วันอังคาร และ CSS จากการเผยแพร่วันศุกร์) ทั้งหมดจึงเป็นเพราะไฟล์เหล่านั้นไม่ได้อัปเดตในช่วงเวลาเดียวกัน

เส้นทางที่มีแสงสว่างเพียงพอ

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

คุณกำหนดค่าโฮสต์เว็บของคุณให้ตอบกลับคำขอของเว็บด้วยส่วนหัวนี้ได้ ดังนี้

Cache-Control: max-age=0,must-revalidate,public

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

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

อย่างไรก็ตาม วิธีนี้เป็นวิธีสมัยใหม่ที่เป็นค่าเริ่มต้นใน CDN ยอดนิยม แต่สามารถกำหนดค่าได้ใน CDN เกือบทุกแห่ง สำหรับโฮสติ้งของ Firebase คุณสามารถใส่ส่วนหัวนี้ในส่วนโฮสติ้งของไฟล์ firebase.json

"headers": [
  // Be sure to put this last, to not override other headers
  {
    "source": "**",
    "headers": [ {
      "key": "Cache-Control",
      "value": "max-age=0,must-revalidate,public"
    }
  }
]

ดังนั้นแม้ว่าฉันจะยังแนะนำตัวเลือกนี้เป็นค่าเริ่มต้นที่เหมาะสม แต่มีเพียงค่าเริ่มต้นเท่านั้น อ่านต่อไปเพื่อดูวิธีดำเนินการและอัปเกรดค่าเริ่มต้น

URL ที่มีการเก็บลายนิ้วมือ

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

Cache-Control: max-age=31536000,immutable

ค่านี้คือปี เป็นวินาที และตามข้อกำหนดแล้ว นี่ก็คือ "ตลอดไป" อย่างมีประสิทธิภาพ

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

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

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

แน่นอนว่าเราไม่สามารถเปลี่ยนชื่อหน้าเว็บที่ "เป็นมิตรกับผู้ใช้" ในลักษณะนี้ได้ เช่น การเปลี่ยนชื่อไฟล์ index.html เป็น index.abcd12.html เป็นสิ่งที่ทำไม่ได้ และคุณไม่สามารถบอกผู้ใช้ให้ไปที่ URL ใหม่ทุกครั้งที่โหลดเว็บไซต์ของคุณ! URL ที่ "ปลอดภัย" เหล่านี้ไม่สามารถเปลี่ยนชื่อและแคชด้วยวิธีนี้ ซึ่งจะนำฉันไปอยู่ตรงกลาง

พื้นที่ตรงกลาง

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

หากคุณต้องการแคช URL ที่ "ใช้งานง่าย" และ HTML ของ URL ดังกล่าว คุณควรพิจารณาถึงทรัพยากร Dependency ที่รายการดังกล่าวรวมไว้ วิธีการแคชURL และการแคช URL ของ URL แต่ละครั้งอาจส่งผลต่อคุณ ลองดูหน้า HTML ที่มี รูปภาพลักษณะนี้

<img src="/images/foo.jpeg" loading="lazy" />

หากคุณอัปเดตหรือเปลี่ยนแปลงเว็บไซต์โดยการลบหรือเปลี่ยนรูปภาพที่โหลดแบบ Lazy Loading นี้ ผู้ใช้ที่ดู HTML ในเวอร์ชันที่แคชไว้อาจได้รับรูปภาพที่ไม่ถูกต้องหรือขาดหายไป เนื่องจากยังคงแคช /images/foo.jpeg เดิมไว้เมื่อกลับมาที่เว็บไซต์อีกครั้ง

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

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

Cache-Control: max-age=3600,immutable,public

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

ตัวเลือกที่ไม่ใช่ HTML

นอกจาก HTML แล้ว ตัวเลือกอื่นๆ สำหรับไฟล์ที่อยู่ในพื้นที่ตรงกลางมีดังนี้

  • โดยทั่วไปแล้ว มองหาเนื้อหาที่ไม่ได้ส่งผลกระทบต่อผู้อื่น

    • เช่น หลีกเลี่ยง CSS เนื่องจากจะทำให้วิธีแสดงผล HTML มีการเปลี่ยนแปลง
  • รูปภาพขนาดใหญ่ที่ใช้เป็นส่วนหนึ่งของบทความในเวลาที่เหมาะสม

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

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

สรุป

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

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

ดูเพิ่มเติม

ดูคำแนะนำทั่วไปเกี่ยวกับแคช HTTP ได้ที่ป้องกันคำขอเครือข่ายที่ไม่จำเป็นด้วยแคช HTTP