นอกจากการแคชตุ๊กตารัสเซียแล้ว ยังมีเทคนิคอื่นๆ อีกมากมายในการเร่งความเร็วประสิทธิภาพในแอป Rails คราวนี้เราจะดูการสนับสนุน GET แบบมีเงื่อนไขในตัวของ Rails ซึ่งช่วยให้คุณสามารถจัดเก็บหน้าที่แสดงผลไว้ในแคชของเบราว์เซอร์ของผู้ใช้
😏 และหากคุณชอบอ่านเพิ่มเติมเกี่ยวกับประสิทธิภาพนอกเหนือจากการแคช ยังมีอีกมากมายที่เราเขียนเกี่ยวกับประสิทธิภาพของ Ruby (บน Rails) ลองดูรายการตรวจสอบการติดตามประสิทธิภาพของ Ruby ของเรา
ส่วนหัว Etag และการแก้ไขล่าสุด
เมื่อเบราว์เซอร์ของคุณดำเนินการคำขอ HTTP GET สำหรับเพจในแอป Rails ของคุณ เราเตอร์จะเชื่อมโยงคำขอดังกล่าวกับการดำเนินการของคอนโทรลเลอร์ตัวใดตัวหนึ่งของคุณ ตัวควบคุมจะขอข้อมูลที่จำเป็นจากฐานข้อมูลและแสดงมุมมอง การตอบสนอง HTTP (ด้วย 02 เป็นโค้ดตอบกลับ) จากนั้นจะถูกส่งกลับไปยังเบราว์เซอร์พร้อมกับ HTML ที่แสดงผลจากมุมมองในเนื้อความของการตอบกลับเพื่อให้เบราว์เซอร์ของคุณแยกวิเคราะห์และแสดงผล
เมื่อมีการร้องขอทรัพยากรอีกครั้ง เราจะดำเนินการไปป์ไลน์เดียวกัน ในบางสถานการณ์ สิ่งนี้ไม่จำเป็นเนื่องจากเพจไม่มีการเปลี่ยนแปลงในระหว่างนี้ ด้วยเหตุนี้ HTTP จึงเสนอ ETag และ แก้ไขล่าสุด ส่วนหัว การใช้สิ่งเหล่านี้ เบราว์เซอร์สามารถจัดเก็บเนื้อหาการตอบกลับ และใช้ส่วนหัวเพื่อทำให้ใช้ไม่ได้เมื่อเนื้อหาเก่า
อีแท็ก หรือ แท็กเอนทิตี ใช้สำหรับการตรวจสอบแคชฝั่งไคลเอ็นต์ ดังนั้นคุณจึงมองว่าเป็นคีย์แคชสำหรับการตอบกลับ HTTP ของคุณ สิ่งเหล่านี้จะถูกส่งกลับไปยังเบราว์เซอร์ในส่วนหัวการตอบกลับ HTTP สำหรับทุกคำขอ
~ $ curl -I http://localhost:3000/products/1HTTP/1.1 200 ตกลง...ETag:W/"9462d76cc55aeb6249fa990e39231c7c"แก้ไขล่าสุด:พุธ 25 เมษายน 2018 08:27:04 GMT...
หากมีการตอบกลับซ้ำในภายหลัง เบราว์เซอร์จะค้นหาการตอบกลับที่มีอยู่ในแคชและใช้ Etag ที่จัดเก็บไว้จากคำขอล่าสุดเป็น 10 ส่วนหัว ส่วนหัวนี้จะบอกแอป Rails ของเราว่าเรามีเวอร์ชันนี้อยู่ในแคชแล้ว
หาก Etag จากคำขอตรงกับคำขอปัจจุบัน Rails จะส่ง 28 การตอบสนองโดยไม่มีเนื้อหาการตอบสนอง นี่จะเป็นการบอกให้เบราว์เซอร์ใช้อันจากแคชในเครื่องแทน
~ $ curl -i -H 'ถ้าไม่มีการจับคู่:W/"9462d76cc55aeb6249fa990e39231c7c"' http://localhost:3000/products/1HTTP/1.1 304 ไม่แก้ไข...ETag:W/"9462d76cc55aeb6249fa990e39231c7c"แก้ไขล่าสุด:พุธ 25 เมษายน 2018 08:27:04 GMT...
คำขอ GET แบบมีเงื่อนไขใน Rails
หากเราขอเพจจากแอปพลิเคชัน Rails ในเครื่อง เราจะเห็นว่า Rails เพิ่ม Etag สำหรับแต่ละคำขอโดยอัตโนมัติ หากเราขอหน้าเดียวกันสองครั้งติดต่อกัน เราจะเห็นการเปลี่ยนแปลง Etag สำหรับแต่ละคำขอ
แม้ว่า Rails จะสร้าง Etag สำหรับแต่ละคำขอตามค่าเริ่มต้น แต่ Rails จะใช้การสรุปเนื้อหาการตอบกลับทั้งหมดเพื่อสร้าง ซึ่งหมายความว่า 31 ในโครงร่างจะยกเลิก Etag เนื่องจากเมตาแท็ก csrf-token เปลี่ยนแปลงสำหรับแต่ละคำขอ เนื่องจากการเปลี่ยนแปลงเนื้อหาสำหรับแต่ละคำขอ Etag จึงใช้งานไม่ได้และแคชในเครื่องถูกทำเครื่องหมายว่าเก่า
นอกจากนั้น Rails จะไม่ส่งคืน 43 โดยค่าเริ่มต้น เนื่องจากแคชในเครื่องไม่เคยถูกทำเครื่องหมายว่าเป็นแคชอย่างชัดเจนในคอนโทรลเลอร์ของเรา
50รหัส> และ 60รหัส>
60รหัส> หากต้องการใช้ Etags จากส่วนหัวคำขอสำหรับ GET แบบมีเงื่อนไข เราจำเป็นต้องทำเครื่องหมายออบเจ็กต์ในแคชในเครื่องว่าเป็น "สด" อย่างชัดเจน ตัวอย่างเช่น สำหรับเพจที่แสดงผลิตภัณฑ์ เราสามารถเก็บแคชให้ใหม่ได้ตราบใดที่ผลิตภัณฑ์และเทมเพลตมุมมองไม่เปลี่ยนแปลง เพื่อให้สำเร็จ เราจะทำสองสิ่ง
- เราจะตั้งค่าอย่างชัดเจนที่จะสร้าง Etag ของเรา เนื่องจากการใช้เนื้อหาการตอบสนองทั้งหมดจะทำให้เราต้องแสดงผลทั้งเนื้อหาเพื่อตรวจสอบว่าการตอบสนองที่แคชไว้นั้นถูกต้องหรือไม่ ซึ่งจะขัดขวางการเร่งความเร็วจากการแคชเพจในเครื่อง
- เราจะเปรียบเทียบ Etag จากส่วนหัวของคำขอกับส่วนหัวที่เราคาดการณ์ไว้ก่อน แสดงผลมุมมอง และเราจะละเว้นการแสดงผลหากตรงกัน
Rails มาพร้อมกับผู้ช่วยที่ทำทุกอย่างเพื่อเรา เรากำหนดวันที่ Etag และ Last-Modified บนผลิตภัณฑ์ได้อย่างชัดเจนโดยใช้ 77 .
หากคุณมี 85 ที่ชัดเจน บล็อก ใช้ 90 แทนที่จะเป็น 104 .
ตอนนี้ การขอหน้าผลิตภัณฑ์หน้าใดหน้าหนึ่งจะเป็นการแคชการตอบกลับในเครื่อง คำขอใดๆ ที่ตามมาในหน้าเดียวกันจะรวม Etag เพื่อบอก Rails ว่าเรามีคำตอบที่แคชไว้ ซึ่งจะถูกนำไปเปรียบเทียบกับ Etag ใหม่ หากตรงกัน Rails จะข้ามการแสดงผลเพจและส่งคืน 117 ทันที

หมายเหตุ :การรีเฟรชเพจจะขอเวอร์ชันที่ไม่ได้แคชของเพจเสมอ หากต้องการทดสอบว่า GET แบบมีเงื่อนไขของคุณใช้งานได้หรือไม่ ให้นำทางออกไปโดยใช้ลิงก์หรือใช้ปุ่มย้อนกลับแทน
คุณชอบบทความนี้และบทความก่อนหน้าในชุด AppSignal Academy อย่างไร เรามีบทความเพิ่มเติมเกี่ยวกับการแคชใน Rails เรียงรายอยู่ แต่โปรดอย่าลังเลที่จะแจ้งให้เราทราบว่าคุณอยากให้เราเขียนเกี่ยวกับอะไร (เกี่ยวกับการแคชหรืออย่างอื่น) ต่อไป!