การค้นหาคอนเทนเนอร์ได้ปฏิวัติวิธีนักพัฒนาซอฟต์แวร์ใช้การออกแบบที่ตอบสนอง และทีม Netflix ได้สัมผัสกับผลกระทบอันยิ่งใหญ่ที่การค้นหาคอนเทนเนอร์มีต่อการพัฒนาที่มีประสิทธิภาพมากขึ้น ความยืดหยุ่นที่เพิ่มขึ้น และประสิทธิภาพที่ดีขึ้น โพสต์นี้จะอธิบายประโยชน์หลักๆ ของการใช้การค้นหาคอนเทนเนอร์ โดยเปรียบเทียบกับวิธีการเก่าๆ โดยเฉพาะวิธีการที่ใช้ JavaScript ในการควบคุมเลย์เอาต์ บทความนี้มีตัวอย่างโค้ดเพื่ออธิบายแต่ละประเด็น ซึ่งแสดงให้เห็นว่าคําค้นหาคอนเทนเนอร์ช่วยให้ชีวิตของคุณในฐานะนักพัฒนาซอฟต์แวร์ง่ายขึ้นมากเพียงใด
1. การออกแบบคอมโพเนนต์ที่เรียบง่าย "จากล่างขึ้นบน" เทียบกับ "จากบนลงล่าง"
การเปลี่ยนแปลงที่สําคัญที่สุดอย่างหนึ่งที่ทีม Netflix พบคือการเปลี่ยนจากแนวทางการออกแบบ "จากบนลงล่าง" เป็นแนวทาง "จากล่างขึ้นบน" ก่อนการค้นหาคอนเทนเนอร์ คอนเทนเนอร์หลักต้องทราบข้อกำหนดของเลย์เอาต์ของคอนเทนเนอร์ย่อยอย่างครบถ้วน เมื่อใช้การค้นหาคอนเทนเนอร์ ตรรกะนี้จะกลับกัน ซึ่งช่วยให้คอมโพเนนต์ย่อยควบคุมเลย์เอาต์ตามขนาดของคอนเทนเนอร์ของตัวเองได้ วิธีนี้ช่วยลดความซับซ้อนของบทบาทของรายการหลักและลดจำนวนตรรกะเลย์เอาต์ในโค้ด
ตัวอย่าง: การค้นหาคอนเทนเนอร์เทียบกับ Media Query และ JavaScript
ก่อน (ต้องใช้ JavaScript):
/* Layout with media queries */
.card {
width: 100%;
}
@media (min-width: 600px) {
.card {
width: 50%;
}
}
@media (min-width: 900px) {
.card {
width: 33.33%;
}
}
// JavaScript to detect parent container size
const container = document.querySelector('.container');
const card = document.querySelector('.card');
function adjustLayout() {
if (window.innerWidth >= 900) {
card.style.width = '33.33%';
} else if (window.innerWidth >= 600) {
card.style.width = '50%';
} else {
card.style.width = '100%';
}
}
window.addEventListener('resize', adjustLayout);
adjustLayout();
หลัง:
/* Container Query */
.container {
container-type: inline-size;
}
.card {
width: 100%;
}
@container (min-width: 600px) {
.card {
width: 50%;
}
}
@container (min-width: 900px) {
.card {
width: 33.33%;
}
}
ตัวอย่างนี้แสดงว่าคอนเทนเนอร์หลักไม่จําเป็นต้องจัดการเลย์เอาต์ย่อยอีกต่อไป กฎ @container
ช่วยให้ .card
ตอบสนองต่อขนาดของคอนเทนเนอร์โดยรอบได้โดยตรง ซึ่งจะลดความซับซ้อนของตรรกะเลย์เอาต์และไม่จำเป็นต้องใช้ JavaScript เลย
2. การตอบสนองโดยไม่มี Media Query ที่ซับซ้อน
ทีม Netflix ค้นพบว่าคําค้นหาคอนเทนเนอร์ช่วยให้การตอบสนองง่ายขึ้นเพียงใด โดยเฉพาะสําหรับการออกแบบที่เน้นอุปกรณ์เคลื่อนที่เป็นอันดับแรก คุณสามารถสร้างคอมโพเนนต์ที่นํามาใช้ซ้ำได้ซึ่งปรับตามขนาดของคอนเทนเนอร์แทนการเขียนคิวรีสื่อที่ซับซ้อน ซึ่งช่วยให้มีเลย์เอาต์แบบไดนามิกในหน้าจอและอุปกรณ์ขนาดต่างๆ ซึ่งจะเป็นประโยชน์อย่างยิ่งสําหรับแอปอย่าง Netflix ที่มีการเข้าชมจากอุปกรณ์เคลื่อนที่เป็นหลัก
ตัวอย่าง: การตอบสนองของคอมโพเนนต์กับคำค้นหาคอนเทนเนอร์
ก่อน:
/* Desktop versus Mobile
this only works if.sidebar is directly contained by a viewport-width element */
.sidebar {
width: 300px;
}
@media (max-width: 768px) {
.sidebar {
width: 100%;
}
}
หลัง:
/* Responsive sidebar based on container,
.sidebar can be placed in any element of any width */
.container {
container-type: inline-size;
}
.sidebar {
width: 100%;
}
@container (min-width: 768px) {
.sidebar {
width: 300px;
}
}
ตอนนี้ .sidebar
จะตอบสนองต่อขนาดคอนเทนเนอร์แทนที่จะใช้ Media Query ตามวิวพอร์ต ซึ่งช่วยให้ปรับให้เข้ากับเลย์เอาต์แบบไดนามิกได้อย่างเป็นธรรมชาติมากขึ้นโดยไม่ต้องทราบขนาดของวิวพอร์ตหรือคอนเทนเนอร์หลัก
3. ลดการพึ่งพา JavaScript ในการจัดการเลย์เอาต์
ก่อนที่จะมีการค้นหาคอนเทนเนอร์ ทีมต่างๆ รวมถึง Netflix ต้องพึ่งพา JavaScript สําหรับเลย์เอาต์แบบไดนามิก การค้นหาขนาดหน้าต่างจะทำให้ JavaScript ทริกเกอร์การเปลี่ยนแปลงเลย์เอาต์ ซึ่งจะเพิ่มความซับซ้อนและอาจทำให้เกิดข้อบกพร่องได้ คิวรีคอนเทนเนอร์จะช่วยลดความจำเป็นนี้ด้วยการเปิดโอกาสให้ CSS จัดการการปรับเปลี่ยนเลย์เอาต์ตามขนาดคอนเทนเนอร์
ตัวอย่าง: การนำตรรกะเลย์เอาต์ที่อิงตาม JavaScript ออก
ก่อน:
const cardContainer = document.querySelector('.card-container');
const cards = cardContainer.children;
function adjustLayout() {
if (cardContainer.offsetWidth > 900) {
cards.forEach(card => card.style.width = '33.33%');
} else if (cardContainer.offsetWidth > 600) {
cards.forEach(card => card.style.width = '50%');
} else {
cards.forEach(card => card.style.width = '100%');
}
}
window.addEventListener('resize', adjustLayout);
adjustLayout();
หลัง:
.card-container {
container-type: inline-size;
}
.card {
width: 100%;
}
@container (min-width: 600px) {
.card {
width: 50%;
}
}
@container (min-width: 900px) {
.card {
width: 33.33%;
}
}
แนวทางนี้ไม่เพียงช่วยลดจํานวน JavaScript ที่จําเป็น แต่ยังช่วยปรับปรุงประสิทธิภาพด้วยการหลีกเลี่ยงการคํานวณรันไทม์
4. โค้ดน้อยลง ข้อบกพร่องน้อยลง
ทีม Netflix พบว่าการใช้การค้นหาคอนเทนเนอร์ทำให้โค้ดมีจำนวนบรรทัดน้อยลงและข้อบกพร่องเกี่ยวกับเลย์เอาต์ลดลง การย้ายตรรกะเลย์เอาต์จาก JavaScript ไปยัง CSS และการไม่ต้องใช้ Media Queries ที่ยุ่งยากช่วยให้นักพัฒนาแอปเขียนโค้ดที่ดูแลรักษาได้ง่ายขึ้น
ตัวอย่าง: การลดโค้ดเลย์เอาต์
ทีม Netflix พบว่าหลังจากใช้การค้นหาคอนเทนเนอร์แล้ว โค้ด CSS ลดลงอย่างมาก โดยลดลงถึง 30% สำหรับคอมโพเนนต์บางรายการ ในขณะเดียวกัน ทีมก็สามารถลดความซับซ้อนของคําค้นหาสื่อที่ซับซ้อนและบางครั้งก็ทำให้เกิดข้อขัดแย้งได้ด้วยการแยกตรรกะที่ควบคุมคอมโพเนนต์ย่อยออก เพื่อให้แยกข้อกังวลต่างๆ ในระดับที่สูงขึ้น การลดจำนวนนี้ไม่เพียงแต่จะเร่งการพัฒนา แต่ยังช่วยลดจุดที่อาจเกิดข้อผิดพลาดได้ ซึ่งส่งผลให้มีข้อบกพร่องน้อยลง
ก่อน:
/* Before with complex media queries */
.card {
width: 100%;
}
@media (min-width: 600px) {
.card {
width: 50%;
}
}
@media (min-width: 900px) {
.card {
width: 33.33%;
}
}
หลัง
.container {
container-type: inline-size;
}
.card {
width: 100%;
}
@container (min-width: 600px) {
.card {
width: 50%;
}
}
@container (min-width: 900px) {
.card {
width: 33.33%;
}
}
5. ประสบการณ์การใช้งานที่ดีขึ้นสำหรับนักพัฒนาแอป
bq. "สิ่งนี้ทำให้ชีวิตฉันง่ายขึ้นหลายร้อยเท่า"
ประโยชน์อย่างหนึ่งที่นักพัฒนาแอปไม่ค่อยตระหนักถึงเกี่ยวกับคําค้นหาคอนเทนเนอร์คือการปรับปรุงประสบการณ์การใช้งานของนักพัฒนาแอป การทำให้ CSS ทำงานในลักษณะที่ใช้งานง่ายและมุ่งเน้นคอมโพเนนต์มากขึ้นจะช่วยให้นักพัฒนาซอฟต์แวร์มุ่งเน้นที่การสร้างคอมโพเนนต์ที่ยืดหยุ่นและนํากลับมาใช้ซ้ำได้โดยไม่ต้องกังวลว่าจะทํางานอย่างไรในสถานการณ์เลย์เอาต์ที่เป็นไปได้ทั้งหมด
ดังที่สมาชิกคนหนึ่งจากทีม Netflix กล่าวไว้ว่า "CSS ควรทำงานแบบนี้มาตั้งแต่ต้น"
6. การแสดงผลสำรองด้วย Polyfill
แม้ว่าตอนนี้การค้นหาคอนเทนเนอร์จะมีอยู่ในเบราว์เซอร์หลักทั้งหมดแล้ว แต่ก็ยังมีความกังวลเกี่ยวกับเบราว์เซอร์เวอร์ชันเก่าที่ยังคงใช้งานอยู่ การแสดงผลสำรองเป็นสิ่งสําคัญมาก ทีม Netflix ใช้ JavaScript polyfill นี้ซึ่งสร้างโดยผู้มีส่วนร่วมในชุมชนเว็บ การติดตั้งใช้งานนั้นง่ายดายด้วยการตรวจจับองค์ประกอบต่อไปนี้
if (! CSS.supports("container-type:size")) {
/*use polyfill from
https://www.npmjs.com/package/container-query-polyfill */
}
บทสรุป
การค้นหาคอนเทนเนอร์เป็นก้าวสำคัญในการพัฒนา CSS ซึ่งช่วยให้นักพัฒนาซอฟต์แวร์สร้างคอมโพเนนต์ที่ยืดหยุ่นและตอบสนองได้ ซึ่งสามารถนำไปใช้ซ้ำในส่วนต่างๆ ของเว็บไซต์ได้ เทมเพลตเหล่านี้มีข้อดีอย่างมากทั้งในด้านประสิทธิภาพและการบำรุงรักษา เนื่องจากลดการพึ่งพา JavaScript สำหรับเลย์เอาต์ กำจัด Media Query ที่ซับซ้อน และเร่งการพัฒนา ปัจจุบัน Use Case ส่วนใหญ่อยู่ในหน้า Tudum ของ Netflix โดยมีแผนที่จะใช้การค้นหาคอนเทนเนอร์ในส่วนอื่นๆ ของ Netflix ทีม Netflix ถือว่าการค้นหาคอนเทนเนอร์เป็นเครื่องมือชั้นยอดในกล่องเครื่องมือของนักพัฒนาซอฟต์แวร์ และการใช้งานจะขยายตัวมากขึ้นเมื่อนักพัฒนาซอฟต์แวร์จำนวนมากขึ้นยอมรับความยืดหยุ่นและประสิทธิภาพที่เครื่องมือนี้มอบให้ ไม่ว่าคุณจะปรับแต่งคอมโพเนนต์ที่มีอยู่หรือออกแบบคอมโพเนนต์ใหม่ทั้งหมด การค้นหาคอนเทนเนอร์เป็นเส้นทางที่ง่ายและสะอาดขึ้นสำหรับการออกแบบที่ปรับเปลี่ยนตามอุปกรณ์
หากยังไม่ได้ลองใช้การค้นหาคอนเทนเนอร์ ให้ลองใช้ดู คุณอาจพบว่าการค้นหานี้ช่วยลดความซับซ้อนของเวิร์กโฟลว์ในแบบที่คาดไม่ถึง