Yêu bộ nhớ đệm của bạn ❤️

Người dùng tải trang web của bạn lần thứ hai sẽ sử dụng bộ nhớ đệm HTTP của họ, do đó, hãy đảm bảo sẽ hoạt động tốt.

Bài đăng này là tệp bổ trợ cho video Love your cache (Yêu bộ nhớ đệm của bạn), thuộc loạt video Extended Nội dung tại Hội nghị dành cho nhà phát triển Chrome năm 2020. Đừng quên xem video nhé:

Khi người dùng tải trang web của bạn lần thứ hai, trình duyệt của họ sẽ sử dụng các tài nguyên bên trong bộ nhớ đệm HTTP của trình duyệt để giúp tải nhanh hơn. Nhưng tiêu chuẩn để lưu vào bộ nhớ đệm web ra đời từ năm 1999 và chúng được định nghĩa khá rộng rãi — quyết định liệu một tệp, như CSS hoặc hình ảnh, có thể được tìm nạp lại từ mạng so với được tải từ bộ nhớ đệm là khoa học không chính xác.

Trong bài đăng này, tôi sẽ trình bày về một chế độ mặc định hiện đại và hợp lý dùng để lưu vào bộ nhớ đệm – một chế độ mặc định thực sự không lưu vào bộ nhớ đệm. Nhưng đó chỉ là tuỳ chọn mặc định, phức tạp hơn là chỉ "tắt tiếng". Hãy đọc tiếp!

Bàn thắng

Khi một trang web được tải lần thứ 2, bạn có hai mục tiêu:

  1. Đảm bảo rằng người dùng của bạn nhận được phiên bản mới nhất (nếu có) bạn đã thay đổi điều gì đó, thay đổi đó sẽ được phản ánh nhanh chóng
  2. Thực hiện thao tác 1 trong khi tìm nạp ít dữ liệu từ mạng nhất có thể

Theo nghĩa rộng nhất, bạn chỉ muốn gửi thay đổi nhỏ nhất đến khách hàng khi họ tải lại trang web của bạn. Và cấu trúc trang web của bạn để đảm bảo phân phối hiệu quả bất kỳ thay đổi nào là thách thức (tìm hiểu thêm về vấn đề đó ở bên dưới, và trong video).

Mặc dù vậy, bạn cũng có các nút điều chỉnh khác khi cân nhắc việc lưu vào bộ nhớ đệm, có lẽ bạn đã quyết định cho phép bộ nhớ đệm HTTP của trình duyệt lưu giữ trang web của bạn trong một khoảng thời gian sao cho không cần yêu cầu mạng nào để phân phát quảng cáo đó. Hoặc bạn đã đã tạo một trình chạy dịch vụ sẽ phân phát trang web hoàn toàn ngoại tuyến trước để kiểm tra xem mọi thứ đã cập nhật hay chưa. Đây là lựa chọn cực kỳ nghiêm ngặt, hợp lệ và được sử dụng cho nhiều trải nghiệm web giống như ứng dụng ngoại tuyến, nhưng web không nhất thiết phải cực kỳ chỉ sử dụng bộ nhớ đệm hoặc thậm chí là cực kỳ chỉ kết nối mạng.

Thông tin khái quát

Là nhà phát triển web, tất cả chúng ta đều quen với ý tưởng có một "bộ nhớ đệm đã lỗi thời". Nhưng chúng ta biết, gần như theo bản năng, các công cụ có sẵn để giải quyết việc này: thực hiện làm mới" hoặc mở cửa sổ ẩn danh hoặc sử dụng một số tổ hợp công cụ cho nhà phát triển để xoá dữ liệu của trang web.

Những người dùng thường xuyên trên mạng không có được sự sang trọng như vậy. Vì vậy, trong khi chúng tôi có một số mục tiêu cốt lõi là đảm bảo người dùng có trải nghiệm tuyệt vời tải, bạn cũng cần đảm bảo rằng họ sẽ không có thời gian không phù hợp hoặc bị mắc kẹt. (Hãy xem video nếu bạn muốn nghe tôi nói về cách chúng tôi suýt nữa thì trang web web.dev/live bị lỗi!)

Một lý do thực sự phổ biến gây ra "bộ nhớ đệm cũ" thực sự là mặc định từ năm 1999 cho việc lưu vào bộ nhớ đệm. Chiến lược này phụ thuộc vào tiêu đề Last-Modified:

Biểu đồ cho thấy khoảng thời gian các nội dung khác nhau được trình duyệt của người dùng lưu vào bộ nhớ đệm
Tài sản được tạo vào những thời điểm khác nhau (có màu xám) sẽ được lưu vào bộ nhớ đệm nên lần tải thứ 2 có thể kết hợp cả tài sản được lưu vào bộ nhớ đệm và tài sản mới

Mỗi tệp bạn tải được giữ lại thêm 10% thời gian tồn tại hiện tại của tệp, vì trình duyệt của bạn nhìn thấy nội dung đó. Ví dụ: nếu index.html được tạo một tháng trước, ảnh sẽ được trình duyệt của bạn lưu vào bộ nhớ đệm trong khoảng ba ngày nữa.

Đây là một ý tưởng có chủ ý vào thời điểm đó, nhưng nếu tính chất tích hợp của các trang web hiện nay, hành vi mặc định này có thể người dùng có các tệp được thiết kế cho các bản phát hành khác nhau trang web của bạn (ví dụ: JS từ bản phát hành vào thứ Ba và CSS từ bản phát hành vào thứ Sáu phát hành), tất cả đều do các tệp đó không được cập nhật cùng một lúc.

Lối đi đủ sáng

Một mặc định hiện đại cho việc lưu vào bộ nhớ đệm là thực sự không lưu vào bộ nhớ đệm và sử dụng CDN để đóng nội dung của bạn đối với người dùng của bạn. Mỗi khi người dùng tải trang web của bạn, họ sẽ truy cập mạng để đã cập nhật hay chưa. Yêu cầu này sẽ có độ trễ thấp vì nó sẽ do CDN cung cấp theo khu vực địa lý gần với từng người dùng cuối.

Bạn có thể định cấu hình máy chủ lưu trữ web để phản hồi các yêu cầu web bằng tiêu đề này:

Cache-Control: max-age=0,must-revalidate,public

Về cơ bản, điều này nói rằng: tệp hoàn toàn không có hiệu lực và bạn phải xác thực mật khẩu đó khỏi mạng trước khi có thể sử dụng lại (nếu không, nó chỉ "được đề xuất").

Quy trình xác thực này tương đối rẻ về số byte được chuyển—nếu một tệp hình ảnh lớn không thay đổi, trình duyệt của bạn sẽ nhận được mã 304 nhưng sẽ tốn độ trễ vì người dùng vẫn phải vào mạng để tìm bị loại. Và đây là nhược điểm chính của phương pháp này. Ứng dụng này có thể hoạt động rất hiệu quả cho những người sử dụng kết nối nhanh ở thế giới thứ nhất và nơi CDN mà bạn lựa chọn có phạm vi phủ sóng rộng, nhưng không phù hợp với những người có thể sử dụng thiết bị di động chậm hơn kết nối hoặc sử dụng cơ sở hạ tầng kém.

Mặc dù đây là một phương pháp hiện đại, là lựa chọn mặc định trên một CDN phổ biến, Netlify, nhưng có thể được định cấu hình trên hầu hết mọi CDN. Đối với tính năng Lưu trữ Firebase, bạn có thể bao gồm tiêu đề này trong phần lưu trữ của tệp firebase.json của bạn:

"headers": [
  // Be sure to put this last, to not override other headers
  {
    "source": "**",
    "headers": [ {
      "key": "Cache-Control",
      "value": "max-age=0,must-revalidate,public"
    }
  }
]

Vì vậy, mặc dù tôi vẫn đề xuất đây là một chế độ mặc định hợp lý, nhưng chỉ là mặc định! Hãy đọc tiếp để tìm hiểu cách thực hiện và nâng cấp các chế độ mặc định.

URL có vân tay số

Bằng cách thêm hàm băm cho nội dung của tệp vào tên thành phần, hình ảnh, v.v. khi được phân phát trên trang web của mình, bạn có thể đảm bảo rằng những tệp này sẽ luôn có content—ví dụ: điều này sẽ dẫn đến các tệp có tên sitecode.af12de.js. Thời gian máy chủ của bạn phản hồi yêu cầu đối với những tệp này, bạn có thể hướng dẫn trình duyệt của người dùng cuối để lưu chúng vào bộ nhớ đệm trong một thời gian dài bằng cách định cấu hình chúng với tiêu đề:

Cache-Control: max-age=31536000,immutable

Giá trị này là năm, tính bằng giây. Theo thông số kỹ thuật, đây là tính năng bằng "vĩnh viễn".

Quan trọng là bạn không nên tạo các hàm băm này theo cách thủ công vì bạn sẽ phải làm quá nhiều việc theo cách thủ công! Bạn có thể dùng các công cụ như Webpack, Rollup, v.v. để giúp bạn xử lý vấn đề này. Đảm bảo để đọc thêm về chúng trong Báo cáo công cụ.

Hãy nhớ rằng không chỉ JavaScript có thể hưởng lợi từ URL có vân tay số; như biểu tượng, CSS và các tệp dữ liệu không thể thay đổi khác cũng có thể được đặt tên là này . (Và hãy nhớ xem video ở trên để tìm hiểu thêm một chút về mã chế độ này, cho phép bạn gửi ít mã hơn mỗi khi trang web của bạn thay đổi).

Bất kể trang web của bạn phương pháp lưu vào bộ nhớ đệm bằng cách nào, những kiểu vân tay số này có giá trị vô cùng lớn đối với bất kỳ trang web nào mà bạn có thể xây dựng. Hầu hết các trang web chỉ không thay đổi trên mọi bản phát hành.

Tất nhiên, chúng tôi không thể đổi tên các trang "thân thiện" dành cho người dùng theo cách này: đổi tên tệp index.html của bạn sang index.abcd12.html. Điều đó là không khả thi, bạn không biết người dùng truy cập vào URL mới mỗi khi họ tải trang web của bạn! Các cụm từ "thân thiện" URL không thể đổi tên và lưu vào bộ nhớ đệm theo cách này, điều này dẫn tôi đến phần giữa mặt đất.

Trung bình

Rõ ràng là có chỗ ở trung gian khi nói đến việc lưu vào bộ nhớ đệm. Tôi đã đưa ra hai phương án cực đoan; lưu vào bộ nhớ đệm không bao giờ hoặc lưu vào bộ nhớ đệm vĩnh viễn. Và sẽ có là một số tệp mà bạn có thể muốn lưu vào bộ nhớ đệm trong một khoảng thời gian, chẳng hạn như "thân thiện" URL mà tôi đã đề cập ở trên.

Nếu bạn muốn lưu các cụm từ "thân thiện" này vào bộ nhớ đệm và HTML của chúng. cân nhắc xem những phần phụ thuộc đó bao gồm như thế nào, cách chúng được lưu vào bộ nhớ đệm cũng như cách việc lưu URL của họ vào bộ nhớ đệm trong một khoảng thời gian có thể ảnh hưởng đến bạn. Hãy xem xét một trang HTML bao gồm một hình ảnh như sau:

<img src="/images/foo.jpeg" loading="lazy" />

Nếu bạn cập nhật hoặc thay đổi trang web của mình bằng cách xoá hoặc thay đổi mô-đun tải từng phần này hình ảnh khác, người dùng xem phiên bản được lưu trong bộ nhớ đệm của HTML có thể nhận được thông tin không chính xác hoặc thiếu hình ảnh—vì chúng vẫn lưu vào bộ nhớ đệm /images/foo.jpeg ban đầu khi họ truy cập lại vào trang web của bạn.

Nếu bạn cẩn thận, việc này có thể không ảnh hưởng đến bạn. Nhưng nhìn chung, điều quan trọng là hãy nhớ rằng trang web của bạn—khi được người dùng cuối lưu vào bộ nhớ đệm—không còn tồn tại trên máy chủ của bạn. Thay vào đó, dữ liệu này có thể tồn tại trong các phần bên trong bộ nhớ đệm của trình duyệt.

Nói chung, hầu hết các hướng dẫn về việc lưu vào bộ nhớ đệm sẽ nói về loại —bạn có muốn lưu vào bộ nhớ đệm trong một giờ, vài giờ, v.v. không. Để thiết lập dùng một tiêu đề như thế này để lưu vào bộ nhớ đệm trong 3600 giây, hoặc giờ):

Cache-Control: max-age=3600,immutable,public

Một điểm cuối cùng. Nếu bạn đang tạo nội dung kịp thời thường chỉ được người dùng truy cập một lần—như các tin bài!—ý kiến của tôi là những điều này không bao giờ được được lưu vào bộ nhớ đệm và bạn nên sử dụng chế độ mặc định hợp lý ở trên. Tôi nghĩ chúng tôi thường ước tính cao hơn giá trị của việc lưu vào bộ nhớ đệm so với mong muốn luôn xem được dữ liệu mới nhất của người dùng và nội dung hay nhất, chẳng hạn như nội dung cập nhật quan trọng về một bản tin hoặc sự kiện.

Tùy chọn không phải HTML

Ngoài HTML, một số tuỳ chọn khác cho tệp nằm ở trung gian bao gồm:

  • Nhìn chung, hãy tìm những thành phần không ảnh hưởng đến người khác

    • Ví dụ: tránh dùng CSS vì nó làm thay đổi cách thức HTML của bạn đã kết xuất
  • Hình ảnh lớn được dùng trong các bài viết kịp thời

    • Người dùng của bạn có thể sẽ không truy cập vào bất kỳ bài viết nào nữa Vì vậy, đừng lưu các bức ảnh hoặc hình ảnh chính vào bộ nhớ đệm vĩnh viễn và kho chứa rác thải
  • Một tài sản thể hiện một nội dung có giá trị vòng đời

    • Dữ liệu JSON về thời tiết có thể chỉ được xuất bản mỗi giờ một lần, vì vậy bạn có thể lưu kết quả trước đó vào bộ nhớ đệm trong một giờ—kết quả này sẽ không thay đổi trong cửa sổ của bạn
    • Các bản dựng của dự án nguồn mở có thể bị giới hạn tỷ lệ, vì vậy, hãy lưu vào bộ nhớ đệm hình ảnh trạng thái bản dựng cho đến khi có thể trạng thái thay đổi

Tóm tắt

Khi người dùng tải trang web của bạn lần thứ hai, bạn đã có phiếu bầu là sự tự tin—họ muốn quay lại và nhận nhiều hơn những gì bạn cung cấp. Lúc này vấn đề, không phải lúc nào cũng chỉ giảm thời gian tải đó và bạn rất nhiều tuỳ chọn có sẵn cho bạn để đảm bảo rằng trình duyệt của bạn chỉ thực hiện công việc đó hệ thống cần mang đến cả trải nghiệm nhanh chóng và cập nhật.

Lưu vào bộ nhớ đệm không phải là một khái niệm mới trên web, nhưng có lẽ nó cần một khái niệm hợp lý mặc định—hãy cân nhắc sử dụng một và chủ động chọn tham gia để có các chiến lược lưu vào bộ nhớ đệm hiệu quả hơn khi bạn cần. Cảm ơn bạn đã đọc!

Xem thêm

Để biết hướng dẫn chung về bộ nhớ đệm HTTP, hãy tham khảo Dùng Bộ nhớ đệm HTTP để ngăn chặn các yêu cầu không cần thiết về mạng.