เพิ่มประสิทธิภาพงานที่ใช้เวลานาน

มีคนบอกว่า "อย่าบล็อกเทรดหลัก" และ "แบ่งงานที่ใช้เวลานาน" แต่การทำเช่นนั้นหมายความว่าอย่างไร

คำแนะนำทั่วไปในการทำให้แอป JavaScript ทำงานได้เร็วมักจะเป็นไปตามคำแนะนำต่อไปนี้

  • "อย่าบล็อกชุดข้อความหลัก"
  • "แบ่งงานที่ใช้เวลานานออกไป"

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

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

งานคืออะไร

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

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

งานที่เชื่อมโยงกับ JavaScript ส่งผลต่อประสิทธิภาพใน 2 วิธีต่อไปนี้

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

ทั้งหมดนี้เกิดขึ้นในเทรดหลัก ยกเว้นโปรแกรมทำงานบนเว็บและ API ที่คล้ายกัน

เทรดหลักคืออะไร

เทรดหลักคือที่ที่งานส่วนใหญ่ทำงานในเบราว์เซอร์และเป็นที่ที่เรียกใช้ JavaScript เกือบทั้งหมดที่คุณเขียน

โดยเทรดหลักจะประมวลผลงานได้ครั้งละ 1 รายการเท่านั้น งานที่ใช้เวลานานกว่า 50 มิลลิวินาทีถือเป็นงานที่ใช้เวลานาน สำหรับงานที่มีความยาวเกิน 50 มิลลิวินาที เวลารวมของงานลบด้วย 50 มิลลิวินาทีจะเรียกว่าระยะเวลาการบล็อกของงาน

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

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

เพื่อป้องกันไม่ให้ชุดข้อความหลักถูกบล็อกนานเกินไป ให้แบ่งงานที่ใช้เวลานานเป็นงานย่อยๆ หลายรายการ

งานเดียวที่ใช้เวลานานกับงานเดียวกัน โดยแบ่งงานออกเป็นงานที่สั้นลง งานที่ยาวคือสี่เหลี่ยมผืนผ้าใหญ่ 1 รูป ขณะที่งานที่แบ่งออกเป็นส่วนๆ คือช่องขนาดเล็ก 5 กล่องซึ่งมีความกว้างรวมกันเท่ากับงานแบบยาว
การแสดงภาพงานที่ใช้เวลานานงานเดียวเทียบกับงานเดียวกันนั้น โดยจะแบ่งออกเป็นงานสั้นๆ 5 งาน

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

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

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

ตอนนี้คุณรู้ถึงความสำคัญของการแบ่งงานแล้ว ต่อไปก็ดูวิธีทำใน JavaScript ได้เลย

กลยุทธ์การจัดการงาน

คำแนะนำทั่วไปอย่างหนึ่งในสถาปัตยกรรมซอฟต์แวร์คือการแบ่งงานออกเป็นฟังก์ชันย่อยๆ ดังนี้

function saveSettings () {
  validateForm();
  showSpinner();
  saveToDatabase();
  updateUI();
  sendAnalytics();
}

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

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

อย่างไรก็ตาม ปัญหาที่อาจเกิดขึ้นคือ JavaScript ไม่เรียกใช้แต่ละฟังก์ชันเหล่านี้เป็นงานแยกจากกัน เนื่องจากมีการเรียกใช้งานภายในฟังก์ชัน saveSettings() ซึ่งหมายความว่าฟังก์ชันทั้ง 5 รายการจะทำงานเดียวกัน

ฟังก์ชัน SaveSettings ตามที่แสดงในเครื่องมือสร้างโปรไฟล์ประสิทธิภาพของ Chrome แม้ว่าฟังก์ชันระดับบนสุดจะเรียกใช้ฟังก์ชันอื่นอีก 5 ฟังก์ชัน แต่งานทั้งหมดจะเกิดขึ้นในงานเดียวที่ใช้เวลานานซึ่งจะบล็อกเทรดหลัก
ฟังก์ชันเดียว saveSettings() ที่เรียกใช้ฟังก์ชัน 5 รายการ โดยงานดังกล่าวจะเป็นส่วนหนึ่งของงานที่มีขนาดใหญ่เพียงงานเดียว

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

เลื่อนการเรียกใช้โค้ดด้วยตนเอง

วิธีหนึ่งที่นักพัฒนาแอปใช้เพื่อแบ่งงานออกเป็นงานย่อยๆ นั้นเกี่ยวข้องกับ setTimeout() คุณจะส่งฟังก์ชันไปยัง setTimeout() โดยใช้เทคนิคนี้ การดำเนินการนี้จะเลื่อนการเรียกใช้ Callback ไปยังงานแยกต่างหาก แม้ว่าคุณจะระบุระยะหมดเวลาเป็น 0 ก็ตาม

function saveSettings () {
  // Do critical work that is user-visible:
  validateForm();
  showSpinner();
  updateUI();

  // Defer work that isn't user-visible to a separate task:
  setTimeout(() => {
    saveToDatabase();
    sendAnalytics();
  }, 0);
}

วิธีนี้เรียกว่าผลตอบแทน และเหมาะสำหรับชุดฟังก์ชันที่จำเป็นต้องทำงานตามลำดับ

อย่างไรก็ตาม โค้ดของคุณอาจไม่ได้มีการจัดระเบียบในลักษณะนี้เสมอไป เช่น คุณอาจมีข้อมูลจํานวนมากที่ต้องประมวลผลแบบวนซ้ำ และงานนั้นอาจใช้เวลานานมากหากมีการทำซ้ำหลายครั้ง

function processData () {
  for (const item of largeDataArray) {
    // Process the individual item here.
  }
}

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

ใช้ async/await เพื่อสร้างจุดผลตอบแทน

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

ตามที่อธิบายไว้ก่อนหน้านี้ คุณใช้ setTimeout เพื่อแสดงผลไปยังเทรดหลักได้ แต่เพื่อความสะดวกและการอ่านจะง่ายขึ้น คุณสามารถโทรหา setTimeout ภายใน Promise และส่งเมธอด resolve เป็น Callback ได้

function yieldToMain () {
  return new Promise(resolve => {
    setTimeout(resolve, 0);
  });
}

ประโยชน์ของฟังก์ชัน yieldToMain() คือคุณสามารถawaitในฟังก์ชัน async ใดก็ได้ จากตัวอย่างก่อนหน้านี้ คุณสามารถสร้างอาร์เรย์ของฟังก์ชันที่จะเรียกใช้ และแสดงผลไปยังเทรดหลักหลังจากที่เรียกใช้แต่ละครั้งได้

async function saveSettings () {
  // Create an array of functions to run:
  const tasks = [
    validateForm,
    showSpinner,
    saveToDatabase,
    updateUI,
    sendAnalytics
  ]

  // Loop over the tasks:
  while (tasks.length > 0) {
    // Shift the first task off the tasks array:
    const task = tasks.shift();

    // Run the task:
    task();

    // Yield to the main thread:
    await yieldToMain();
  }
}

ผลที่ได้คือตอนนี้งานที่เคยเป็นโมโนลิธถูกแยกออกเป็นงานย่อยๆ

ฟังก์ชัน SaveSettings เดียวกันกับที่แสดงในเครื่องมือสร้างโปรไฟล์ประสิทธิภาพของ Chrome โดยมีเพียงผลตอบแทนเท่านั้น ผลที่ได้คืองานเดี่ยวๆ ที่เคยถูกแบ่งออกเป็น 5 งาน คือ 1 งานสำหรับแต่ละหน้าที่
ตอนนี้ฟังก์ชัน saveSettings() จะเรียกใช้ฟังก์ชันย่อยเป็นงานแยกต่างหาก

API เครื่องจัดตารางเวลาโดยเฉพาะ

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

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

การรองรับเบราว์เซอร์

  • 94
  • 94
  • x

แหล่งที่มา

API เครื่องจัดตารางเวลามีฟังก์ชัน postTask() ซึ่งช่วยให้กำหนดเวลางานได้ละเอียดยิ่งขึ้นและเป็นวิธีหนึ่งในการช่วยเบราว์เซอร์จัดลำดับความสำคัญของงานเพื่อให้งานที่มีลำดับความสำคัญต่ำส่งกลับไปยังเทรดหลัก postTask() ใช้การสัญญาและยอมรับการตั้งค่า 1 ใน 3 รายการของ priority ดังนี้

  • 'background' สำหรับงานที่มีลำดับความสำคัญต่ำสุด
  • 'user-visible' สำหรับงานที่มีลำดับความสำคัญปานกลาง ตัวเลือกนี้จะเป็นค่าเริ่มต้นหากไม่ได้ตั้งค่า priority ไว้
  • 'user-blocking'สำหรับงานสำคัญที่จำเป็นต้องเรียกใช้ในลำดับความสำคัญสูง

ลองดูโค้ดต่อไปนี้เป็นตัวอย่าง ซึ่ง API ของ postTask() ใช้เพื่อเรียกใช้งาน 3 รายการที่มีลำดับความสำคัญสูงสุดเท่าที่จะเป็นไปได้ และงานที่มีลำดับความสำคัญต่ำสุดอีก 2 งาน

function saveSettings () {
  // Validate the form at high priority
  scheduler.postTask(validateForm, {priority: 'user-blocking'});

  // Show the spinner at high priority:
  scheduler.postTask(showSpinner, {priority: 'user-blocking'});

  // Update the database in the background:
  scheduler.postTask(saveToDatabase, {priority: 'background'});

  // Update the user interface at high priority:
  scheduler.postTask(updateUI, {priority: 'user-blocking'});

  // Send analytics data in the background:
  scheduler.postTask(sendAnalytics, {priority: 'background'});
};

ในส่วนนี้ ระบบจะกำหนดเวลาของงานตามลำดับความสำคัญโดยให้งานที่มีลำดับความสำคัญของเบราว์เซอร์ เช่น การโต้ตอบของผู้ใช้ ทำงานได้ในระหว่างที่จำเป็น

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

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

ผลตอบแทนในตัวที่มาพร้อมกับความต่อเนื่องโดยใช้ scheduler.yield() API ที่กำลังจะเปิดตัว

สิ่งหนึ่งที่เสนอให้เพิ่ม API เครื่องจัดตารางเวลาคือ scheduler.yield() ซึ่งเป็น API ที่ออกแบบมาเพื่อผลตอบแทนต่อเทรดหลักในเบราว์เซอร์โดยเฉพาะ การใช้งานจะคล้ายกับฟังก์ชัน yieldToMain() ที่แสดงก่อนหน้านี้ในคู่มือนี้

async function saveSettings () {
  // Create an array of functions to run:
  const tasks = [
    validateForm,
    showSpinner,
    saveToDatabase,
    updateUI,
    sendAnalytics
  ]

  // Loop over the tasks:
  while (tasks.length > 0) {
    // Shift the first task off the tasks array:
    const task = tasks.shift();

    // Run the task:
    task();

    // Yield to the main thread with the scheduler
    // API's own yielding mechanism:
    await scheduler.yield();
  }
}

คุ้นเคยกับโค้ดนี้เป็นส่วนใหญ่ แต่จะใช้ await scheduler.yield() แทนการใช้ yieldToMain()

แผนภาพ 3 ภาพแสดงงานที่ไม่มีผลตอบแทน ไม่เกี่ยวเนื่อง และไม่หยุดหย่อน แม้จะไม่ต้องผลตอบแทน ก็มีงานยาวๆ อยู่ เมื่อผลตอบแทน งานจะมีมากขึ้นในระยะสั้น แต่ก็อาจถูกขัดจังหวะโดยงานอื่นๆ ที่ไม่เกี่ยวข้อง เมื่อได้ผลตอบแทนและความต่อเนื่อง จะมีงานอื่นๆ ที่สั้นลง แต่ลำดับการดำเนินการของมันจะยังคงอยู่
เมื่อคุณใช้ scheduler.yield() การดำเนินการของงานจะกลับมาที่จุดเดิมแม้ว่าจะเลยจุดผลตอบแทนแล้วก็ตาม

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

การใช้ scheduler.postTask() กับ priority: 'user-blocking' ก็มีแนวโน้มสูงที่จะดำเนินการอย่างต่อเนื่องเนื่องจากลำดับความสำคัญ user-blocking สูง จึงอาจใช้แนวทางนี้เป็นทางเลือกได้ในระหว่างนี้

การใช้ setTimeout() (หรือ scheduler.postTask() ที่มี priority: 'user-visibile' หรือไม่ระบุ priority อย่างชัดเจน) จะกำหนดเวลางานไว้ที่ด้านหลังของคิวเพื่อให้งานอื่นๆ ที่รอดำเนินการทำงานก่อนการทำงานต่อเนื่องได้

ไม่ใช้ isInputPending()

การรองรับเบราว์เซอร์

  • 87
  • 87
  • x
  • x

isInputPending() API ช่วยในการตรวจสอบว่าผู้ใช้ได้พยายามโต้ตอบกับหน้าเว็บหรือไม่ และจะตอบกลับเมื่อมีอินพุตรอดำเนินการเท่านั้น

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

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

  • isInputPending() อาจแสดงผล false อย่างไม่ถูกต้องแม้ว่าผู้ใช้จะโต้ตอบในบางสถานการณ์
  • อินพุตไม่ได้เป็นเพียงกรณีเดียวที่งานควรแสดงผล ภาพเคลื่อนไหวและการอัปเดตอินเทอร์เฟซผู้ใช้ตามปกติอื่นๆ ก็มีความสำคัญไม่แพ้กันเพื่อมอบหน้าเว็บที่ปรับเปลี่ยนตามอุปกรณ์
  • ตั้งแต่นั้นเป็นต้นมา เราได้เปิดตัว API ผลตอบแทนที่ครอบคลุมมากขึ้น ซึ่งช่วยแก้ไขปัญหาเกี่ยวกับผลตอบแทน เช่น scheduler.postTask() และ scheduler.yield()

บทสรุป

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

  • ให้เทรดหลักสำหรับงานสำคัญที่แสดงต่อผู้ใช้
  • จัดลำดับความสำคัญของงานด้วย postTask()
  • พิจารณาทดลองใช้ scheduler.yield()
  • สุดท้าย ให้ทำงานในส่วนต่างๆ ให้น้อยที่สุดเท่าที่จะทำได้

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

ขอขอบคุณ Philip Walton ที่ช่วยตรวจสอบคู่มือนี้ทางเทคนิค

ภาพขนาดย่อที่มาจาก Unwash โดยได้รับความเอื้อเฟื้อจาก Amirali Mirhashemian