การเพิ่มประสิทธิภาพการโต้ตอบในเลย์เอาต์ที่ซับซ้อน

ฟีเจอร์บนเว็บ: content-visibility

รักษาอัตราเฟรมสูง (60 FPS) และกำจัดเวลาในการตอบสนองของการโต้ตอบระหว่างการลากและวางหรือการเปลี่ยนแปลงจำนวนมากในเลย์เอาต์หลายคอลัมน์ที่ซับซ้อน เช่น บอร์ด Kanban หรือตารางกริดข้อมูลขนาดใหญ่

ภาพรวม

ในเลย์เอาต์ที่ซับซ้อน การเปลี่ยนแปลงเล็กน้อยกับรายการเดียว เช่น การลากการ์ดหรือการแก้ไขเซลล์ อาจทำให้เกิดปฏิกิริยาลูกโซ่ของการคำนวณสไตล์และเลย์เอาต์ที่บังคับให้เบราว์เซอร์จัดเรียงทั้งหน้าใหม่ ซึ่งส่งผลให้เฟรมหายไปและเวลาในการตอบสนองของ Interaction to Next Paint (INP) สูง

การใช้ content-visibility: auto กับขอบเขตเลย์เอาต์แบบแยกส่วน (เช่น คอลัมน์ในบอร์ด Kanban) จะช่วยแยกงานการแสดงผลได้

กลไกสำหรับองค์ประกอบบนหน้าจอ

คุณควรทำความเข้าใจว่า content-visibility: auto มีประโยชน์ต่อองค์ประกอบที่ปรากฏบนหน้าจออยู่แล้วอย่างไร ดังนี้

  • สำหรับองค์ประกอบที่มองเห็นได้ เบราว์เซอร์จะไม่ข้ามการแสดงผล
  • แต่ประโยชน์ด้านประสิทธิภาพจะมาจากการจำกัด CSS ที่พร็อพเพอร์ตี้บังคับใช้โดยอัตโนมัติ (เช่น เลย์เอาต์ สไตล์ และการวาด) ทั้งหมด
  • การจำกัดนี้ทำหน้าที่เป็นขอบเขต หากเกิดการเปลี่ยนแปลงภายในคอนเทนเนอร์ที่มีการใช้การกักกัน เบราว์เซอร์จะทราบว่าการเปลี่ยนแปลงดังกล่าวไม่สามารถส่งผลต่อเรขาคณิตหรือสไตล์ขององค์ประกอบภายนอกคอนเทนเนอร์นั้นได้ การจัดเรียงหน้าใหม่จะแยกออกจากกันเพื่อป้องกันไม่ให้มีการคำนวณเลย์เอาต์โดยรวมใหม่

การใช้งาน

1. ระบุภูมิภาคที่มีการกักกัน

ใช้ content-visibility: auto กับคอนเทนเนอร์ขนาดใหญ่ที่สมบูรณ์ในตัวซึ่งแสดงถึงหน่วยเลย์เอาต์ที่แยกต่างหาก (เช่น คอลัมน์ตารางกริด รายการบอร์ด)

.board-column {
  /* Apply containment boundaries */
  content-visibility: auto;
  
  /* Mandatory: Provide a placeholder size to prevent layouts shifts.
     For a vertical column, define a reasonable width and height. 
     - 'auto' is optional and enables the browser to remember the actual size
       once rendered. It must be paired with a <length> value to be used for
       the first render.
     - '300px' is the estimated width of this element. This can be any valid
      CSS <length> value. Replace it with the expected width of your
      component.
     - '800px' is the estimated height of this element. This can be any valid
      CSS <length> value. Replace it with the expected height of your
      component.
   */
  contain-intrinsic-size: auto 300px auto 800px;
}

2. จัดการการโต้ตอบ

ตรวจสอบว่าการโต้ตอบที่เกิดขึ้นภายในคอลัมน์ได้รับประโยชน์จากการจำกัดขอบเขต

// Example: Drag and drop item movement
function moveItemToColumn(itemId, columnId) {
  const item = document.getElementById(itemId);
  const column = document.getElementById(columnId);
  
  // The browser will only reflow this specific column, 
  // not the entire board layout!
  column.appendChild(item);
}

กลยุทธ์สำรอง

พร็อพเพอร์ตี้จะลดระดับลงอย่างเหมาะสม ในเบราว์เซอร์ที่ไม่รองรับ

  • ระบบจะละเว้นพร็อพเพอร์ตี้ และการเปลี่ยนแปลงจะทำให้เกิดการจัดเรียงใหม่ทั่วโลกตามมาตรฐาน
  • หากต้องการให้ได้ผลลัพธ์การแยกที่คล้ายกันในเบราว์เซอร์รุ่นเก่า คุณสามารถกลับไปใช้การจำกัดด้วยตนเองได้โดยทำดังนี้
@supports not (content-visibility: auto) {
  .board-column {
    /* Manual fallback for containment */
    contain: layout style paint;
  }
}