content-Visibility: thuộc tính CSS mới giúp tăng hiệu suất hiển thị

Cải thiện thời gian tải ban đầu bằng cách bỏ qua quá trình kết xuất nội dung ngoài màn hình.

Ngày xuất bản: 5 tháng 8 năm 2020

Thuộc tính content-visibility cho phép tác nhân người dùng bỏ qua công việc kết xuất của một phần tử, bao gồm cả bố cục và vẽ, cho đến khi cần. Vì quá trình kết xuất bị bỏ qua, nên nếu một phần lớn nội dung của bạn nằm ngoài màn hình, thì việc sử dụng thuộc tính content-visibility sẽ giúp người dùng tải nhanh hơn nhiều trong lần đầu tiên. Tính năng này cũng cho phép tương tác nhanh hơn với nội dung trên màn hình. Khá gọn gàng.

Hỗ trợ trình duyệt

  • Chrome: 85.
  • Edge: 85.
  • Firefox: 125.
  • Safari: 18.

Nguồn

bản minh hoạ có các hình ảnh thể hiện kết quả mạng
Trong bản minh hoạ bài viết, việc áp dụng content-visibility: auto cho các khu vực nội dung được phân đoạn sẽ giúp tăng hiệu suất kết xuất 7 lần khi tải lần đầu. Hãy đọc tiếp để tìm hiểu thêm.

Giới hạn CSS

Mục tiêu chính và tổng thể của tính năng chứa CSS là cho phép cải thiện hiệu suất kết xuất nội dung web bằng cách tách biệt một cây con DOM khỏi phần còn lại của trang theo cách có thể dự đoán.

Về cơ bản, nhà phát triển có thể cho trình duyệt biết những phần nào của trang được đóng gói dưới dạng một tập hợp nội dung, cho phép trình duyệt suy luận về nội dung mà không cần xem xét trạng thái bên ngoài cây con. Khi biết được bit nội dung nào (cây con) chứa nội dung riêng biệt, trình duyệt có thể đưa ra quyết định tối ưu hoá để hiển thị trang.

Có bốn loại phương thức chứa CSS, mỗi loại là một giá trị tiềm năng cho thuộc tính CSS contain. Bạn có thể kết hợp các loại này trong một danh sách giá trị được phân tách bằng dấu cách:

  • size: Vùng chứa kích thước trên một phần tử đảm bảo hộp của phần tử có thể được bố trí mà không cần kiểm tra các phần tử con cháu của nó. Điều này có nghĩa là chúng ta có thể bỏ qua bố cục của các phần tử con nếu tất cả những gì chúng ta cần là kích thước của phần tử.
  • layout: Tính năng chứa bố cục có nghĩa là các phần tử con không ảnh hưởng đến bố cục bên ngoài của các hộp khác trên trang. Điều này cho phép chúng ta có thể bỏ qua bố cục của các phần tử con nếu tất cả những gì chúng ta muốn làm là bố trí các hộp khác.
  • style: Vùng chứa kiểu đảm bảo rằng các thuộc tính có thể có ảnh hưởng đến nhiều hơn các thành phần con cháu của nó không thoát khỏi phần tử đó (ví dụ: bộ đếm). Điều này cho phép chúng ta có thể bỏ qua việc tính toán kiểu cho các phần tử con nếu tất cả những gì chúng ta muốn là tính toán kiểu trên các phần tử khác.
  • paint: Tính năng chứa Paint đảm bảo rằng các phần tử con của hộp chứa không hiển thị bên ngoài giới hạn của hộp đó. Không có phần tử nào có thể tràn ra ngoài phần tử này, và nếu một phần tử nằm ngoài màn hình hoặc không hiển thị, thì các phần tử con của phần tử đó cũng sẽ không hiển thị. Điều này cho phép chúng ta có thể bỏ qua việc tô màu con cháu nếu phần tử nằm ngoài màn hình.

Bỏ qua công việc kết xuất bằng content-visibility

Bạn có thể khó xác định giá trị chứa nào nên sử dụng, vì tính năng tối ưu hoá trình duyệt chỉ có thể kích hoạt khi bạn chỉ định một tập hợp thích hợp. Bạn có thể thử nghiệm với các giá trị để xem giá trị nào hoạt động tốt nhất hoặc bạn có thể sử dụng content-visibility để tự động áp dụng vùng chứa cần thiết. content-visibility giúp đảm bảo bạn đạt được mức tăng hiệu suất lớn nhất mà nhà phát triển có thể đáp ứng mà không cần nhiều công sức.

Thuộc tính content-visibility chấp nhận một số giá trị, nhưng auto là giá trị giúp cải thiện hiệu suất ngay lập tức. Một phần tử có content-visibility: auto sẽ có vùng chứa layout, stylepaint. Nếu phần tử nằm ngoài màn hình (và không liên quan đến người dùng – các phần tử liên quan sẽ là những phần tử có tiêu điểm hoặc lựa chọn trong cây con), thì phần tử đó cũng sẽ có vùng chứa size (và ngừng vẽ cũng như kiểm thử lượt nhấp nội dung của phần tử đó).

Điều này có nghĩa là gì? Tóm lại, nếu phần tử nằm ngoài màn hình, thì các thành phần con của nó sẽ không được kết xuất. Trình duyệt xác định kích thước của phần tử mà không xem xét bất kỳ nội dung nào và trình duyệt sẽ dừng ở đó. Hầu hết các quy trình kết xuất, chẳng hạn như định kiểu và bố cục cho cây con của phần tử đều bị bỏ qua.

Khi phần tử tiến đến khung nhìn, trình duyệt sẽ không còn thêm vùng chứa size và bắt đầu vẽ cũng như kiểm thử nhấn vào nội dung của phần tử. Điều này cho phép công việc kết xuất được thực hiện đúng lúc để người dùng nhìn thấy.

Lưu ý về khả năng hỗ trợ tiếp cận

Một trong những tính năng của content-visibility: auto là nội dung ngoài màn hình vẫn có trong mô hình đối tượng tài liệu và do đó, cây hỗ trợ tiếp cận (không giống như với visibility: hidden). Điều này có nghĩa là bạn có thể tìm kiếm nội dung trên trang và chuyển đến nội dung đó mà không cần chờ nội dung tải hoặc hy sinh hiệu suất kết xuất.

Tuy nhiên, mặt trái của điều này là các phần tử điểm đánh dấu có các tính năng kiểu như display: none hoặc visibility: hidden cũng sẽ xuất hiện trong cây hỗ trợ tiếp cận khi nằm ngoài màn hình, vì trình duyệt sẽ không hiển thị các kiểu này cho đến khi chúng vào khung nhìn. Để các thành phần này không xuất hiện trong cây hỗ trợ tiếp cận, có thể gây lộn xộn, hãy nhớ thêm aria-hidden="true".

Ví dụ: blog du lịch

Trong ví dụ này, chúng ta đặt blog du lịch làm cơ sở ở bên phải và áp dụng content-visibility: auto cho các khu vực được chia thành phần ở bên trái. Kết quả cho thấy thời gian kết xuất thay đổi từ 232 mili giây đến 30 mili giây trong lần tải trang đầu tiên.

Blog du lịch thường chứa một tập hợp các câu chuyện có một vài hình ảnh và một số văn bản mô tả. Sau đây là những gì xảy ra trong một trình duyệt thông thường khi chuyển đến một blog du lịch:

  1. Một phần của trang được tải xuống từ mạng, cùng với mọi tài nguyên cần thiết.
  2. Kiểu trình duyệt và bố trí tất cả nội dung của trang mà không cần xem xét liệu nội dung có hiển thị cho người dùng hay không.
  3. Trình duyệt sẽ quay lại bước 1 cho đến khi tải xuống tất cả trang và tài nguyên.

Trong bước 2, trình duyệt xử lý tất cả nội dung để tìm những nội dung có thể đã thay đổi. Phương thức này cập nhật kiểu và bố cục của mọi phần tử mới, cùng với các phần tử có thể đã thay đổi do các bản cập nhật mới. Đây là công việc kết xuất. Việc này sẽ mất nhiều thời gian.

Ảnh chụp màn hình một blog du lịch.
Ví dụ về một blog du lịch. Xem Bản minh hoạ trên Codepen

Bây giờ, hãy xem điều gì sẽ xảy ra nếu bạn đưa content-visibility: auto vào từng tin bài riêng lẻ trên blog. Vòng lặp chung giống nhau: trình duyệt tải xuống và hiển thị các phần của trang. Tuy nhiên, điểm khác biệt là ở lượng công việc mà hàm này thực hiện trong bước 2.

Với thuộc tính content-visibility, thuộc tính này sẽ tạo kiểu và bố cục cho tất cả nội dung mà người dùng hiện có thể nhìn thấy (nội dung trên màn hình). Tuy nhiên, khi xử lý câu chuyện hoàn toàn nằm ngoài màn hình, trình duyệt sẽ bỏ qua công việc kết xuất và chỉ định kiểu và bố cục cho chính hộp phần tử.

Hiệu suất tải trang này sẽ giống như khi trang này chứa đầy đủ các câu chuyện trên màn hình và các hộp trống cho từng câu chuyện ngoài màn hình. Cách này hoạt động tốt hơn nhiều, với chi phí kết xuất tải dự kiến giảm 50% trở lên. Trong ví dụ này, chúng ta thấy thời gian kết xuất tăng từ 232 mili giây lên 30 mili giây. Tức là hiệu suất tăng 7 lần.

Bạn cần làm gì để hưởng những lợi ích này? Trước tiên, chúng ta phân chia nội dung thành các phần:

Ảnh chụp màn hình có chú thích về việc chia nội dung thành các phần bằng một lớp CSS.
Ví dụ về việc phân đoạn nội dung thành các phần bằng lớp story để nhận content-visibility: auto. Xem Bản minh hoạ trên Codepen

Sau đó, chúng ta áp dụng quy tắc kiểu sau cho các phần:

.story {
  content-visibility: auto;
  contain-intrinsic-size: 1000px; /* Explained in the next section. */
}

Chỉ định kích thước tự nhiên của một phần tử bằng contain-intrinsic-size

Để khai thác các lợi ích tiềm năng của content-visibility, trình duyệt cần áp dụng tính năng chứa kích thước để đảm bảo rằng kết quả kết xuất nội dung không ảnh hưởng đến kích thước của phần tử theo bất kỳ cách nào. Điều này có nghĩa là phần tử sẽ bố trí như thể phần tử đó trống. Nếu phần tử không có chiều cao được chỉ định trong bố cục khối thông thường, thì phần tử đó sẽ có chiều cao là 0.

Điều này có thể không lý tưởng vì kích thước của thanh cuộn sẽ thay đổi, phụ thuộc vào chiều cao của mỗi câu chuyện không phải là 0.

Rất may, CSS cung cấp một thuộc tính khác là contain-intrinsic-size. Thuộc tính này chỉ định hiệu quả kích thước tự nhiên của phần tử nếu phần tử đó chịu ảnh hưởng của tính năng chứa kích thước. Trong ví dụ này, chúng ta sẽ đặt giá trị này thành 1000px để ước tính chiều cao và chiều rộng của các phần.

Điều này có nghĩa là div này sẽ bố trí như thể có một phần tử con duy nhất có kích thước "intrinsic-size", đảm bảo rằng các div không có kích thước vẫn chiếm không gian. contain-intrinsic-size đóng vai trò là kích thước phần giữ chỗ thay cho nội dung được hiển thị.

Từ khoá auto cho contain-intrinsic-size sẽ khiến trình duyệt ghi nhớ kích thước hiển thị gần đây nhất (nếu có) và sử dụng kích thước đó thay vì kích thước phần giữ chỗ do nhà phát triển cung cấp. Ví dụ: nếu bạn chỉ định contain-intrinsic-size: auto 300px, thì phần tử sẽ bắt đầu với kích thước nội tại 300px theo mỗi phương diện, nhưng sau khi nội dung của phần tử được kết xuất, phần tử đó sẽ giữ lại kích thước nội tại đã kết xuất. Mọi thay đổi về kích thước kết xuất tiếp theo cũng sẽ được ghi nhớ. Trên thực tế, điều này có nghĩa là nếu bạn cuộn một phần tử có áp dụng content-visibility: auto rồi di chuyển phần tử đó ra ngoài màn hình, thì phần tử đó sẽ tự động giữ lại chiều rộng và chiều cao lý tưởng, đồng thời không quay về kích thước phần giữ chỗ. Tính năng này đặc biệt hữu ích cho các trình cuộn vô hạn, giờ đây có thể tự động cải thiện khả năng ước tính kích thước theo thời gian khi người dùng khám phá trang.

Ẩn nội dung bằng content-visibility: hidden

Nếu bạn muốn giữ nội dung không kết xuất bất kể nội dung đó có xuất hiện trên màn hình hay không, đồng thời tận dụng các lợi ích của trạng thái kết xuất được lưu trong bộ nhớ đệm thì sao? Nhập: content-visibility: hidden.

Thuộc tính content-visibility: hidden mang lại cho bạn tất cả các lợi ích giống như nội dung chưa kết xuất và trạng thái kết xuất được lưu vào bộ nhớ đệm như content-visibility: auto ngoài màn hình. Tuy nhiên, không giống như auto, lớp này không tự động bắt đầu kết xuất trên màn hình.

Điều này giúp bạn có thêm quyền kiểm soát, cho phép bạn ẩn nội dung của một phần tử và sau đó nhanh chóng hiện lại nội dung đó.

So sánh với các cách phổ biến khác để ẩn nội dung của phần tử:

  • display: none: ẩn phần tử và huỷ trạng thái kết xuất của phần tử đó. Điều này có nghĩa là việc hiển thị phần tử tốn kém như việc kết xuất một phần tử mới có cùng nội dung.
  • visibility: hidden: ẩn phần tử và giữ trạng thái kết xuất của phần tử đó. Việc này không thực sự xoá phần tử khỏi tài liệu, vì phần tử đó (và là cây con) vẫn chiếm không gian hình học trên trang và vẫn có thể nhấp vào được. Lớp này cũng cập nhật trạng thái kết xuất bất cứ khi nào cần thiết, ngay cả khi bị ẩn.

Mặt khác, content-visibility: hidden ẩn phần tử trong khi vẫn giữ nguyên trạng thái kết xuất của phần tử đó. Vì vậy, nếu có bất kỳ thay đổi nào cần xảy ra, thì các thay đổi đó chỉ xảy ra khi phần tử hiển thị lại (tức là thuộc tính content-visibility: hidden bị xoá).

Một số trường hợp sử dụng tuyệt vời cho content-visibility: hidden là khi triển khai các thanh cuộn ảo nâng cao và đo lường bố cục. Các ứng dụng này cũng rất phù hợp với ứng dụng một trang (SPA). Khung hiển thị của ứng dụng không hoạt động có thể được để lại trong DOM khi áp dụng content-visibility: hidden để ngăn hiển thị nhưng duy trì trạng thái được lưu vào bộ nhớ đệm. Điều này giúp thành phần hiển thị hiển thị nhanh khi thành phần đó hoạt động trở lại.

Ảnh hưởng đến Lượt tương tác đến nội dung hiển thị tiếp theo (INP)

INP là chỉ số đánh giá khả năng phản hồi đáng tin cậy của trang đối với hoạt động đầu vào của người dùng. Khả năng phản hồi có thể bị ảnh hưởng khi có quá nhiều tác vụ chạy trên luồng chính, bao gồm cả tác vụ kết xuất hình ảnh.

Bất cứ khi nào có thể giảm công việc kết xuất trên một trang bất kỳ, bạn đều tạo cơ hội để luồng chính phản hồi nhanh hơn đối với hoạt động đầu vào của người dùng. Điều này bao gồm cả công việc kết xuất và việc sử dụng thuộc tính CSS content-visiblity khi thích hợp có thể giảm công việc kết xuất, đặc biệt là trong quá trình khởi động, khi hầu hết công việc kết xuất và bố cục được thực hiện.

Việc giảm công việc kết xuất có ảnh hưởng trực tiếp đến INP. Khi người dùng cố gắng tương tác với một trang sử dụng đúng thuộc tính content-visibility để trì hoãn bố cục và kết xuất các phần tử ngoài màn hình, bạn đang cho luồng chính cơ hội phản hồi công việc quan trọng mà người dùng nhìn thấy. Điều này có thể cải thiện INP của trang trong một số trường hợp.

Kết luận

content-visibility và Thông số kỹ thuật về vùng chứa CSS có nghĩa là một số tính năng tăng hiệu suất thú vị sẽ có mặt cho tệp CSS của bạn. Để biết thêm thông tin về các thuộc tính này, hãy xem: