Xử lý bộ đệm của trình duyệt trong các ứng dụng một trang


27

Tôi đang cố gắng tìm ra cách xử lý đúng bộ đệm của trình duyệt web cho các ứng dụng trang đơn.

Tôi có một thiết kế khá điển hình: một số tệp HTML, JS và CSS triển khai SPA và một loạt dữ liệu JSON được sử dụng bởi SPA. Các vấn đề phát sinh khi tôi muốn đẩy một bản cập nhật: Tôi cập nhật phần tĩnh của trang web và mã tạo JSON cùng một lúc, nhưng các trình duyệt máy khách thường có phần tĩnh được lưu trong bộ nhớ cache, vì vậy mã cũ cố xử lý dữ liệu mới và có thể (tùy thuộc vào những thay đổi được thực hiện) gặp vấn đề. (Đặc biệt, IE có vẻ mạnh mẽ hơn Chrome hoặc Firefox về việc sử dụng bộ nhớ cache mà không cần xác nhận lại.)

Cách tốt nhất để xử lý việc này là gì?

  1. Đảm bảo các thay đổi JSON của tôi tương thích ngược và giả sử bộ đệm của trình duyệt sẽ hết hạn trong khung thời gian hợp lý.
  2. Nhúng một số loại số phiên bản trong cả JS tĩnh và JSON, sau đó thực thi window.location.reload(true);nếu chúng không khớp.
  3. Chỉ ra sự kết hợp thích hợp của các tiêu đề ( must-revalidatehoặc no-cachebất cứ điều gì; các nguồn khác nhau về cách thực hiện việc này) để đảm bảo rằng các trình duyệt luôn xác nhận lại tất cả tài nguyên trên mỗi tải, ngay cả khi điều đó có nghĩa là thêm một vài chuyến đi vòng để tải trang.
  4. Micro-quản lý kiểm soát bộ đệm của tôi và hết hạn các tiêu đề để nội dung tĩnh hết hạn khi tôi muốn đẩy một bản cập nhật.
  5. Thứ gì khác?

1
Đã nghe thấy # 3 và # 4 bất ngờ thất bại trong các điều khiển trình duyệt web nhúng nếu môi trường của bạn là xấu ( ho iOS) từ đồng nghiệp. # 1 và # 2 có thể là lựa chọn cấp ứng dụng nhưng vẫn có thể (?) Gây ra sự cố bộ đệm cho các tài nguyên khác hoặc cho tải tài nguyên một phần. Điều duy nhất tôi thấy đáng tin cậy làm việc trong mã sẵn sàng sản xuất là tìm nạp yoururl.html? <SomeTimeStamp> vì điều này sẽ giả mạo hầu hết các cơ chế lưu trữ. Phần thưởng: cuộn toàn bộ ứng dụng web của bạn vào một tệp để tải thành công nguyên tử hoặc thất bại. Nhược điểm: hoạt động tốt nhất trên một liên kết địa phương. Số dặm của bạn có thể thay đổi. Chúc may mắn!
J Trana

2
+1 để sử dụng số phiên bản hoặc dấu thời gian làm tham số URL cho tài nguyên.
9000

Câu trả lời:


14

Bạn cần một giải pháp phá bộ đệm . Vai trò của bộ đệm cache là:

  1. Đổi tên tài nguyên thành một tên duy nhất tùy thuộc vào nội dung của chúng.
  2. Cập nhật tất cả các tham chiếu đến các tài nguyên đó.

Trong một dự án dựa trên Grunt, người ta thường sử dụng grunt-rev để đảm bảo rằng tất cả các tệp cần được làm mới đều được đặt tên duy nhất, dựa trên nội dung của chúng.

Nếu bạn đảm bảo rằng các tệp JSON của bạn có được tên tệp bộ nhớ cache cùng với các tham chiếu đến chúng trong Javascript của bạn, các máy khách sẽ luôn tải các tệp JSON mà Javascript mong đợi.

Ưu điểm của việc đặt tên tệp dựa trên hàm băm là các tệp không thay đổi sẽ có cùng tên tệp sau khi xóa bộ đệm, do đó trình duyệt có thể tiếp tục sử dụng nội dung được lưu trong bộ nhớ cache một cách an toàn khi không thay đổi.

Rõ ràng đây là loại điều bạn muốn được tự động hóa như là một phần của quá trình sản xuất dự án của bạn để bạn không phải theo dõi thay đổi tên tệp & tài liệu tham khảo theo cách thủ công.


2
+1 cho bit "bộ nhớ cache" được in nghiêng, mở ra cơ hội thực sự google công cụ này một cách hiệu quả.
Zak Kus

@Ted Percival - khung yeoman thực hiện điều này, mà tôi sử dụng, nhưng tôi đang thấy một vấn đề. Khi tôi phát hành bản dựng mới, trình duyệt có thể được lưu trữ index.html với các tham chiếu đến các tệp cũ ... và trình duyệt bị lỗi. Làm thế nào tôi nên sửa cái này? (A. và tìm kiếm cơ sở một (ví dụ: 12345.main.js -> main.js)
timh

5

Bạn có thể sử dụng if-modified-since + last-modifiedhoặc if-none-match + etagtiêu đề cùng với cache-controltiêu đề thích hợp . (Có thể có lỗi trình duyệt , nhưng không có gì bạn không thể quản lý trong các trình duyệt gần đây.)

Nếu các tệp là tĩnh, thì tôi khuyên bạn nên sử dụng if-modified-since, vì nó có thể được thực hiện tự động với máy chủ HTTP được cấu hình tốt. Nó sẽ gửi lại 304 nếu tệp không được sửa đổi kể từ lần tải xuống cuối cùng.

Tôi không nghĩ rằng số 1 và số 2 của bạn sẽ hoạt động lâu dài. Số 3 hoặc số 4 có thể hoạt động. Số 3 đơn giản hơn, nhưng bạn phải học cách giải quyết vấn đề này chỉ một lần. Vì vậy, tôi sẽ thử số 4 nếu tôi là bạn, nhưng giải pháp có thể phụ thuộc vào trình duyệt mà khách hàng của bạn sử dụng ... Ví dụ IE8 có vấn đề bằng cách cập nhật bộ đệm ajax, v.v ...


2

Nếu bạn có thể bao gồm Bộ lọc Java Servlet trong SPA của mình, thì đây là một giải pháp hiệu quả: CorrectBrowserCacheHandlerFilter.java

Về cơ bản, khi trình duyệt của bạn yêu cầu các tệp tĩnh, máy chủ sẽ chuyển hướng mọi yêu cầu đến cùng một yêu cầu nhưng với tham số truy vấn băm ( ?v=azErTví dụ) phụ thuộc vào nội dung của tệp tĩnh đích.

Làm điều này, trình duyệt sẽ không bao giờ lưu trữ các tệp tĩnh được khai báo trong index.htmlví dụ của bạn (vì sẽ luôn nhận được a 302 Moved Temporarily), nhưng sẽ chỉ lưu trữ các tệp có phiên bản băm (máy chủ sẽ trả lời 200cho chúng). Vì vậy, bộ đệm của trình duyệt sẽ được sử dụng hiệu quả cho các tệp tĩnh có phiên bản băm.

Tuyên bố miễn trừ trách nhiệm: Tôi là tác giả của CorrectBrowserCacheHandlerFilter.java.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.