มันคุ้มค่าหรือไม่ที่จะเปลี่ยนโครงสร้างไฟล์รูปภาพผู้ใช้ทั้งหมดของฉันเพื่อใช้ประโยชน์จากการแคชเบราว์เซอร์อย่างง่าย ๆ ?


9

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

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

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

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

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

ขอบคุณ

คำตอบ:


7

วิธีแก้ปัญหาที่ใช้กันทั่วไปวิธีหนึ่งคือทำให้ URL รูปภาพของคุณมีลักษณะดังนี้:

http://www.example.com/path/to/images/1.jpg?v=123456

นี่/path/to/images/1.jpgคือเส้นทาง URL ที่แท้จริงของรูปภาพในขณะที่?v=123456เป็นเพียงแบบสอบถามจำลองที่จ้องมองไปที่ส่วนท้ายของ URL สตริงข้อความค้นหาสามารถเป็นได้ทุกอย่างไม่ว่าจะเป็นหมายเลขเวอร์ชั่นเวลาประทับความยุ่งเหยิงของเนื้อหาภาพตราบใดที่คุณเปลี่ยนแปลงเมื่อใดก็ตามที่ภาพมีการเปลี่ยนแปลงและทำให้เหมือนเดิมทุกครั้ง

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

ดังนั้นคุณสามารถกำหนดค่าเว็บเซิร์ฟเวอร์ของคุณเพื่อส่งExpiresและCache-Controlส่วนหัว HTTP เพื่อให้แคชไม่ จำกัด ปลอดภัยในความรู้ที่คุณสามารถบังคับให้โหลดซ้ำโดยการเปลี่ยนสตริงแบบสอบถาม วิธีหนึ่งในการทำเช่นนั้นหากคุณใช้ Apache กับmod_expiresคือการวาง.htaccessไฟล์ในไดเรกทอรีรูปภาพด้วยบรรทัด:

ExpiresActive On
ExpiresDefault "access plus 1 year"

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

http://cdn.sstatic.net/stackoverflow/all.css?v=7cd8ea9d6f1e

นี่?v=7cd8ea9d6f1eคือสตริงเคียวรี dummy เหมือนกับที่ฉันอธิบายไว้ข้างต้น คุณสามารถยืนยันได้โดยเปลี่ยนมันและเห็นว่ามันยังคงส่งคืนไฟล์เดียวกัน


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

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

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

1
ใช่ว่าควรจะทำงาน
Ilmari Karonen

1
ไม่มีข้อเสียอย่างมีนัยสำคัญใด ๆ ที่ฉันตระหนักถึง คุณอาจท้ายด้วยสำเนาที่ซ้ำกันของภาพของคุณในดัชนีเครื่องมือค้นหา แต่อย่างน้อยเครื่องมือค้นหาสำคัญ ๆ เช่น Google นั้นฉลาดมากเกี่ยวกับการจัดการกับสิ่งต่าง ๆ เนื่องจากมันเป็นกลอุบายทั่วไป ไม่ว่าในกรณีใดปัญหานั้นสามารถบรรเทาได้ด้วยการส่งrel = "canonical" ส่วนหัว HTTPและทำให้การหมดอายุของคุณนั้นเรียบง่าย (พูดเพียงแค่หนึ่งเดือนหรือหนึ่งสัปดาห์แทนที่จะเป็นทั้งปี)
Ilmari Karonen

6

มีวิธีแคชมากกว่าหนึ่งวิธี

รับเงื่อนไข

หากคุณกำลังจัดเก็บภาพเหล่านี้บนระบบไฟล์และให้บริการพวกเขาโดยตรงผ่านเว็บเซิร์ฟเวอร์คุณอาจจะใช้อยู่แล้วได้รับเงื่อนไข เว็บเซิร์ฟเวอร์จะใช้ข้อมูลเมตาของระบบไฟล์โดยอัตโนมัติเพื่อตั้งค่าส่วนหัว ETAG และจะตอบกลับโดยอัตโนมัติด้วย "304 Not Modified" หากเบราว์เซอร์มีIf-Modified-SinceหรือรวมIf-Matchesส่วนหัวไว้ในคำขอ (เบราว์เซอร์ทั้งหมดจะ)

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

คุณสามารถลดจำนวนการร้องขอเล็กน้อยโดยเสียค่าใช้จ่ายของความสดแคชโดยให้เว็บเซิร์ฟเวอร์ของคุณตั้งค่าCache-Controlส่วนหัวด้วยpublic,max-age=Nค่าสำหรับรูปภาพของคุณ สิ่งนี้บอกว่าแคชสามารถเก็บทรัพยากรได้นานไม่max-ageกี่วินาทีก่อนที่พวกเขาจะต้องตรวจสอบว่ามีการอัพเดทหรือไม่

อย่างไรก็ตาม HTTP จะกำหนดวิธีเดียวในการทำให้รายการแคชไม่ถูกต้องซึ่งอาจไม่ตรงกับความหมายของแอปพลิเคชันของคุณ: หากคุณโพสต์หรือ PUT ไปยัง URL ที่อัปเดตรูปโปรไฟล์ให้ตอบกลับด้วยLocation: [url of photo]ส่วนหัวและรายการแคชสำหรับ URL นั้น

(นี่เป็นกลไกที่ช่วยให้คุณสามารถแคชหน้าเว็บที่มีความคิดเห็นแล้วให้โหลดหน้าเว็บใหม่โดยเบราว์เซอร์หลังจากผู้ใช้โพสต์ความคิดเห็นใหม่เบราว์เซอร์จะตอบกลับPOST /commentด้วย303 See Otherและ a Location: /page/with/commentโปรดทราบว่าสิ่งนี้ไม่ได้ใช้ ทำงานใน Firefox เนื่องจากข้อผิดพลาดที่ยาวนาน )

หากคุณไม่มีปริมาณข้อมูลมากวิธีการนี้จะใช้แคชได้ดี

เปลี่ยน URL

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

มีสองเทคนิคทั่วไปสำหรับการนี้

สตริงการสืบค้น

เว็บเซิร์ฟเวอร์ละเว้นสตริงการสืบค้นเมื่อให้บริการไฟล์จากระบบไฟล์ อย่างไรก็ตามแคชไม่ได้: /1.jpg?t=12345และ/1.jpg?t=67890เป็นทรัพยากรที่แตกต่างกันสองอย่างที่ไม่เกี่ยวข้องกันอย่างสมบูรณ์แม้ว่าเซิร์ฟเวอร์จะคิดเหมือนกันก็ตาม

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

ข้อเสียคือมันเป็นเรื่องยากหรือเป็นไปไม่ได้ที่จะสั่งให้เว็บเซิร์ฟเวอร์ของ URL ใหม่สำหรับรายการหากคุณต้องการบังคับให้แคชใช้ไม่ได้ ตัวอย่างเช่นหากเบราว์เซอร์ที่มีหน้า HTML เก็บไว้ชั่วคราวที่มี/1.jpg?v=1การอ้างอิง แต่เกิดขึ้นเพื่อล้างรายการสำหรับ/1.jpg?v=1(บางทีมันอาจจะวิ่งออกมาจากไฟล์หรือพื้นที่หน่วยความจำ) /1.jpg?v=1ก็จะทำให้คำขอใหม่เพื่อ หากในขณะเดียวกันภาพได้เปลี่ยน/1.jpg?v=2เป็นการตอบสนองที่เหมาะสมคือ:

  1. ให้บริการไฟล์เวอร์ชันเก่า คุณจะทำเช่นนี้หากคุณต้องการให้ทรัพยากรทั้งหมดสอดคล้องกันเหมือนอยู่ในช่วงเวลาหนึ่ง นี่คือสิ่งที่คุณควรทำกับไฟล์ CSS เช่นเนื่องจากไฟล์ css ใหม่ที่มีไฟล์ html เก่าอาจทำงานไม่ถูกต้อง!
  2. 301 Moved Permanentlyเปลี่ยนเส้นทางไปยังรุ่นใหม่ของไฟล์โดยใช้ คุณจะทำเช่นนี้หากคุณต้องการให้ทรัพยากรทั้งหมดเป็นทรัพยากรใหม่

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

ชื่อไฟล์

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


0

อ่านเกี่ยวกับสถานะ http 304 Not Modifiedคุณควรจะสามารถตอบสนองต่อคำขอดาวน์โหลดที่มี 304 และโดยที่บอกให้เซิร์ฟเวอร์ใช้ข้อมูลที่เก็บไว้ในแคชแล้วส่งไปยังเบราว์เซอร์อีกครั้ง และอ่านคำถามนี้/programming/2978496/make-php-page-return-304-not-modified-if-it-hasnt-been-modified


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

ฉันไม่คุ้นเคยกับมันเลยคิดว่าฟรานซิสอาวิลารู้มากขึ้นเกี่ยวกับมัน
Puggan Se
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.