Worklet แอนิเมชันของ Houdini

เพิ่มประสิทธิภาพภาพเคลื่อนไหวของเว็บแอป

สรุป: เวิร์กเลตภาพเคลื่อนไหวช่วยให้คุณเขียนภาพเคลื่อนไหวแบบบังคับซึ่งทำงานในอัตราเฟรมเดิมของอุปกรณ์เพื่อให้ราบรื่นยิ่งขึ้นและไม่มีกระตุก™ ทําให้ภาพเคลื่อนไหวมีความยืดหยุ่นมากขึ้นเมื่อเกิดข้อขัดข้องในเธรดหลัก และสามารถลิงก์กับการเลื่อนแทนเวลา เวิร์กเลตภาพเคลื่อนไหวมีอยู่ใน Chrome Canary (อยู่หลัง Flag "ฟีเจอร์แพลตฟอร์มเว็บเวอร์ชันทดลอง") และเรากำลังวางแผนช่วงทดลองใช้จากต้นทางสำหรับ Chrome 71 คุณเริ่มใช้ฟีเจอร์นี้เป็นการปรับปรุงแบบค่อยเป็นค่อยไปได้ตั้งแต่วันนี้

มี Animation API อื่นอีกไหม

ไม่ได้ ฟีเจอร์นี้เป็นส่วนขยายของฟีเจอร์ที่เรามีอยู่แล้ว และเรามีเหตุผลที่ดี มาเริ่มกันตั้งแต่ต้น หากต้องการสร้างภาพเคลื่อนไหวขององค์ประกอบ DOM ในเว็บวันนี้ คุณมี 2 ½ ทางเลือก ได้แก่ การเปลี่ยน CSS สำหรับการเปลี่ยนจาก A ไป B แบบง่าย ภาพเคลื่อนไหว CSS สำหรับภาพเคลื่อนไหวตามเวลาที่อาจวนซ้ำและซับซ้อนมากขึ้น และ Web Animations API (WAAPI) สำหรับภาพเคลื่อนไหวที่ซับซ้อนเกือบจะกำหนดเองได้ ตารางการสนับสนุนของ WAAPI ดูเหมือนจะไม่ค่อยดีนัก แต่เรากำลังพยายามปรับปรุงให้ดีขึ้น ในระหว่างนี้ เรามีโพลีฟิลล์

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

แล้วสถานะไม่มีสถานะล่ะ ตัวอย่างเช่น ลองนึกถึงแถบที่อยู่ของ Chrome ใน Android หากเลื่อนลง ไอคอนจะเลื่อนออกไปนอกมุมมอง แต่ทันทีที่คุณเลื่อนขึ้น โฆษณาจะกลับมาปรากฏขึ้น แม้ว่าคุณจะเลื่อนหน้าไปครึ่งทางแล้วก็ตาม ภาพเคลื่อนไหวไม่เพียงขึ้นอยู่กับตำแหน่งการเลื่อน แต่ยังขึ้นอยู่กับทิศทางการเลื่อนก่อนหน้าด้วย ข้อมูลมีสถานะ

อีกปัญหาหนึ่งคือการจัดสไตล์แถบเลื่อน เป็นที่รู้จักกันว่าแต่งตัวไม่เก่ง หรืออย่างน้อยก็แต่งตัวไม่เก่งพอ ฉันต้องทำอย่างไรหากต้องการใช้น้อนเหมียวเป็นแถบเลื่อน ไม่ว่าคุณจะเลือกเทคนิคใดก็ตาม การสร้างแถบเลื่อนที่กําหนดเองนั้นไม่มีประสิทธิภาพและไม่ง่าย

ประเด็นคือสิ่งเหล่านี้ทั้งหมดใช้ยากและแทบเป็นไปไม่ได้ที่จะติดตั้งใช้งานอย่างมีประสิทธิภาพ ส่วนใหญ่จะอาศัยเหตุการณ์และ/หรือ requestAnimationFrame ซึ่งอาจทำให้คุณใช้ 60 FPS ต่อไป แม้ว่าหน้าจอจะทำงานได้ที่ 90 FPS, 120 FPS หรือสูงกว่า และจะใช้เพียงเศษเสี้ยวของงบประมาณเฟรมเธรดหลักอันมีค่า

เวิร์กเลตภาพเคลื่อนไหวจะขยายความสามารถของสแต็กภาพเคลื่อนไหวของเว็บเพื่อให้สร้างเอฟเฟกต์ประเภทนี้ได้ง่ายขึ้น ก่อนจะลงลึกกัน เรามาทบทวนข้อมูลเบื้องต้นเกี่ยวกับภาพเคลื่อนไหวกันก่อน

ข้อมูลเบื้องต้นเกี่ยวกับภาพเคลื่อนไหวและไทม์ไลน์

WAAPI และ Animation Worklet ใช้ไทม์ไลน์อย่างกว้างขวางเพื่อให้คุณจัดระเบียบภาพเคลื่อนไหวและเอฟเฟกต์ในแบบที่คุณต้องการได้ ส่วนนี้เป็นข้อมูลสรุปสั้นๆ หรือข้อมูลเบื้องต้นเกี่ยวกับไทม์ไลน์และวิธีการทำงานของไทม์ไลน์กับภาพเคลื่อนไหว

แต่ละเอกสารมี document.timeline ค่าเริ่มต้นที่ 0 เมื่อสร้างเอกสารและนับมิลลิวินาทีนับตั้งแต่ที่เอกสารเริ่มมีอยู่ ภาพเคลื่อนไหวทั้งหมดของเอกสารจะทำงานตามไทม์ไลน์นี้

มาดูตัวอย่างข้อมูลโค้ด WAAPI นี้เพื่อให้เข้าใจมากขึ้น

const animation = new Animation(
  new KeyframeEffect(
    document.querySelector('#a'),
    [
      {
        transform: 'translateX(0)',
      },
      {
        transform: 'translateX(500px)',
      },
      {
        transform: 'translateY(500px)',
      },
    ],
    {
      delay: 3000,
      duration: 2000,
      iterations: 3,
    }
  ),
  document.timeline
);

animation.play();

เมื่อเราเรียกใช้ animation.play() ภาพเคลื่อนไหวจะใช้ currentTime ของไทม์ไลน์เป็นเวลาเริ่มต้น ภาพเคลื่อนไหวของเรามีความล่าช้า 3000ms ซึ่งหมายความว่าภาพเคลื่อนไหวจะเริ่ม (หรือ "ทำงาน") เมื่อไทม์ไลน์ถึง `startTime

  • 3000. After that time, the animation engine will animate the given element from the first keyframe (translateX(0)), through all intermediate keyframes (translateX(500px)) all the way to the last keyframe (translateY(500px)) in exactly 2000ms, as prescribed by thedurationoptions. Since we have a duration of 2000ms, we will reach the middle keyframe when the timeline'scurrentTimeisstartTime + 3000 + 1000and the last keyframe atstartTime + 3000 + 2000` ประเด็นคือไทม์ไลน์จะควบคุมตำแหน่งของเราในแอนิเมชัน

เมื่อภาพเคลื่อนไหวไปถึงคีย์เฟรมสุดท้ายแล้ว ระบบจะข้ามกลับไปที่คีย์เฟรมแรกและเริ่มภาพเคลื่อนไหวซ้ำรอบถัดไป กระบวนการนี้จะทําซ้ำทั้งหมด 3 ครั้งนับตั้งแต่ที่เราตั้งค่า iterations: 3 หากต้องการให้ภาพเคลื่อนไหวเล่นไปเรื่อยๆ เราจะเขียน iterations: Number.POSITIVE_INFINITY นี่คือผลลัพธ์ของโค้ดด้านบน

WAAPI มีประสิทธิภาพสูงมาก และมีฟีเจอร์อื่นๆ อีกมากมายใน API นี้ เช่น การผ่อนคลาย การเลื่อนเวลาเริ่มต้น น้ำหนักของเฟรมหลัก และลักษณะการเติม ซึ่งเกินขอบเขตของบทความนี้ หากต้องการดูข้อมูลเพิ่มเติม เราขอแนะนําให้อ่านบทความนี้เกี่ยวกับภาพเคลื่อนไหว CSS ใน CSS Tricks

การเขียนเวิร์กเลตภาพเคลื่อนไหว

เมื่อเข้าใจแนวคิดของไทม์ไลน์แล้ว เรามาเริ่มดูเวิร์กเลตภาพเคลื่อนไหวและวิธีที่เวิร์กเลตนี้ช่วยให้คุณจัดการไทม์ไลน์ได้ Animation Worklet API ไม่ได้อิงตาม WAAPI เท่านั้น แต่ยังเป็นองค์ประกอบระดับล่างที่อธิบายวิธีการทำงานของ WAAPI ในความหมายของเว็บที่ขยายได้ ไวยากรณ์ของทั้ง 2 รายการนี้คล้ายกันมาก

Worklet ภาพเคลื่อนไหว WAAPI
new WorkletAnimation(
  'passthrough',
  new KeyframeEffect(
    document.querySelector('#a'),
    [
      {
        transform: 'translateX(0)'
      },
      {
        transform: 'translateX(500px)'
      }
    ],
    {
      duration: 2000,
      iterations: Number.POSITIVE_INFINITY
    }
  ),
  document.timeline
).play();
      
        new Animation(

        new KeyframeEffect(
        document.querySelector('#a'),
        [
        {
        transform: 'translateX(0)'
        },
        {
        transform: 'translateX(500px)'
        }
        ],
        {
        duration: 2000,
        iterations: Number.POSITIVE_INFINITY
        }
        ),
        document.timeline
        ).play();
        

ความแตกต่างอยู่ที่พารามิเตอร์แรก ซึ่งเป็นชื่อของ Worklet ที่ขับเคลื่อนภาพเคลื่อนไหวนี้

การตรวจหาองค์ประกอบ

Chrome เป็นเบราว์เซอร์แรกที่เปิดตัวฟีเจอร์นี้ คุณจึงต้องตรวจสอบว่าโค้ดไม่ได้คาดหวังว่าจะมี AnimationWorklet อยู่ ดังนั้นก่อนโหลดชิ้นงาน เราควรตรวจดูว่าเบราว์เซอร์ของผู้ใช้รองรับAnimationWorkletหรือไม่ด้วยการตรวจสอบง่ายๆ ดังนี้

if ('animationWorklet' in CSS) {
  // AnimationWorklet is supported!
}

กำลังโหลดชิ้นงาน

เวิร์กเลตเป็นแนวคิดใหม่ที่ทีม Houdini นำเสนอเพื่อให้สร้างและปรับขนาด API ใหม่จำนวนมากได้ง่ายขึ้น เราจะอธิบายรายละเอียดของเวิร์กเลตเพิ่มเติมในภายหลัง แต่ตอนนี้คุณอาจเข้าใจเวิร์กเลตได้ง่ายๆ ว่าเป็นเธรดราคาถูกและเบา (เช่น เวิร์กเกอร์)

เราต้องตรวจสอบว่าได้โหลดเวิร์กเลตชื่อ "passthrough" แล้วก่อนที่จะประกาศภาพเคลื่อนไหว

// index.html
await CSS.animationWorklet.addModule('passthrough-aw.js');
// ... WorkletAnimation initialization from above ...

// passthrough-aw.js
registerAnimator(
  'passthrough',
  class {
    animate(currentTime, effect) {
      effect.localTime = currentTime;
    }
  }
);

เกิดอะไรขึ้น เรากําลังลงทะเบียนคลาสเป็นภาพเคลื่อนไหวโดยใช้การเรียก registerAnimator() ของ AnimationWorklet โดยตั้งชื่อเป็น "passthrough" ซึ่งเป็นชื่อเดียวกับที่เราใช้ในคอนสตรคเตอร์ WorkletAnimation() ด้านบน เมื่อลงทะเบียนเสร็จแล้ว พรอมต์ที่ addModule() แสดงจะได้รับการแก้ไขและเราจะเริ่มสร้างภาพเคลื่อนไหวโดยใช้เวิร์กเลตนั้นได้

ระบบจะเรียกใช้เมธอด animate() ของอินสแตนซ์สำหรับเฟรมทุกเฟรมที่เบราว์เซอร์ต้องการแสดงผล โดยส่ง currentTime ของไทม์ไลน์ภาพเคลื่อนไหว รวมถึงเอฟเฟกต์ที่ประมวลผลอยู่ในปัจจุบัน เรามีเอฟเฟกต์เพียงรายการเดียวคือ KeyframeEffect และใช้ currentTime เพื่อตั้งค่า localTime ของเอฟเฟกต์ จึงเป็นที่มาของชื่อ "พาสทรู" ของภาพเคลื่อนไหวนี้ เมื่อใช้โค้ดนี้สำหรับเวิร์กเลต WAAPI และ AnimationWorklet ด้านบนจะทํางานเหมือนกันทุกประการ ดังที่เห็นในเดโม

เวลา

พารามิเตอร์ currentTime ของเมธอด animate() คือ currentTime ของไทม์ไลน์ที่เราส่งไปยังคอนสตรัคเตอร์ WorkletAnimation() ในตัวอย่างก่อนหน้านี้ เราเพิ่งส่งเวลานั้นไปยังเอฟเฟกต์ แต่เนื่องจากนี่คือโค้ด JavaScript และเราสามารถบิดเบือนเวลา 💫

function remap(minIn, maxIn, minOut, maxOut, v) {
  return ((v - minIn) / (maxIn - minIn)) * (maxOut - minOut) + minOut;
}
registerAnimator(
  'sin',
  class {
    animate(currentTime, effect) {
      effect.localTime = remap(
        -1,
        1,
        0,
        2000,
        Math.sin((currentTime * 2 * Math.PI) / 2000)
      );
    }
  }
);

เราจะนํา Math.sin() ของ currentTime มาแมปค่านั้นใหม่เป็นช่วง [0; 2000] ซึ่งเป็นช่วงเวลาที่กําหนดเอฟเฟกต์ ตอนนี้ภาพเคลื่อนไหวดูแตกต่างออกไปมาก โดยไม่ต้องเปลี่ยนคีย์เฟรมหรือตัวเลือกของภาพเคลื่อนไหว โค้ดเวิร์กเลตมีความซับซ้อนได้ตามความสะดวก และให้คุณกำหนดเอฟเฟกต์ที่จะเล่นตามลำดับและระดับใดก็ได้แบบเป็นโปรแกรม

ตัวเลือกเหนือตัวเลือก

คุณอาจต้องการใช้ชิ้นงานซ้ำและเปลี่ยนตัวเลข ด้วยเหตุนี้ ตัวสร้าง WorkletAnimation จึงอนุญาตให้คุณส่งออบเจ็กต์ตัวเลือกไปยังเวิร์กเลตได้ ดังนี้

registerAnimator(
  'factor',
  class {
    constructor(options = {}) {
      this.factor = options.factor || 1;
    }
    animate(currentTime, effect) {
      effect.localTime = currentTime * this.factor;
    }
  }
);

new WorkletAnimation(
  'factor',
  new KeyframeEffect(
    document.querySelector('#b'),
    [
      /* ... same keyframes as before ... */
    ],
    {
      duration: 2000,
      iterations: Number.POSITIVE_INFINITY,
    }
  ),
  document.timeline,
  {factor: 0.5}
).play();

ในตัวอย่างนี้ ภาพเคลื่อนไหวทั้ง 2 รายการทำงานด้วยโค้ดเดียวกัน แต่มีตัวเลือกต่างกัน

บอกสถานะในพื้นที่ของคุณ

ดังที่ได้บอกไว้ก่อนหน้านี้ ปัญหาหลักอย่างหนึ่งที่เวิร์กเลตภาพเคลื่อนไหวมุ่งเน้นที่จะแก้ไขคือภาพเคลื่อนไหวที่มีสถานะ อนุญาตให้ชิ้นงานภาพเคลื่อนไหวเก็บสถานะ อย่างไรก็ตาม ฟีเจอร์หลักอย่างหนึ่งของเวิร์กเลตคือสามารถย้ายไปยังเธรดอื่นหรือแม้แต่ทำลายเพื่อประหยัดทรัพยากร ซึ่งจะทำลายสถานะของเวิร์กเลตด้วย เพื่อป้องกันไม่ให้สถานะสูญหาย เวิร์กเลตภาพเคลื่อนไหวจะมีฮุกที่เรียกก่อนเวิร์กเลตถูกทำลาย ซึ่งคุณใช้เพื่อแสดงผลออบเจ็กต์สถานะได้ ระบบจะส่งออบเจ็กต์นั้นไปยังคอนสตรัคเตอร์เมื่อสร้างเวิร์กเลตอีกครั้ง ในการสร้างครั้งแรก พารามิเตอร์ดังกล่าวจะเป็น undefined

registerAnimator(
  'randomspin',
  class {
    constructor(options = {}, state = {}) {
      this.direction = state.direction || (Math.random() > 0.5 ? 1 : -1);
    }
    animate(currentTime, effect) {
      // Some math to make sure that `localTime` is always > 0.
      effect.localTime = 2000 + this.direction * (currentTime % 2000);
    }
    destroy() {
      return {
        direction: this.direction,
      };
    }
  }
);

ทุกครั้งที่คุณรีเฟรชการสาธิตนี้ คุณจะมีสิทธิ์ 50/50 ว่าสี่เหลี่ยมจัตุรัสจะหมุนไปทางใด หากเบราว์เซอร์จะรื้อถอน Worklet และย้ายไปยังเธรดอื่น ก็จะมีการเรียกใช้ Math.random() อีกครั้งเมื่อสร้าง ซึ่งอาจทําให้ทิศทางเปลี่ยนแปลงอย่างฉับพลัน เพื่อป้องกันไม่ให้เกิดเหตุการณ์ดังกล่าว เราจะแสดงผลลัพธ์เป็นสถานะของภาพเคลื่อนไหวซึ่งเลือกแบบสุ่ม และนำไปใช้ในคอนสตรัคเตอร์ (หากมี)

การเชื่อมโยงกับมิติเวลาต่อเนื่อง: ScrollTimeline

ดังที่ส่วนก่อนหน้านี้ได้แสดงไว้ AnimationWorklet ช่วยให้เราสามารถกำหนดแบบเป็นโปรแกรมได้ว่าการเลื่อนไทม์ไลน์มีผลต่อเอฟเฟกต์ของภาพเคลื่อนไหวอย่างไร แต่ที่ผ่านมา ไทม์ไลน์ของเราคือ document.timeline เสมอ ซึ่งจะติดตามเวลา

ScrollTimeline เปิดโอกาสใหม่ๆ และให้คุณควบคุมภาพเคลื่อนไหวด้วยการเลื่อนแทนเวลา เราจะนําชิ้นงาน "การส่งต่อ" แรกสุดของเรามาใช้ซ้ำในการสาธิตนี้

new WorkletAnimation(
  'passthrough',
  new KeyframeEffect(
    document.querySelector('#a'),
    [
      {
        transform: 'translateX(0)',
      },
      {
        transform: 'translateX(500px)',
      },
    ],
    {
      duration: 2000,
      fill: 'both',
    }
  ),
  new ScrollTimeline({
    scrollSource: document.querySelector('main'),
    orientation: 'vertical', // "horizontal" or "vertical".
    timeRange: 2000,
  })
).play();

เราจะสร้าง ScrollTimeline ใหม่แทนการส่ง document.timeline คุณอาจเดาได้ว่า ScrollTimeline ไม่ได้ใช้เวลา แต่ใช้ตําแหน่งการเลื่อนของ scrollSource เพื่อตั้งค่า currentTime ในเวิร์กเลต การเลื่อนขึ้นสุด (หรือซ้ายสุด) หมายถึง currentTime = 0 ส่วนการเลื่อนลงสุด (หรือขวาสุด) จะตั้งค่า currentTime เป็น timeRange หากเลื่อนกล่องในการสาธิตนี้ คุณจะควบคุมตำแหน่งของกล่องสีแดงได้

หากคุณสร้าง ScrollTimeline ที่มีองค์ประกอบที่ไม่เลื่อน currentTime ของไทม์ไลน์จะเป็น NaN ดังนั้น คุณควรเตรียมพร้อมให้ NaN เป็น currentTime ของคุณเสมอ โดยเฉพาะเมื่อใช้การออกแบบที่ปรับเปลี่ยนตามอุปกรณ์ โดยทั่วไปแล้ว การตั้งค่าเริ่มต้นเป็นค่า 0 มักเป็นทางเลือกที่เหมาะสม

การลิงก์ภาพเคลื่อนไหวกับตำแหน่งการเลื่อนเป็นสิ่งที่เราพยายามทำมาอย่างยาวนาน แต่ก็ไม่เคยบรรลุเป้าหมายในระดับความถูกต้องนี้ (นอกเหนือจากการแก้ปัญหาด้วย CSS3D แบบฮ่าคๆ) ชิ้นงานภาพเคลื่อนไหวช่วยให้คุณใช้เอฟเฟกต์เหล่านี้ได้ง่ายๆ ในขณะเดียวกันก็มีประสิทธิภาพสูง ตัวอย่างเช่น การสาธิตเอฟเฟกต์ภาพ Parallax ในการเลื่อนหน้าจอนี้แสดงให้เห็นว่าตอนนี้คุณกำหนดภาพเคลื่อนไหวที่ทำงานจากการเลื่อนหน้าจอได้เพียงไม่กี่บรรทัด

กลไกภายใน

Worklet

เวิร์กเลตคือบริบท JavaScript ที่มีขอบเขตแยกต่างหากและ API เพียงเล็กน้อย แพลตฟอร์ม API ขนาดเล็กช่วยให้เบราว์เซอร์เพิ่มประสิทธิภาพได้มากขึ้น โดยเฉพาะในอุปกรณ์ระดับล่าง นอกจากนี้ เวิร์กเลตไม่ได้เชื่อมโยงกับลูปเหตุการณ์ที่เฉพาะเจาะจง แต่สามารถย้ายไปมาระหว่างเธรดได้ตามต้องการ ซึ่งสำคัญอย่างยิ่งสำหรับ AnimationWorklet

Compositor NSync

คุณอาจทราบว่าพร็อพเพอร์ตี้ CSS บางรายการแสดงภาพเคลื่อนไหวได้เร็ว ในขณะที่บางรายการไม่แสดง พร็อพเพอร์ตี้บางรายการต้องดำเนินการบางอย่างกับ GPU เพื่อให้เคลื่อนไหวได้ ส่วนพร็อพเพอร์ตี้อื่นๆ จะบังคับให้เบราว์เซอร์จัดวางเอกสารทั้งฉบับใหม่

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

ตบข้อมือ

โดยปกติแล้วจะมีกระบวนการคอมโพสิตเพียง 1 รายการเท่านั้นที่อาจแชร์กันในหลายแท็บ เนื่องจาก GPU เป็นทรัพยากรที่มีการแข่งขันสูง หากคอมโพสิตเตอร์ถูกบล็อก เบราว์เซอร์ทั้งตัวจะหยุดทำงานและไม่ตอบสนองต่อการป้อนข้อมูลของผู้ใช้ คุณต้องหลีกเลี่ยงการดำเนินการนี้โดยสิ้นเชิง จะเกิดอะไรขึ้นหากเวิร์กเลตของคุณไม่สามารถส่งข้อมูลที่คอมโพสิตต้องการได้ทันเวลาสำหรับการแสดงผลเฟรม

หากเกิดกรณีนี้ขึ้น ระบบจะอนุญาตให้ "เลื่อน" ชิ้นงานตามข้อกําหนด ซึ่งจะทำงานช้ากว่าโปรแกรมคอมโพสิเตอร์ และโปรแกรมคอมโพสิเตอร์ได้รับอนุญาตให้ใช้ข้อมูลของเฟรมสุดท้ายซ้ำเพื่อรักษาอัตราเฟรมให้สูง ลักษณะที่ปรากฏจะดูกระตุก แต่ความแตกต่างที่สำคัญคือเบราว์เซอร์ยังคงตอบสนองต่ออินพุตของผู้ใช้

บทสรุป

AnimationWorklet มีประโยชน์หลายประการต่อเว็บ ประโยชน์ที่เห็นได้ชัดคือการควบคุมภาพเคลื่อนไหวได้มากขึ้นและวิธีใหม่ๆ ในการแสดงภาพเคลื่อนไหวเพื่อยกระดับความสมจริงของภาพในเว็บไปอีกขั้น แต่การออกแบบ API ยังช่วยให้แอปของคุณมีความยืดหยุ่นมากขึ้นเมื่อเกิดปัญหากระตุกไปพร้อมๆ กับการเข้าถึงฟีเจอร์ใหม่ๆ ทั้งหมดด้วย

ชิ้นงานภาพเคลื่อนไหวอยู่ใน Canary และเรากําลังมุ่งสู่เวอร์ชันทดลองใช้กับ Chrome 71 เราหวังว่าคุณจะได้สัมผัสประสบการณ์การใช้งานเว็บที่ยอดเยี่ยมและบอกให้เราทราบถึงสิ่งที่เราควรปรับปรุง นอกจากนี้ยังมี polyfill ที่ให้คุณใช้ API เดียวกันได้ แต่ไม่แยกประสิทธิภาพ

โปรดทราบว่าการเปลี่ยน CSS และภาพเคลื่อนไหว CSS ยังคงเป็นตัวเลือกที่ใช้งานได้และอาจง่ายกว่ามากสำหรับภาพเคลื่อนไหวพื้นฐาน แต่หากต้องการใช้รูปแบบที่ซับซ้อนขึ้น AnimationWorklet ก็พร้อมช่วยเหลือคุณ