ในโลกของการพัฒนาเว็บที่เน้นประสบการณ์ผู้ใช้เป็นสำคัญ การสร้าง Animation ที่ลื่นไหลและตอบสนองได้ดีเป็นสิ่งจำเป็น อย่างไรก็ตาม บางครั้ง Animation ที่ซับซ้อนหรือมีการเปลี่ยนแปลงคุณสมบัติหลายอย่าง อาจทำให้เกิดอาการกระตุก ส่งผลให้เว็บไซต์ดูไม่เป็นมืออาชีพและลดประสบการณ์ที่ดีของผู้ใช้ลงได้
CSS will-change คือหนึ่งในคุณสมบัติของ CSS ที่เข้ามาช่วยแก้ปัญหานี้ มันไม่ได้เป็นคำสั่งที่สร้าง Animation โดยตรง แต่เป็น "คำแนะนำ" ที่เราส่งให้เบราว์เซอร์ล่วงหน้า เพื่อให้เบราว์เซอร์เตรียมพร้อมสำหรับการเปลี่ยนแปลงคุณสมบัติของ Element นั้นๆ ได้อย่างมีประสิทธิภาพมากขึ้น
will-change ทำงานอย่างไร?
ลองจินตนาการว่าเบราว์เซอร์คือเชฟที่กำลังทำอาหาร เมื่อเราสร้าง Animation เช่น การขยับ Element (transform), การเปลี่ยนความโปร่งใส (opacity) หรือการเปลี่ยนสี (color), เบราว์เซอร์จะต้องคำนวณและวาด Element เหล่านั้นใหม่
โดยปกติ เบราว์เซอร์จะประมวลผลไปทีละขั้นตอน:
- - Layout: คำนวณตำแหน่งและขนาดของ Element
- Paint: ระบายสีพิกเซลของ Element
- Composite: วาง Layer ของ Element ที่ระบายสีแล้วเข้าด้วยกัน เพื่อแสดงผลบนหน้าจอ
- - สร้าง Composite Layer ใหม่: สำหรับคุณสมบัติบางอย่าง เช่น transform, opacity, filter เบราว์เซอร์อาจสร้าง Element นั้นเป็น Layer แยกออกมา และส่งให้ GPU (หน่วยประมวลผลกราฟิก) ช่วยประมวลผล ซึ่งเร็วกว่าการใช้ CPU อย่างเดียว
- จัดสรรทรัพยากร: เบราว์เซอร์จะจัดสรร Memory หรือทรัพยากรอื่นๆ เพื่อรองรับการเปลี่ยนแปลงนั้นๆ
โครงสร้างการใช้งาน will-change
CSS
โค้ด: เลือกทั้งหมด
.element {
will-change: <propertyName> | <custom-ident> | initial | inherit | unset;
}
- - <propertyName>: คือชื่อคุณสมบัติ CSS ที่เราคาดว่าจะเปลี่ยนแปลงบ่อยๆ หรือมีการทำ Animation เช่น transform, opacity, scroll-position, left, top, width, height หรือ contents
- auto: (ค่าเริ่มต้น) เบราว์เซอร์จะตัดสินใจเองว่าจะ Optimize หรือไม่
- initial, inherit, unset: ค่ามาตรฐานของ CSS
will-change ไม่ได้มีไว้สำหรับทุก Animation แต่มีประโยชน์อย่างยิ่งกับ Animation ที่:
- - มีการเปลี่ยนแปลงบ่อยครั้ง หรือเป็นเวลานาน: เช่น การเลื่อนหน้า (Scrolling), การลาก Element (Drag & Drop), หรือ Animation ที่ทำงานต่อเนื่อง
- เป็น Animation ที่ซับซ้อน: มีการคำนวณมาก หรือมีการเปลี่ยนแปลงคุณสมบัติที่มักจะทำให้เกิด Layout/Paint Cycle ซ้ำๆ
- เกิดจากการ Interaction ของผู้ใช้: เมื่อผู้ใช้มีปฏิสัมพันธ์กับ Element แล้วเกิด Animation ทันที
Animation พลิกการ์ดมักจะใช้ transform: rotateY() ซึ่งสามารถใช้ประโยชน์จาก Composite Layer ได้
HTML
โค้ด: เลือกทั้งหมด
<div class="card-container">
<div class="card">
<div class="front">ด้านหน้า</div>
<div class="back">ด้านหลัง</div>
</div>
</div>
โค้ด: เลือกทั้งหมด
.card-container {
perspective: 1000px; /* จำเป็นสำหรับการทำ 3D Transform */
width: 200px;
height: 300px;
}
.card {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d; /* ทำให้ด้านหลังแสดงผลได้ถูกต้อง */
transition: transform 0.6s ease-in-out;
/* บอกเบราว์เซอร์ว่า card จะมีการเปลี่ยน transform */
will-change: transform;
}
.card:hover {
transform: rotateY(180deg);
}
.front, .back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden; /* ซ่อนด้านหลังเมื่อไม่หันมา */
display: flex;
justify-content: center;
align-items: center;
font-size: 1.5em;
color: white;
border-radius: 8px;
}
.front {
background-color: #3498db;
}
.back {
background-color: #e74c3c;
transform: rotateY(180deg); /* หมุนด้านหลังกลับมา */
}
ตัวอย่าง ตัวอย่างการใช้งาน will-change ที่ "ไม่ควรใช้"
การใช้ will-change อย่างไม่ถูกต้อง อาจส่งผลเสียมากกว่าผลดี เพราะเป็นการบังคับให้เบราว์เซอร์จองทรัพยากรไว้ล่วงหน้าโดยไม่จำเป็น ซึ่งอาจทำให้:
- - กิน Memory มากเกินไป: โดยเฉพาะถ้าใช้กับ Element จำนวนมาก หรือคุณสมบัติที่ไม่จำเป็นต้อง Optimize
- ทำให้เกิดอาการกระตุกแทน: หากเบราว์เซอร์ต้องสร้าง Layer มากเกินไป หรือจัดการทรัพยากรที่จองไว้โดยไม่เกิดประโยชน์
- ไม่มีผลลัพธ์ใดๆ: หากใช้กับคุณสมบัติที่ไม่ได้รับการ Optimize ด้วย will-change
ตัวอย่างที่ไม่ควรใช้ (1): การใส่ will-change แบบถาวรกับทุก Element หรือคุณสมบัติที่ไม่ใช่ Animation
CSS
โค้ด: เลือกทั้งหมด
/* ไม่ควรทำแบบนี้ */
body {
will-change: transform, opacity, color, background-color; /* ใช้กับหลายคุณสมบัติและไม่เหมาะสม */
}
/* ไม่ควรทำแบบนี้ */
.button {
will-change: background-color; /* background-color ไม่ได้ถูก Optimize ด้วย will-change ในเชิงประสิทธิภาพสูง */
}
- body เป็น Element ที่ใหญ่และไม่ควรจะมีการ transform หรือ opacity ตลอดเวลา การใส่ will-change ถาวรจะทำให้เปลือง Memory โดยไม่จำเป็น
- การเปลี่ยน background-color มักจะจัดการได้ดีอยู่แล้วโดยเบราว์เซอร์และไม่ได้ประโยชน์จากการ Optimize แบบ Composite Layer มากนัก
ตัวอย่างที่ไม่ควรใช้ (2): การใส่ will-change กับ Element ที่ไม่ได้มี Animation หรือ Interaction ใดๆ
HTML
โค้ด: เลือกทั้งหมด
<p class="static-text">นี่คือข้อความธรรมดา</p>
โค้ด: เลือกทั้งหมด
/* ไม่ควรทำแบบนี้ */
.static-text {
will-change: opacity; /* ไม่มีความจำเป็น */
}
สรุปและข้อควรพิจารณา
will-change เป็นเครื่องมือที่ทรงพลังสำหรับการปรับปรุงประสิทธิภาพของ Animation แต่ต้องใช้ด้วยความระมัดระวังและเข้าใจหลักการทำงานของมัน:
- - ใช้เมื่อจำเป็นเท่านั้น: ใช้เมื่อพบว่า Animation มีอาการกระตุกจริงๆ หลังจากพยายาม Optimize ด้วยวิธีอื่นแล้ว (เช่น ใช้ transform แทน left/top)
- เจาะจงคุณสมบัติ: ระบุคุณสมบัติที่จะเปลี่ยนให้เฉพาะเจาะจงที่สุด (เช่น will-change: transform; ดีกว่า will-change: all;)
- ใช้แบบชั่วคราว: ในสถานการณ์ที่ดีที่สุด ควรเพิ่ม will-change เมื่อ Element กำลังจะถูก Animation และถอดออกเมื่อ Animation สิ้นสุดลง (อาจใช้ JavaScript ช่วยในการเพิ่ม/ลบ Class)
- ทดสอบเสมอ: ใช้ DevTools ของเบราว์เซอร์ (เช่น Chrome DevTools > Performance) เพื่อตรวจสอบผลลัพธ์ว่า will-change ช่วยให้ Animation ลื่นไหลขึ้นจริงหรือไม่ และไม่ทำให้เกิดปัญหาอื่นตามมา
ลิ้งค์อ้างอิง
- https://www.mindphp.com/บทเรียนออนไลน์/ ... ตอน-1.html
- https://www.mindphp.com/บทเรียนออนไลน์/ ... ตอน-1.html
- https://www.mindphp.com/บทเรียนออนไลน์/ ... ตอน-2.html