Bên cạnh bộ nhớ đệm búp bê của Nga, còn 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 tính năng hỗ trợ GET có điều kiện 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ộ đệm 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 ngoài bộ nhớ đệm, chúng tôi đã viết nhiều hơn nữa về hiệu suất của Ruby (on 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à sửa đổi lần cuối
Khi trình duyệt của bạn thực thi yêu cầu HTTP GET cho một trang trong ứng dụng Rails, bộ định tuyến sẽ liên kết trang đó với một trong các hành động đ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 làm mã phản hồi) sau đó được gửi trở lại trình duyệt cùng 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 lại, chúng tôi sẽ thực hiện theo quy trình tương tự. 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. Để làm được điều đó, HTTP cung cấp ETag của nó và Sửa đổi lần cuối tiêu đề. Bằng cách 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 đề để vô hiệu hóa chúng khi chúng trở nên cũ.
Thẻ , 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 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 http://localhost:3000/products/1HTTP/1.1 200 OK...ETag:W/"9462d76cc55aeb6249fa990e39231c7c"Sửa đổi lần cuối:Thứ Tư, ngày 25 tháng 4 năm 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ộ đệm 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 tiêu đề. Tiêu đề này sẽ cho ứng dụng Rails biết rằng chúng tôi đã có phiên bản này trong bộ đệm.
Nếu Etag từ yêu cầu khớp với yêu cầu 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 bộ đệm từ bộ đệm cục bộ của nó.
~ $curl -i -H 'If-None-Match:W/"9462d76cc55aeb6249fa990e39231c7c"' http://localhost:3000/products/1HTTP/1.1 304 Không được sửa đổi...ETag:W/"9462d76cc55aeb6249fa990e39231c7c"Sửa đổi lần cuối:Thứ Tư, ngày 25 tháng 4 năm 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 của Etag cho mỗi yêu cầu.
Mặc dù Rails tạo Etag cho mỗi yêu cầu theo mặc định, nhưng nó sử dụng bản tóm tắt của toàn bộ nội dung phản hồi để tạo ra yêu cầu đó. Điều này có nghĩa là <%= csrf_meta_tags %> trong bố cục sẽ tắt Etag vì thẻ meta csrf-token thay đổi cho mỗi yêu cầu. Bởi vì điều đó làm thay đổi nội dung cho mỗi yêu cầu, Etag bị vô hiệu và bộ nhớ đệm cục bộ bị đánh dấu là cũ.
Ngoài ra, 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_when và stale?
Để sử dụng Etags từ tiêu đề yêu cầu cho 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 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ữ cho bộ đệm luôn mới miễn là sản phẩm và mẫu xem không thay đổi. Để thực hiện được điều đó, chúng tôi sẽ làm hai việc.
- 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ộ nội dung phản hồi sẽ yêu cầu chúng tôi hiển thị toàn bộ nội dung để kiểm tra xem phản hồi được lưu trong bộ nhớ đệm có hợp lệ hay không, điều này làm mất đi khả năng tăng tốc từ việc lưu trang vào bộ nhớ đệm cục bộ.
- Chúng tôi sẽ so sánh Etag từ tiêu đề yêu cầu với tiêu đề mà chúng tôi dự đoán trước hiển thị chế độ xem và chúng tôi sẽ bỏ qua hiển thị nếu chúng khớp.
Rails có những người trợ giúp làm mọi việc cho chúng ta. Chúng tôi có thể căn cứ rõ ràng vào 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 .
Nếu bạn có respond_to rõ ràng chặn, sử dụng stale? thay vì fresh_when .
Bây giờ, việc yêu cầu một trong các trang sản phẩm sẽ lưu trữ phản hồi cục bộ. Mọi yêu cầu tiếp theo tới cùng một trang sẽ bao gồm Etag để báo cho Rails biết rằng chúng tôi có phản hồi được lưu trong bộ nhớ đệm, sau đó được so sánh với Etag mới. Nếu khớ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 không được lưu trong bộ nhớ cache của trang. Để kiểm tra xem GET có điều kiện của bạn có hoạt động hay không, hãy điều hướng khỏi trang bằng cách sử dụng liên kết hoặc sử dụng nút quay lại.
Bạn thấy bài viết này và các bài viết trước trong loạt bài của Học viện AppSignal như thế nào? Chúng tôi có thêm một số bài viết về bộ nhớ đệm trong Rails, nhưng vui lòng cho chúng tôi biết bạn muốn chúng tôi viết về chủ đề gì tiếp theo (liên quan đến bộ nhớ đệm hoặc cách khác)!