Tek sayfalı uygulamalarda tarayıcı önbelleği ile ilgilenmek


27

Tek sayfa uygulamalar için web tarayıcı önbelleğini doğru bir şekilde nasıl kullanabileceğimi bulmaya çalışıyorum.

Oldukça tipik bir tasarıma sahibim: SPA'yı uygulayan birkaç HTML, JS ve CSS dosyası ve SPA tarafından tüketilen bir miktar JSON verisi. Bir güncellemeyi zorlamak istediğimde sorunlar ortaya çıkıyor: Sitenin statik kısmını ve JSON'u oluşturan kodu aynı anda güncelliyorum, ancak istemci tarayıcılar genellikle statik kısmı önbelleğe aldı, bu nedenle eski kod yeni verileri işlemeye çalışıyor. (yapılan değişikliklere bağlı olarak) problemlerle karşılaşabilir. (Özellikle, IE, yeniden doğrulanmadan önbelleğe alınmış JS'yi kullanma konusunda Chrome veya Firefox'tan daha agresif görünüyor.)

Bununla başa çıkmanın en iyi yolu nedir?

  1. JSON değişikliklerimin geriye dönük olarak uyumlu olduğundan ve tarayıcı önbelleklerinin makul bir süre içinde sona ereceğini varsayalım.
  2. Hem statik JS'ye hem de JSON'a bir tür sürüm numarası yerleştirin, sonra window.location.reload(true);eşleşmiyorsa uygulayın.
  3. Tarayıcıların, siteyi yüklemek için birkaç tur atmak anlamına gelse bile, her yükte tüm kaynakları yeniden değerlendirebilmelerini sağlamak için uygun başlıkların ( must-revalidateveya no-cacheveya her neyse; kaynaklar bunun nasıl yapılacağına bağlı olarak değişir) kombinasyonunu belirleyin.
  4. Bir önbellek kontrolümü mikro yönetiyor ve bir güncelleme zorlamak istediğimde statik içeriğin süresinin dolmasını sağlamak için başlıkları sona erdiriyor.
  5. Başka bir şey?

1
Ortamınız iş arkadaşlarınızdan kötüyse ( iOS öksürüğü ) gömülü web tarayıcısı denetimlerinde # 3 ve # 4 beklenmedik bir şekilde başarısız olduğunu duydum . # 1 ve # 2 bir uygulama düzeyinde seçim olabilir, ancak yine de (?) Diğer kaynaklar veya kısmi kaynak yükleri için önbellek sorunlarına neden olabilir. Üretime hazır kodda güvenilir bir şekilde çalıştığım tek şey, çoğu önbelleğe alma mekanizmasını taklit edeceğinden yoururl.html? <SomeTimeStamp> 'ı almaktır. Bonus: tüm web uygulamanızı bir dosyaya yerleştirin, böylece yükler atomik olarak başarılı veya başarısız olur. Dezavantajı: yerel bağlantıda en iyi sonucu verir. Kilometreniz değişebilir. İyi şanslar!
J Trana

2
Kaynaklar için bir URL parametresi olarak sürüm numarası veya zaman damgası kullanmak
9000

Yanıtlar:


14

Önbellek bozucu bir çözüme ihtiyacınız var . Önbellek bozmanın rolü:

  1. Kaynakları, içeriklerine bağlı olarak benzersiz bir adla yeniden adlandırın.
  2. Bu kaynaklara yapılan tüm referansları güncelleyin.

Grunt tabanlı bir projede, yenilenmesi gereken tüm dosyalara içeriklerine göre benzersiz adlar verilmesini sağlamak için grunt-rev kullanmak yaygındır .

JSON dosyalarınızın önbellek bozan dosya adlarını Javascript'inizdeki referanslarla birlikte almasını sağlarsanız, istemciler her zaman Javascript'in beklediği JSON dosyalarını yükler.

Karma tabanlı dosya adlandırma işleminin avantajı, değiştirilmemiş dosyaların önbellek bozulduktan sonra aynı dosya adlarını elde etmesidir, böylece tarayıcılar, değişmediğinde önbellek içeriğini güvenle kullanmaya devam edebilir.

Açıkçası bu, projenizin üretim yapısının bir parçası olarak otomatik olmasını istediğiniz bir şeydir, böylece dosya adlarını ve referansları el ile değiştirmek zorunda kalmazsınız.


2
İtalik "önbellek bozma" biti için +1, aslında bu şeyleri verimli bir şekilde google'a çeviren kapıyı açar.
Zak Kus

@Ted Percival - Kullandığım yeoman çerçevesi, bir problem görüyorum. yeni bir derleme yayınladığımda, tarayıcı eski dosyalara referanslarla index.html önbelleğe alınmış olabilir ... ve tarayıcı bir hata alıyor. bunu nasıl düzeltmeliyim? (A.) tüm eski dosya adlarını yenileriyle eşleştir (bu işe yarar) (B.) index.html dosyasına önbellek içermeyen başlık ekler (ancak buna her zaman saygı duyulur) (C.), döndürülen dosyayı tanımak için .htaccess ekler. ve temel olanı arayın (ör. 12345.main.js -> main.js)
saat

5

Doğru başlıkla birlikte başlıkları kullanabilir if-modified-since + last-modifiedveya if-none-match + etagbaşlıkları kullanabilirsiniz cache-control. ( Tarayıcı hataları olabilir , ancak son tarayıcılarda yönetemediğiniz hiçbir şey yoktur.)

Dosyalar statikse, o zaman kullanmanızı öneririm if-modified-since, çünkü iyi yapılandırılmış bir HTTP sunucusuyla otomatik olarak yapılabilir. Son indirmeden bu yana dosya değiştirilmezse 304 geri gönderilmelidir.

1 ve 2'nizin uzun vadede işe yarayacağını sanmıyorum. # 3 veya # 4 çalışabilir. # 3 daha basittir, ancak bu sorunla nasıl başa çıkılacağını bir kez öğrenmek zorundasınız. Öyleyse 4 numarayı denerdim, ama bu çözüm müşterilerinizin kullandığı tarayıcılara bağlı olabilir ... Örneğin IE8'in ajax önbelleğini güncelleyerek sorunları var ...


2

SPA'nıza Java Servlet Filtresi ekleyebilirseniz, işte size çalışan bir çözüm: CorrectBrowserCacheHandlerFilter.java

Temel olarak, tarayıcınız statik dosyaları istediğinde, sunucu her isteği aynı olana yönlendirir, ancak ?v=azErThedef statik dosyanın içeriğine bağlı olan bir karma sorgu parametresiyle ( örneğin).

Bunu yaptığınızda, tarayıcı, index.htmlörneğin (her zaman bir a alacağınız için) belirtilen statik dosyaları hiçbir zaman önbelleğe almaz 302 Moved Temporarily, ancak yalnızca karma sürümüne sahip olanları önbelleğe alır (sunucu 200onlara cevap verir). Böylece tarayıcı önbelleği, karma sürümüne sahip bu statik dosyalar için verimli bir şekilde kullanılacaktır.

Yasal Uyarı: Ben yazarıyım CorrectBrowserCacheHandlerFilter.java.

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.