Basit tarayıcı önbelleklemesinden yararlanmak için tüm kullanıcı resimleri dosya yapımı değiştirmeye değer mi?


9

Mobil sitelerimden birinde, kullanıcının profil resimlerini kullanıcı klasöründe '1.jpg' olarak saklıyorum ve yükledikleri ekstra resimler için kademeli olarak oradan gidiyorum. Bu, profil resimlerini her değiştirdiklerinde, örneğin dosya adının aynı kaldığı anlamına gelir.

Bir kullanıcının profili her görüntülendiğinde ve yeniden görüntülendiğinde aynı eski resmin tekrar tekrar indirilmemesi için resim önbelleğinden yararlanmak istedim, ancak aynı zamanda kullanıcılarımın tarayıcılarının değiştiyse yenisini indirin.

Okuduğum kadarıyla, bunu gerçekten yapmanın tek yolunun, rastgele dosya adlarını kullanmak ve DB'deki tüm bu dosya adlarını takip etmektir, böylece son zamanlarda süresi dolmayan bir önbellek ayarlayabilirsiniz -değiştirilen resimler yeni bir dosya adına sahip oldukları için tekrar çekilir. Ancak şimdiye kadar yapılandırılmış olma yolumun güzelliği, veritabanını tamamen atlayabilmem ve konumlarının öngörülebilir olması nedeniyle doğrudan dosyalara erişebilmem.

Yani sorum şu: Sitemdeki tüm dosya yapısını değiştirmem ve DB elemanını eklemem, yeni yükleme sonrasında ebedi önbellekleme ve otomatik yeniden indirme avantajına değer mi?

Bu büyük bir girişim, ama eğer layık görülürse, bu şiddetli değişiklikle ilerlerken sorunum yok. Ben sadece bu "büyük çocuklar" bunu nasıl yapmak emin olmak istiyorum böylece dosya yapısını bir daha asla değiştirmek zorunda kalmam.

Teşekkürler.

Yanıtlar:


7

Yaygın olarak kullanılan bir çözüm, resim URL'lerinizin şöyle görünmesini sağlamaktır:

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

Burada, /path/to/images/1.jpggörüntünün gerçek URL yolu ?v=123456, URL'nin sonuna yapıştırılmış sadece sahte bir sorgu. Sorgu dizesi, görüntü değiştiğinde değiştirdiğiniz sürece sürüm numarası, zaman damgası, resim içeriğinin karması gibi herhangi bir şey olabilir ve değişmediği zaman aynı kalmasını sağlar.

İşin püf noktası, web sunucusunun böyle bir URL sunması istendiğinde sorgu dizesini yok sayacaktır, çünkü URL aslında statik bir dosyayı işaret eder. Ancak, kullanıcının tarayıcısında (ve aradaki herhangi bir proxy'de), farklı sorgu dizelerine sahip URL'ler tamamen farklı olacaktır ve bu nedenle sorgu dizesinde yapılacak herhangi bir değişiklik, tarayıcıyı dosyayı yeniden yüklemeye zorlar.

Böylece, göndermek, web sunucusu yapılandırabilir Expiresve Cache-Controlsorgu dizesi değiştirerek yeniden kuvvet bilerek güvenli belirsiz önbelleğe alma, izin HTTP başlıkları. Bunu yapmanın bir yolu, mod_expires ile Apache kullanıyorsanız .htaccess, resim dizininize şu satırları içeren bir dosya koymaktır :

ExpiresActive On
ExpiresDefault "access plus 1 year"

Bu teknik birçok popüler web sitesi tarafından kullanılmaktadır. Örneğin, bu sayfanın HTML kaynağına bakarsanız, stil sayfasının aşağıdaki gibi bir URL'den yüklendiğini görürsünüz:

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

Burada, ?v=7cd8ea9d6f1eyukarıda tarif ettiğim gibi bir kukla sorgu dizesidir; bunu değiştirerek ve gerçekten de aynı dosyayı döndürdüğünü görerek onaylayabilirsiniz.


Ayrıca ilginç, ancak kullanıcının tarayıcısına ne zaman tekrar getirmesini (örn. Sorgu değerini değiştirerek) ne zaman söylemem gerektiğini belirlemek için, dosyanın ilk kez ne zaman tarayıcıya ilk bakıldığında ne zaman değiştirildiğini nasıl izleyebilirim?
ProgrammerGirl

1
Dosyanın ne zaman görüntülendiğini izlemenize gerek yoktur. Dosyanın en son ne zaman değiştirildiğini (veya başka bir uygun özelliğini) takip edin ve sorgu dizesine ekleyin. Bu şekilde, dosya her değiştiğinde, URL de değişecektir.
Ilmari Karonen

Çok, çok, ilginç. Bu yüzden muhtemelen dosyaların "son değiştirildi" özelliğini getirebilir ve sadece sorgu değeri, doğru yapabilir miyim?
ProgrammerGirl

1
Evet, işe yaramalı.
Ilmari Karonen

1
Farkında olduğum önemli bir dezavantaj yok. Arama motoru dizinlerinde resimlerinizin kopyalarını alabilirsiniz, ancak en azından Google gibi büyük arama motorları bu tür şeylerle uğraşmak konusunda oldukça zekidir, çünkü bu çok yaygın bir numaradır. Her durumda, rel = "canonical" HTTP üstbilgileri göndererek ve son kullanma sürelerinizi mütevazı tutarak (örneğin, tüm yıl yerine yalnızca bir ay veya bir hafta) bu sorunu hafifletebilirsiniz .
Ilmari Karonen

6

Önbelleklemenin birden fazla yolu vardır.

Koşullu GET

Bu görüntüleri dosya sisteminde saklıyorsanız ve doğrudan web sunucusu üzerinden sunuyorsanız, büyük olasılıkla koşullu get kullanıyorsunuzdur . Web sunucusu, bir ETAG üstbilgisi ayarlamak için dosya sistemi meta verilerini otomatik olarak kullanır ve tarayıcı isteğinde yer alıyorsa If-Modified-Sinceveya If-Matchesüstbilgiler içeriyorsa otomatik olarak "304 Değiştirilmedi" ile yanıt verir . (Tüm tarayıcılar çalışacaktır.)

Bu durumda görüntünün tamamı geri sunulmaz, bu nedenle bant genişliği tasarrufunuz olur. Bununla birlikte, bir GET isteği düzenlenmeye devam edecektir, bu nedenle yine de bir isteğin ek yükü ve gecikmesine sahip olacaksınız.

Web sunucunuzun Cache-Controlüstbilgilerinizi public,max-age=Nresimleriniz için bir değer ayarlamasını sağlayarak önbellek tazeliği pahasına istek sayısını biraz azaltabilirsiniz . Bu, önbelleklerin max-agegüncellenip güncellenmediğini kontrol etmeden önce kaynağı en fazla saniye tutabileceğini söylüyor .

Ancak HTTP, uygulamanızın semantiğine uymayabilecek bir önbellek girdisini geçersiz kılmanın yalnızca bir yolunu tanımlar: profil fotoğrafını güncelleyen bir URL'ye POST veya PUT yazarsanız, bir Location: [url of photo]üstbilgiyle yanıtlayın ve bu url için önbellek girdisi geçersiz kılınacaktır.

(Bu, bir web sayfasını yorumlarla önbelleğe almanızı ve ardından kullanıcı yeni bir yorum gönderdikten sonra sayfayı tarayıcı tarafından zorla yeniden yüklemenizi sağlayan mekanizmadır. Tarayıcı bir POST /commentile 303 See Otherve a'ya yanıt verecektir Location: /page/with/comment. Uzun süredir devam eden bir hata nedeniyle Firefox'ta çalışmak .)

Çok fazla trafiğiniz olmadığı sürece, bu önbelleğe alma yaklaşımı iyidir.

URL'leri değiştirme

URL, bir kaynağın temsilidir, bu nedenle önbelleğe almayı yönetmenin başka bir yolu da kaynağın önbellek parametrelerini değiştirmek değil, "sonsuza kadar önbellek" direktifiyle yepyeni bir kaynak oluşturmaktır. Bu, "büyük oğlanlar" ın tercih ettiği yaklaşımdır, çünkü fazladan istek üretmelerine izin vermez , bu da onları çok fazla bant genişliği tasarrufu sağlar. Dezavantajı çok daha fazla defter tutma gerektirir.

Bunun için iki genel teknik vardır.

Sorgu dizeleri

Web sunucuları, dosya sisteminden bir dosya sunarken sorgu dizelerini yok sayar. Ancak önbellekler şunları yapmaz: /1.jpg?t=12345ve /1.jpg?t=67890sunucu aynı olduklarını düşünmesine rağmen tamamen farklı, ilgisiz iki kaynaktır.

Yapabileceğiniz kolay bir şey, html'nizdeki bir kaynağa başvuru yaptığınızda ve uzun bir Expiresbaşlık ayarladığınızda dosya sistemi zaman damgasını sorgu dizesi olarak eklemektir. Tarayıcı daha sonra bu kaynağı sonsuza kadar önbelleğe alır ve sorgu dizesi değişmediği sürece herhangi bir GET yapmaz.

Bir dezavantajı, bir önbelleği zorla geçersiz kılmak istiyorsanız, yeni URL'nin web sunucusuna bir öğe için talimat vermenin zor veya imkansız olmasıdır. Örneğin, bir tarayıcının /1.jpg?v=1referansı olan önbelleğe alınmış bir HTML sayfası varsa , ancak girişini temizlediyse /1.jpg?v=1(belki dosya veya bellek alanından yoksun), yeni bir istekte bulunacaktır /1.jpg?v=1. Bu arada görüntü olarak değiştiyse /1.jpg?v=2, uygun yanıt:

  1. Dosyanın eski sürümünü sunun. Tüm kaynakların belirli bir zamanda olduğu gibi birbirleriyle tutarlı olmasını istiyorsanız bunu yaparsınız. Örneğin, eski bir html dosyasına sahip yeni bir css dosyası düzgün çalışmayabileceğinden, CSS dosyaları ile yapmanız gereken budur!
  2. Düğmesini kullanarak dosyanın yeni sürümüne yönlendirin 301 Moved Permanently. Tüm kaynakların mümkün olduğunca yeni olmasını istiyorsanız bunu yapardınız.

Bunların her ikisini de tek başına bir web sunucusu ile yapmak zordur, bu da hem daha karmaşık hem de daha kaynak yoğun olabilen görüntü istekleri için bile bir web uygulaması başlatmanız gerektiği anlamına gelir. Web sunucuları dosya sunma konusunda çok hızlıdır , bu nedenle bir web uygulamasının ek yükü bant genişliği ve gecikme kazanımlarınızı yutabilir.

Dosya adları

Bir sorgu dizesi eklemek yerine dosya adını değiştirirsiniz. Bu, dosya sisteminde birden çok dosya sürümünü tutmanın kolay olduğu anlamına gelir, ancak kaynaklarınızı ve adlarını takip etmek için muhtemelen dosya meta verilerini depolamanız ve başka bir veritabanı defteri tutmanız gerekir.


0

http durumu hakkında bilgi edinin 304 Not Modified, 304 ile bir indirme isteğine yanıt verebilmeniz ve sunucuya önbelleğe alınmış verileri kullanmasını, tarayıcıya yeniden göndermeyi önerebilmeniz gerekir. ve bu soruyu okuyun /programming/2978496/make-php-page-return-304-not-modified-if-it-hasnt-been-modified


İlginç, ama bu sorunlu bir dosya şeması için "bant yardımı" bir çözüm mü, yoksa benim dosya şemam iyi mi ve sadece bu önbellekleme yeteneği gerekir? Ayrıca, kullanıcının tarayıcısına ne zaman yeniden getirmesini söylemem gerektiğini belirlemek için dosyanın en son ne zaman değiştirildiğini (tarayıcı ilk kez görüntülendiğinde) nasıl anlayabilirim?
ProgrammerGirl

Im aşina değilim, Francis Avila hakkında daha çok şey biliyor düşünüyorum
Puggan Se
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.