Ngăn chặn CSS trong Chrome 52

TL;DR

Thuộc tính mới CSS Containment (Giới hạn CSS) cho phép nhà phát triển giới hạn phạm vi của kiểu, bố cục và công việc vẽ của trình duyệt.

CSS Containment. Trước: bố cục mất 59,6 mili giây. Sau: bố cục mất 0,05 mili giây

Phương thức này có một vài giá trị, tạo nên cú pháp như sau:

    contain: none | strict | content | [ size || layout || style || paint ]

Tính năng này có trong Chrome 52 trở lên và Opera 40 trở lên (và có hỗ trợ công khai từ Firefox). Hãy dùng thử và cho chúng tôi biết cảm nhận của bạn!

Thuộc tính chứa

Khi tạo một ứng dụng web hoặc thậm chí là một trang web phức tạp, thách thức chính về hiệu suất là giới hạn hiệu ứng của kiểu, bố cục và sơn. Thông thường, toàn bộ DOM được coi là "trong phạm vi" cho công việc tính toán, điều này có thể có nghĩa là việc thử một "thành phần hiển thị" độc lập trong ứng dụng web có thể sẽ gặp khó khăn: các thay đổi trong một phần của DOM có thể ảnh hưởng đến các phần khác và không có cách nào để cho trình duyệt biết nội dung nào nên nằm trong hoặc ngoài phạm vi.

Ví dụ: giả sử một phần DOM của bạn có dạng như sau:

    <section class="view">
      Home
    </section>

    <section class="view">
      About
    </section>

    <section class="view">
      Contact
    </section>

Và bạn sẽ thêm một phần tử mới vào một thành phần hiển thị, phần tử này sẽ kích hoạt các kiểu, bố cục và sơn:

    <section class="view">
      Home
    </section>

    <section class="view">
      About
      <div class="newly-added-element">Check me out!</div>
    </section>

    <section class="view">
      Contact
    </section>

Tuy nhiên, trong trường hợp này, toàn bộ DOM nằm trong phạm vi hiệu quả, nghĩa là các phép tính về kiểu, bố cục và sơn sẽ phải xem xét tất cả các phần tử, bất kể các phần tử đó có thay đổi hay không. DOM càng lớn thì càng có nhiều công việc tính toán liên quan, nghĩa là ứng dụng của bạn có thể không phản hồi hoạt động đầu vào của người dùng.

Tin vui là các trình duyệt hiện đại đang tự động giới hạn phạm vi của các kiểu, bố cục và công việc vẽ, nghĩa là mọi thứ sẽ diễn ra nhanh hơn mà bạn không cần làm gì cả.

Nhưng tin tuyệt vời hơn là có một thuộc tính CSS mới sẽ chuyển giao quyền kiểm soát phạm vi cho nhà phát triển: Containment (Giới hạn).

CSS Containment là một thuộc tính mới, với từ khoá contain (chứa) hỗ trợ 4 giá trị:

  • layout
  • paint
  • size
  • style

Mỗi giá trị trong số này cho phép bạn giới hạn lượng công việc kết xuất mà trình duyệt cần thực hiện. Hãy cùng tìm hiểu chi tiết hơn về từng giá trị.

Bố cục (contain: layout)

Tính năng chứa bố cục có lẽ là lợi ích lớn nhất của tính năng chứa, cùng với contain: paint.

Bố cục thường nằm trong phạm vi tài liệu, giúp bố cục đó mở rộng theo tỷ lệ với kích thước của DOM. Vì vậy, nếu bạn thay đổi thuộc tính left của một phần tử, thì có thể bạn cần kiểm tra mọi phần tử trong DOM.

Việc bật tính năng chứa ở đây có thể làm giảm số lượng phần tử xuống chỉ còn một vài phần tử, thay vì toàn bộ tài liệu, giúp trình duyệt tiết kiệm được rất nhiều công việc không cần thiết và cải thiện đáng kể hiệu suất.

Paint (chứa: paint)

Vẽ theo phạm vi là một lợi ích vô cùng hữu ích khác của tính năng chứa. Về cơ bản, tính năng chứa sơn sẽ cắt bớt phần tử có liên quan, nhưng cũng có một số tác dụng phụ khác:

  • Thành phần này đóng vai trò là khối chứa cho các phần tử có vị trí tuyệt đối và cố định. Điều này có nghĩa là mọi phần tử con đều được định vị dựa trên phần tử có contain: paint chứ không phải bất kỳ phần tử mẹ nào khác như – giả sử – tài liệu.
  • Nó trở thành ngữ cảnh xếp chồng. Điều này có nghĩa là các thành phần như z-index sẽ ảnh hưởng đến phần tử và các phần tử con sẽ được xếp chồng theo ngữ cảnh mới.
  • Đây sẽ trở thành ngữ cảnh định dạng mới. Điều này có nghĩa là nếu bạn có một phần tử cấp khối có vùng chứa sơn, thì phần tử đó sẽ được coi là một môi trường bố cục mới, độc lập. Điều này có nghĩa là bố cục bên ngoài phần tử thường sẽ không ảnh hưởng đến các phần tử con của phần tử chứa.

Kích thước (contain: size)

contain: size có nghĩa là các phần tử con của phần tử không ảnh hưởng đến kích thước của phần tử mẹ và các kích thước được suy luận hoặc khai báo của phần tử con sẽ là các kích thước được sử dụng. Do đó, nếu bạn đặt contain: size nhưng không chỉ định kích thước cho phần tử (trực tiếp hoặc thông qua các thuộc tính flex), thì phần tử đó sẽ được hiển thị ở kích thước 0px x 0px!

Tính năng chứa kích thước thực sự là một biện pháp phòng ngừa để đảm bảo bạn không dựa vào các phần tử con để định cỡ, nhưng bản thân tính năng này không mang lại nhiều lợi ích về hiệu suất.

Kiểu (contain: style)

Có thể khó dự đoán tác động của việc thay đổi kiểu của một phần tử đối với cây DOM khi khôi phục cây. Một ví dụ về điều này là trong các bộ đếm CSS, trong đó việc thay đổi bộ đếm trong một thành phần con có thể ảnh hưởng đến các giá trị bộ đếm có cùng tên được sử dụng ở nơi khác trong tài liệu. Khi bạn đặt contain: style, các thay đổi về kiểu sẽ không được truyền ngược lại phần tử chứa.

Để rõ ràng hơn, contain: style không cung cấp tính năng tạo kiểu theo phạm vi như bạn có thể nhận được từ Shadow DOM; tính năng chứa ở đây chỉ đơn thuần là giới hạn các phần của cây đang được xem xét khi các kiểu được thay đổi, không phải khi các kiểu được khai báo.

Quy định nghiêm ngặt và biện pháp kiểm soát nội dung

Bạn cũng có thể kết hợp các từ khoá, chẳng hạn như contain: layout paint, để chỉ áp dụng các hành vi đó cho một phần tử. Tuy nhiên, contain cũng hỗ trợ thêm hai giá trị:

  • contain: strict có nghĩa giống như contain: size layout paint
  • contain: content có nghĩa giống như contain: layout paint

Bạn nên sử dụng tính năng chứa nghiêm ngặt khi biết trước kích thước của phần tử (hoặc muốn đặt trước kích thước của phần tử đó). Tuy nhiên, hãy lưu ý rằng nếu bạn khai báo tính năng chứa nghiêm ngặt mà không có kích thước, thì do tính năng chứa kích thước ngầm ẩn, phần tử có thể được hiển thị dưới dạng hộp 0px x 0px.

Mặt khác, tính năng chứa nội dung mang lại những cải tiến đáng kể về phạm vi, nhưng không yêu cầu bạn phải biết hoặc chỉ định trước kích thước của phần tử.

Trong hai loại này, contain: content là loại bạn nên sử dụng theo mặc định. Bạn nên coi việc kiểm soát nghiêm ngặt là một lối thoát khi contain: content không đủ mạnh để đáp ứng nhu cầu của bạn.

Hãy cho chúng tôi biết cảm nhận của bạn

Cách tốt nhất để bắt đầu cho trình duyệt biết những nội dung bạn muốn tách biệt trong trang là sử dụng tính năng chứa. Hãy dùng thử tính năng này trong Chrome 52 trở lên và cho chúng tôi biết cảm nhận của bạn!