Apakah layak untuk mengubah seluruh struktur file gambar pengguna saya untuk mengambil keuntungan dari cache browser yang sederhana?

9

Di salah satu situs seluler saya, saya hanya menyimpan gambar profil pengguna saya sebagai '1.jpg' di folder pengguna mereka, dan secara bertahap pergi dari sana untuk setiap foto tambahan yang mereka unggah. Ini berarti bahwa setiap kali mereka mengubah gambar profil mereka, misalnya, nama file tetap sama.

Saya ingin memanfaatkan cache gambar sehingga gambar lama yang sama tidak dapat diunduh berulang kali setiap kali profil pengguna dilihat dan dilihat kembali, tetapi pada saat yang sama, saya ingin browser pengguna saya untuk unduh yang baru jika sudah berubah.

Dari apa yang telah saya baca, tampaknya satu-satunya cara untuk benar-benar melakukan ini adalah dengan benar-benar menggunakan nama file acak dan melacak semua nama file di DB, sehingga Anda dapat mengatur cache yang tidak kedaluwarsa, sementara baru-baru ini -hampir berubah bisa ditarik lagi karena mereka memiliki nama file baru. Keindahan dari cara saya membuat mereka terstruktur sampai sekarang, bagaimanapun, adalah bahwa saya dapat melewatkan database sepenuhnya dan mengakses file secara langsung karena lokasi mereka dapat diprediksi.

Jadi pertanyaan saya adalah, apakah layak bagi saya untuk mengubah seluruh struktur file situs saya, ditambah menambahkan elemen DB, untuk kepentingan caching abadi dan mengunduh ulang otomatis pada unggahan baru?

Ini adalah usaha yang sangat besar, tetapi jika dianggap layak, saya tidak punya masalah bergerak maju dengan perubahan drastis ini. Saya hanya ingin memastikan ini adalah cara "big boys" melakukannya sehingga saya tidak perlu mengubah struktur file lagi.

Terima kasih.

ProgrammerGirl
sumber

Jawaban:

7

Salah satu solusi yang umum digunakan adalah membuat URL gambar Anda terlihat seperti ini:

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

Di sini, /path/to/images/1.jpgadalah jalur URL sebenarnya dari gambar, sementara ?v=123456itu hanya kueri dummy yang menatap ditempelkan di akhir URL. String kueri dapat berupa apa saja - nomor versi, stempel waktu, hash dari konten gambar - selama Anda mengubahnya setiap kali gambar berubah, dan tetap sama ketika tidak.

Kuncinya adalah bahwa server web, ketika diminta untuk melayani URL seperti itu, akan mengabaikan string kueri, karena URL sebenarnya menunjuk ke file statis. Tetapi untuk browser pengguna (dan ke proksi mana pun di antaranya), URL dengan string kueri yang berbeda akan sangat berbeda, dan setiap perubahan pada string kueri memaksa browser untuk memuat ulang file.

Dengan demikian, Anda dapat mengkonfigurasi server web Anda untuk mengirim Expiresdan Cache-Controlheader HTTP untuk memungkinkan caching tidak terbatas, aman karena mengetahui bahwa Anda dapat memaksa memuat ulang dengan mengubah string kueri. Salah satu cara untuk melakukannya, jika Anda menggunakan Apache dengan mod_expires , adalah dengan meletakkan .htaccessfile di direktori gambar Anda dengan baris:

ExpiresActive On
ExpiresDefault "access plus 1 year"

Teknik ini digunakan oleh banyak situs web populer. Misalnya, jika Anda melihat sumber HTML dari halaman ini, Anda akan menemukan bahwa style sheet untuk itu diambil dari URL seperti ini:

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

Di sini, ?v=7cd8ea9d6f1eini adalah string kueri dummy seperti yang saya jelaskan di atas; Anda dapat mengonfirmasi bahwa dengan mengubahnya dan melihatnya memang masih mengembalikan file yang sama.

Ilmari Karonen
sumber
Juga menarik, tetapi bagaimana saya akan melacak kapan file terakhir kali diubah vs ketika browser pertama kali dilihat, untuk menentukan kapan saya harus memberitahu browser pengguna untuk mengambilnya lagi (misalnya dengan mengubah nilai permintaan)?
ProgrammerGirl
1
Anda tidak perlu melacak ketika file dilihat. Pantau terus kapan file terakhir kali diubah (atau properti lain yang sesuai) dan sertakan dalam string kueri. Dengan begitu, setiap kali file berubah, URL akan berubah juga.
Ilmari Karonen
Sangat, sangat, menarik. Jadi saya mungkin bisa mengambil properti "terakhir dimodifikasi" dari file, dan hanya membuat nilai kueri, benar?
ProgrammerGirl
1
Ya, itu seharusnya berhasil.
Ilmari Karonen
1
Tidak ada kerugian signifikan yang saya sadari. Anda mungkin berakhir dengan salinan duplikat gambar Anda di indeks mesin pencari, tetapi setidaknya mesin pencari utama seperti Google cukup pintar dalam menangani hal-hal seperti itu, karena itu adalah trik yang umum. Dalam kasus apa pun, masalah itu dapat dikurangi dengan mengirimkan header HTTP rel = "canonical" dan dengan menjaga waktu kedaluwarsa Anda sederhana (katakanlah, hanya satu bulan atau satu minggu, bukan satu tahun penuh).
Ilmari Karonen
6

Ada lebih dari satu cara untuk melakukan cache.

GET bersyarat

Jika Anda menyimpan gambar-gambar ini di sistem file dan menyajikannya langsung melalui server web, Anda mungkin sudah menggunakan get kondisional . Server web akan secara otomatis menggunakan metadata sistem file untuk mengatur header ETAG, dan secara otomatis akan menjawab dengan "304 Tidak Dimodifikasi" jika browser menyertakan If-Modified-Sinceatau If-Matchesheader dalam permintaannya. (Semua browser akan.)

Dalam hal ini seluruh gambar tidak disajikan kembali, sehingga Anda memiliki penghematan bandwidth. Namun, permintaan GET masih akan dikeluarkan, sehingga Anda masih memiliki overhead dan latensi permintaan.

Anda dapat mengurangi jumlah permintaan dengan mengorbankan kesegaran cache dengan membuat server web Anda menetapkan Cache-Controlheader dengan public,max-age=Nnilai untuk gambar Anda. Ini mengatakan bahwa cache dapat menyimpan sumber daya paling banyak max-agedetik sebelum mereka harus memeriksa apakah itu diperbarui.

Namun, HTTP hanya menetapkan satu cara untuk membatalkan entri cache, yang mungkin tidak sesuai dengan semantik aplikasi Anda: jika Anda POST atau PUT ke url yang memperbarui foto profil, balas dengan Location: [url of photo]header dan entri cache untuk url itu akan dibatalkan.

(Ini adalah mekanisme yang memungkinkan Anda untuk me-cache halaman web dengan komentar, dan kemudian memiliki halaman reload secara paksa oleh browser setelah pengguna memposting komentar baru. Browser akan membalas POST /commentdengan 303 See Otherdan a Location: /page/with/comment. Perhatikan bahwa ini tidak digunakan untuk bekerja di Firefox karena bug yang sudah berlangsung lama .)

Kecuali Anda memiliki banyak lalu lintas, pendekatan caching ini baik-baik saja.

Mengubah url

Sebuah url adalah representasi dari sumber daya, jadi cara lain untuk mengelola caching adalah tidak mengubah parameter cache untuk sumber daya, tetapi untuk membuat sumber daya baru dengan arahan "cache forever". Ini adalah pendekatan yang disukai "anak besar", karena memungkinkan mereka untuk tidak menghasilkan permintaan tambahan, menghemat banyak bandwidth. Kelemahannya adalah itu membutuhkan lebih banyak pembukuan tambahan.

Ada dua teknik umum untuk ini.

String pertanyaan

Server web mengabaikan string kueri saat menyajikan file dari sistem file. Namun, cache tidak: /1.jpg?t=12345dan /1.jpg?t=67890dua sumber daya yang sama sekali berbeda dan tidak terkait, meskipun server berpikir mereka sama.

Jadi satu hal mudah yang dapat Anda lakukan adalah menambahkan timestamp sistem file sebagai string kueri setiap kali Anda membuat referensi ke sumber daya di html Anda, dan mengatur Expiresheader panjang . Browser kemudian akan menembolok sumber daya ini selamanya dan tidak melakukan GET apapun selama string kueri tidak berubah.

Kelemahannya adalah sulit atau tidak mungkin untuk menginstruksikan server web dari url baru untuk suatu item jika Anda ingin secara paksa membatalkan cache. Misalnya, jika browser memiliki halaman HTML dalam cache dengan /1.jpg?v=1referensi, tetapi kebetulan menghapus entri untuk /1.jpg?v=1(mungkin kehabisan file atau ruang memori), itu akan membuat permintaan baru untuk /1.jpg?v=1. Jika sementara itu gambar berubah /1.jpg?v=2, respons yang tepat adalah:

  1. Sajikan versi file yang lama. Anda akan melakukan ini jika Anda ingin semua sumber daya konsisten satu sama lain karena mereka berada pada titik waktu tertentu. Ini yang harus Anda lakukan dengan file CSS, misalnya, karena file css baru dengan file html lama mungkin tidak berfungsi dengan baik!
  2. Arahkan ke versi baru file menggunakan 301 Moved Permanently. Anda akan melakukan ini jika Anda ingin semua sumber daya menjadi baru mungkin.

Kedua hal ini sulit dilakukan dengan server web saja, yang berarti Anda harus menjalankan aplikasi web bahkan untuk permintaan gambar, yang dapat menjadi lebih rumit dan lebih intensif sumber daya. Webservers sangat cepat dalam melayani file, sehingga overhead aplikasi web mungkin akhirnya menelan bandwidth dan keuntungan latensi Anda.

Nama file

Alih-alih menambahkan string kueri, Anda mengubah nama file. Ini berarti mudah untuk menyimpan beberapa versi file pada sistem file, tetapi Anda mungkin perlu menyimpan metadata file dan melakukan pembukuan basis data lainnya untuk melacak sumber daya dan nama mereka.


sumber
0

membaca tentang status http 304 Not Modified, Anda harus dapat menanggapi permintaan unduhan dengan 304, dan dengan itu memberitahu server untuk menggunakan data yang di-cache, insted untuk mengirim ulang ke browser. dan baca pertanyaan ini /programming/2978496/make-php-page-return-304-not-modified-if-it-hasnt-been-modified

Puggan Se
sumber
Menarik, tetapi apakah ini solusi "bantuan band" untuk skema file yang bermasalah, atau apakah skema file saya baik dan hanya perlu kemampuan caching ini? Juga, bagaimana saya tahu kapan file terakhir diubah vs ketika browser pertama kali dilihat, untuk menentukan kapan saya harus memberitahu browser pengguna untuk mengambilnya lagi?
ProgrammerGirl
Saya tidak begitu akrab dengan itu, pikir Francis Avila tahu lebih banyak tentang hal itu
Puggan Se