Có đáng để thay đổi toàn bộ cấu trúc tệp hình ảnh người dùng của tôi để tận dụng bộ nhớ đệm trình duyệt đơn giản không?


9

Trên một trong những trang web di động của tôi, tôi chỉ cần lưu trữ hình ảnh hồ sơ người dùng của mình là '1.jpg' trong thư mục người dùng của họ và dần dần đi từ đó cho bất kỳ bức ảnh bổ sung nào họ tải lên. Điều này có nghĩa là bất cứ khi nào họ thay đổi ảnh hồ sơ của họ, ví dụ, tên tệp vẫn giữ nguyên.

Tôi đã muốn tận dụng bộ nhớ đệm hình ảnh để cùng một hình ảnh cũ không bị tải xuống nhiều lần mỗi khi hồ sơ người dùng được xem và xem lại, nhưng đồng thời, tôi muốn trình duyệt của người dùng của mình tải về cái mới nếu nó đã thay đổi

Từ những gì tôi đã đọc, có vẻ như cách duy nhất để thực sự làm điều này là thực sự sử dụng tên tệp ngẫu nhiên và theo dõi tất cả các tên tệp đó trong DB, để bạn có thể đặt bộ đệm không hết hạn, trong khi gần đây Các bức ảnh được trao đổi được kéo lại vì chúng có tên tệp mới. Tuy nhiên, cái hay của cách tôi cấu trúc chúng cho đến bây giờ là tôi có thể bỏ qua cơ sở dữ liệu hoàn toàn và truy cập trực tiếp vào các tệp vì vị trí của chúng có thể dự đoán được.

Vì vậy, câu hỏi của tôi là, nó có đáng để tôi thay đổi toàn bộ cấu trúc tệp của trang web của mình không, cộng thêm yếu tố DB, vì lợi ích của bộ nhớ đệm vĩnh cửu và tự động tải xuống lại khi tải lên mới?

Đây là một công việc to lớn, nhưng nếu nó được coi là xứng đáng, tôi không có vấn đề gì để tiến lên với sự thay đổi mạnh mẽ này. Tôi chỉ muốn chắc chắn rằng đây là cách các "ông lớn" làm điều đó để tôi không bao giờ phải thay đổi cấu trúc tập tin nữa.

Cảm ơn.

Câu trả lời:


7

Một giải pháp thường được sử dụng là làm cho các URL hình ảnh của bạn trông giống như thế này:

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

Ở đây, /path/to/images/1.jpglà đường dẫn URL thực của hình ảnh, trong khi ?v=123456chỉ là một truy vấn giả nhìn chằm chằm vào cuối URL. Chuỗi truy vấn có thể là bất cứ thứ gì - số phiên bản, dấu thời gian, hàm băm của nội dung hình ảnh - miễn là bạn thay đổi nó bất cứ khi nào hình ảnh thay đổi và giữ nguyên như vậy khi không.

Thủ thuật là máy chủ web, khi được yêu cầu cung cấp một URL như vậy, sẽ bỏ qua chuỗi truy vấn, vì thực tế URL chỉ đến một tệp tĩnh. Nhưng đối với trình duyệt của người dùng (và với bất kỳ proxy nào ở giữa), các URL có các chuỗi truy vấn khác nhau sẽ hoàn toàn khác nhau và do đó, bất kỳ thay đổi nào đối với chuỗi truy vấn buộc trình duyệt phải tải lại tệp.

Do đó, bạn có thể định cấu hình máy chủ web của mình để gửi ExpiresCache-Controlcác tiêu đề HTTP để cho phép bộ nhớ đệm không xác định, an toàn với kiến ​​thức mà bạn có thể buộc tải lại bằng cách thay đổi chuỗi truy vấn. Một cách để làm điều đó, nếu bạn đang sử dụng Apache với mod_Exires , là đặt một .htaccesstệp trong thư mục hình ảnh của bạn với các dòng:

ExpiresActive On
ExpiresDefault "access plus 1 year"

Kỹ thuật này được sử dụng bởi nhiều trang web phổ biến. Ví dụ: nếu bạn xem nguồn HTML của chính trang này, bạn sẽ thấy rằng biểu định kiểu cho nó được tải từ một URL như thế này:

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

Ở đây, ?v=7cd8ea9d6f1emột chuỗi truy vấn giả giống như tôi đã mô tả ở trên; bạn có thể xác nhận rằng bằng cách thay đổi nó và thấy rằng nó thực sự vẫn trả về cùng một tệp.


Cũng thú vị, nhưng làm cách nào để theo dõi khi tệp được sửa đổi lần cuối so với khi trình duyệt được xem lần đầu tiên, để xác định khi nào tôi nên báo cho trình duyệt của người dùng tìm nạp lại (ví dụ: bằng cách thay đổi giá trị truy vấn)?
Lập trình viên

1
Bạn không cần theo dõi khi tập tin được xem. Chỉ cần theo dõi khi tập tin được thay đổi lần cuối (hoặc một số thuộc tính phù hợp khác của nó) và đưa nó vào chuỗi truy vấn. Bằng cách đó, bất cứ khi nào tệp thay đổi, URL cũng sẽ thay đổi.
Ilmari Karonen

Rất, rất, thú vị. Vì vậy, tôi có thể lấy thuộc tính "sửa đổi lần cuối" của các tệp và chỉ cần làm cho giá trị truy vấn đó chính xác?
Lập trình viên

1
Vâng, điều đó nên làm việc.
Ilmari Karonen

1
Không có bất kỳ nhược điểm đáng kể nào mà tôi biết. Bạn có thể kết thúc với các bản sao hình ảnh trùng lặp trong các chỉ mục của công cụ tìm kiếm, nhưng ít nhất các công cụ tìm kiếm lớn như Google khá thông minh trong việc xử lý những điều đó, vì đó là một thủ thuật phổ biến. Trong mọi trường hợp, vấn đề đó có thể được giảm thiểu bằng cách gửi các tiêu đề HTTP rel = "canonical" và bằng cách giữ cho thời gian hết hạn của bạn khiêm tốn (giả sử, chỉ một tháng hoặc một tuần thay vì cả năm).
Ilmari Karonen

6

Có nhiều hơn một cách để lưu trữ.

NHẬN có điều kiện

Nếu bạn đang lưu trữ những hình ảnh này trên hệ thống tệp và phục vụ chúng trực tiếp thông qua máy chủ web, có lẽ bạn đã sử dụng get có điều kiện . Máy chủ web sẽ tự động sử dụng siêu dữ liệu của hệ thống tệp để đặt tiêu đề ETAG và sẽ tự động trả lời với "304 Không được sửa đổi" nếu trình duyệt bao gồm If-Modified-Sincehoặc If-Matchescác tiêu đề trong yêu cầu của nó. (Tất cả các trình duyệt sẽ.)

Trong trường hợp này, toàn bộ hình ảnh không được phục vụ, vì vậy bạn có thể tiết kiệm băng thông. Tuy nhiên, yêu cầu GET vẫn sẽ được phát hành, vì vậy bạn vẫn sẽ có chi phí và độ trễ của yêu cầu.

Bạn có thể giảm số lượng yêu cầu một chút với chi phí làm mới bộ đệm bằng cách đặt máy chủ web của bạn đặt Cache-Controltiêu đề public,max-age=Ncho giá trị cho hình ảnh của bạn. Điều này nói rằng cache có thể giữ tài nguyên trong ít nhất max-agevài giây trước khi chúng phải kiểm tra xem nó có được cập nhật hay không.

Tuy nhiên, HTTP chỉ xác định một cách để vô hiệu hóa mục nhập bộ đệm, có thể không phù hợp với ngữ nghĩa của ứng dụng của bạn: nếu bạn POST hoặc PUT vào một url cập nhật ảnh hồ sơ, trả lời bằng Location: [url of photo]tiêu đề và mục nhập bộ đệm cho url đó sẽ bị vô hiệu.

(Đây là cơ chế cho phép bạn cache một trang web với ý kiến, và sau đó có trang buộc nạp lại bởi trình duyệt sau khi bài viết sử dụng một bình luận mới. Trình duyệt sẽ trả lời một POST /commentvới 303 See OtherLocation: /page/with/comment. Lưu ý rằng điều này đã không được sử dụng để hoạt động trong Firefox do lỗi lâu đời .)

Trừ khi bạn có nhiều lưu lượng, cách tiếp cận bộ nhớ đệm này là tốt.

Thay đổi url

Một url là một đại diện của một tài nguyên, vì vậy một cách khác để quản lý bộ đệm không phải là thay đổi các tham số bộ đệm cho tài nguyên, mà là tạo một tài nguyên hoàn toàn mới bằng một lệnh "cache mãi mãi". Đây là cách tiếp cận mà các "ông lớn" ưa thích, bởi vì nó cho phép họ không tạo thêm yêu cầu, tiết kiệm cho họ rất nhiều băng thông. Nhược điểm là nó đòi hỏi nhiều sổ sách kế toán hơn.

Có hai kỹ thuật chung cho việc này.

Chuỗi truy vấn

Máy chủ web bỏ qua các chuỗi truy vấn khi phục vụ một tệp từ hệ thống tệp. Tuy nhiên, bộ nhớ cache thì không: /1.jpg?t=12345/1.jpg?t=67890là hai tài nguyên hoàn toàn khác nhau, không liên quan đến nhau, mặc dù máy chủ cho rằng chúng giống nhau.

Vì vậy, một điều dễ dàng bạn có thể làm là nối dấu thời gian của hệ thống tệp dưới dạng chuỗi truy vấn bất cứ khi nào bạn tạo tham chiếu đến tài nguyên trong html của mình và đặt Expirestiêu đề dài . Trình duyệt sau đó sẽ lưu trữ tài nguyên này mãi mãi và không thực hiện bất kỳ GET nào miễn là chuỗi truy vấn không thay đổi.

Một nhược điểm là khó hoặc không thể hướng dẫn máy chủ web về url mới cho một mục nếu bạn muốn vô hiệu hóa bộ đệm. Ví dụ: nếu một trình duyệt có trang HTML được lưu trong bộ nhớ cache có /1.jpg?v=1tham chiếu, nhưng tình cờ xóa mục nhập cho /1.jpg?v=1(có thể nó đã hết dung lượng bộ nhớ hoặc bộ nhớ), nó sẽ đưa ra yêu cầu mới /1.jpg?v=1. Nếu trong lúc đó, hình ảnh đã thay đổi thành /1.jpg?v=2, phản hồi thích hợp là:

  1. Phục vụ phiên bản cũ của tập tin. Bạn sẽ làm điều này nếu bạn muốn tất cả các tài nguyên phù hợp với nhau vì chúng ở một thời điểm nhất định. Đây là những gì bạn nên làm với các tệp CSS, ví dụ, vì một tệp css mới với tệp html cũ có thể không hoạt động đúng!
  2. Chuyển hướng đến phiên bản mới của tệp bằng cách sử dụng 301 Moved Permanently. Bạn sẽ làm điều này nếu bạn muốn tất cả các tài nguyên càng mới càng tốt.

Cả hai điều này đều khó thực hiện với một máy chủ web, điều đó có nghĩa là bạn cần phải gọi một ứng dụng web ngay cả đối với các yêu cầu hình ảnh, có thể phức tạp hơn và tốn nhiều tài nguyên hơn. Máy chủ web rất nhanh trong việc phục vụ các tệp, do đó, chi phí chung của ứng dụng web có thể sẽ nuốt chửng băng thông và độ trễ của bạn.

Tên tệp

Thay vì thêm một chuỗi truy vấn, bạn thay đổi tên tệp. Điều này có nghĩa là dễ dàng giữ nhiều phiên bản tệp trên hệ thống tệp, nhưng có lẽ bạn sẽ cần lưu trữ siêu dữ liệu tệp và thực hiện lưu giữ sổ sách cơ sở dữ liệu khác để theo dõi tài nguyên và tên của chúng.


0

đọc về trạng thái http 304 Not Modified, bạn sẽ có thể phản hồi yêu cầu tải xuống bằng 304 và thông báo cho máy chủ sử dụng dữ liệu được lưu trong bộ nhớ cache, nhờ gửi lại nó cho trình duyệt. và đọc câu hỏi này /programming/2978496/make-php-page-return-304-not-modified-if-it-hasnt-been-modified


Thật thú vị, nhưng đây có phải là một giải pháp "hỗ trợ băng tần" cho một lược đồ tệp có vấn đề hay là lược đồ tệp của tôi tốt và chỉ cần khả năng lưu trữ này? Ngoài ra, làm thế nào để tôi biết khi nào tệp được sửa đổi lần cuối so với khi trình duyệt được xem lần đầu tiên, để xác định khi nào tôi nên báo cho trình duyệt của người dùng tìm nạp lại?
Lập trình viên

Tôi không quá quen thuộc với nó, hãy nghĩ rằng Francis Avila biết nhiều hơn về nó
Puggan Se
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.