Computer >> Máy Tính >  >> Lập trình >> Ruby

Bộ nhớ đệm phía máy khách trong Rails:yêu cầu GET có điều kiện

Bên cạnh bộ đệm búp bê Nga, có nhiều kỹ thuật khác để tăng tốc hiệu suất trong ứng dụng Rails. Lần này chúng ta sẽ xem xét hỗ trợ GET có điều kiện được tích hợp sẵn của Rails, cho phép bạn lưu trữ các trang được hiển thị trong bộ nhớ cache của trình duyệt của người dùng.

👋 Và nếu bạn muốn đọc thêm về hiệu suất bên ngoài bộ nhớ đệm, chúng tôi đã viết nhiều hơn về hiệu suất của Ruby (trên Rails), hãy xem danh sách kiểm tra giám sát hiệu suất Ruby của chúng tôi.

Tiêu đề Etag và Tiêu đề được sửa đổi lần cuối

Khi trình duyệt của bạn thực hiện một yêu cầu HTTP GET cho một trang trong ứng dụng Rails của bạn, bộ định tuyến sẽ liên kết nó với một trong các hành động của bộ điều khiển của bạn. Bộ điều khiển sau đó sẽ yêu cầu dữ liệu cần thiết từ cơ sở dữ liệu và hiển thị chế độ xem. Phản hồi HTTP (với 200 OK như mã phản hồi) sau đó được gửi trở lại trình duyệt với HTML được hiển thị từ chế độ xem trong nội dung phản hồi để trình duyệt của bạn phân tích cú pháp và hiển thị.

Khi tài nguyên được yêu cầu một lần nữa, chúng tôi sẽ thực hiện theo cùng một đường dẫn. Trong một số trường hợp, điều này là không cần thiết vì trang không thay đổi trong thời gian chờ đợi. Vì vậy, HTTP cung cấp ETag Sửa đổi lần cuối tiêu đề. Sử dụng những thứ này, trình duyệt có thể lưu trữ nội dung phản hồi và sử dụng các tiêu đề để làm mất hiệu lực của chúng khi chúng trở nên cũ.

Etags hoặc Thẻ thực thể , được sử dụng để xác thực bộ đệm phía máy khách, vì vậy bạn có thể coi chúng như các khóa bộ đệm cho các phản hồi HTTP của mình. Chúng được chuyển trở lại trình duyệt trong tiêu đề phản hồi HTTP cho mọi yêu cầu.

~ $ curl -I https://localhost:3000/products/1
HTTP/1.1 200 OK
...
ETag: W/"9462d76cc55aeb6249fa990e39231c7c"
Last-Modified: Wed, 25 Apr 2018 08:27:04 GMT
...

Nếu phản hồi được lặp lại sau đó, trình duyệt sẽ tìm thấy phản hồi hiện có trong bộ nhớ cache của nó và sử dụng Etag được lưu trữ từ yêu cầu cuối cùng dưới dạng If-None-Match đầu trang. Tiêu đề này sẽ cho ứng dụng Rails của chúng tôi biết rằng chúng tôi đã có phiên bản này trong bộ nhớ cache.

Nếu Etag từ yêu cầu khớp với Etag hiện tại, Rails sẽ gửi 304 Not Modified phản hồi mà không có cơ quan phản hồi. Điều này sẽ yêu cầu trình duyệt sử dụng một cái từ bộ nhớ cache cục bộ của nó thay thế.

~ $ curl -i -H 'If-None-Match: W/"9462d76cc55aeb6249fa990e39231c7c"' https://localhost:3000/products/1
HTTP/1.1 304 Not Modified
...
ETag: W/"9462d76cc55aeb6249fa990e39231c7c"
Last-Modified: Wed, 25 Apr 2018 08:27:04 GMT
...

Yêu cầu GET có điều kiện trong Rails

Nếu chúng tôi yêu cầu một trang từ ứng dụng Rails cục bộ, chúng tôi có thể thấy rằng Rails tự động thêm Etag cho mỗi yêu cầu. Nếu chúng tôi yêu cầu cùng một trang vài lần liên tiếp, chúng tôi có thể thấy các thay đổi về Etag cho mỗi yêu cầu.

Trong khi Rails tạo Etag cho mỗi yêu cầu theo mặc định, nó sử dụng một bản tóm tắt của toàn bộ nội dung phản hồi để tạo ra nó. Điều này có nghĩa là <%= csrf_meta_tags %> trong bố cục ném Etag ra, vì thẻ meta csrf-token thay đổi cho mỗi yêu cầu. Vì điều đó thay đổi nội dung cho mỗi yêu cầu, Etag bị vô hiệu và bộ nhớ cache cục bộ được đánh dấu là cũ.

Bên cạnh đó, Rails sẽ không bao giờ trả về 304 Not Modified theo mặc định, vì bộ đệm cục bộ không bao giờ được đánh dấu rõ ràng là mới trong bộ điều khiển của chúng tôi.

fresh_whenstale?

Để sử dụng Etags từ tiêu đề yêu cầu cho các GET có điều kiện, chúng ta cần đánh dấu rõ ràng một đối tượng trong bộ đệm ẩn cục bộ là "mới". Ví dụ:đối với một trang hiển thị sản phẩm, chúng tôi có thể giữ mới bộ nhớ cache miễn là sản phẩm và các mẫu chế độ xem không thay đổi. Để điều đó hoạt động hiệu quả, chúng tôi sẽ làm hai việc.

  1. Chúng tôi sẽ đặt rõ ràng các giá trị sẽ tạo nên Etag của chúng tôi, vì việc sử dụng toàn bộ phần nội dung phản hồi sẽ yêu cầu chúng tôi kết xuất toàn bộ phần nội dung để kiểm tra xem phản hồi được lưu trong bộ nhớ cache có hợp lệ hay không, điều này sẽ phủ nhận việc tăng tốc từ bộ nhớ đệm trang cục bộ.
  2. Chúng tôi sẽ so sánh Etag từ tiêu đề yêu cầu với Etag mà chúng tôi dự đoán trước đây hiển thị chế độ xem và chúng tôi sẽ bỏ hiển thị nếu chúng khớp.

Rails đi kèm với những người trợ giúp làm mọi thứ cho chúng ta. Chúng tôi có thể căn cứ rõ ràng Ngày Etag và Ngày sửa đổi lần cuối trên sản phẩm bằng cách sử dụng fresh_when .

# app/views/products/show.html.erb
def show
  @product = Product.find(params[:id])
  fresh_when @product
end

Nếu bạn có respond_to rõ ràng chặn, sử dụng stale? thay vì fresh_when .

# app/views/products/show.html.erb
def show
  @product = Product.find(params[:id])
 
  if stale?(@product)
    respond_to do |format|
      format.html
    end
  end
end

Bây giờ, yêu cầu một trong các trang sản phẩm sẽ lưu phản hồi vào bộ nhớ cache cục bộ. Bất kỳ yêu cầu nào tiếp theo đến cùng một trang sẽ bao gồm Etag để cho Rails biết chúng tôi có phản hồi được lưu trong bộ nhớ cache, sau đó được so sánh với Etag mới. Nếu điều đó phù hợp, Rails sẽ bỏ qua việc hiển thị trang và trả về 304 Not Modified ngay lập tức.

Lưu ý :Làm mới trang sẽ luôn yêu cầu phiên bản chưa được lưu vào bộ nhớ cache của trang. Để kiểm tra xem các GET có điều kiện của bạn có hoạt động hay không, hãy điều hướng bằng cách sử dụng liên kết hoặc sử dụng nút quay lại.

Bạn thích bài viết này và các bài viết trước trong loạt bài AppSignal Academy như thế nào? Chúng tôi có một số bài viết khác về bộ nhớ đệm trong Rails sắp xếp, nhưng vui lòng cho chúng tôi biết bạn muốn chúng tôi viết về điều gì (liên quan đến bộ nhớ đệm hoặc cách khác) tiếp theo!