ไทย

สำรวจ Concurrent Mode และ interruptible rendering ของ React เรียนรู้ว่าการเปลี่ยนแปลงครั้งใหญ่นี้ช่วยปรับปรุงประสิทธิภาพ การตอบสนอง และประสบการณ์ผู้ใช้ทั่วโลกได้อย่างไร

React Concurrent Mode: การเรียนรู้ Interruptible Rendering เพื่อประสบการณ์ผู้ใช้ที่เหนือกว่า

ในโลกของการพัฒนา front-end ที่เปลี่ยนแปลงอยู่เสมอ ประสบการณ์ผู้ใช้ (UX) คือสิ่งสำคัญที่สุด ผู้ใช้ทั่วโลกคาดหวังว่าแอปพลิเคชันจะรวดเร็ว ลื่นไหล และตอบสนองได้ดี ไม่ว่าพวกเขาจะใช้อุปกรณ์ใด สภาพเครือข่ายเป็นอย่างไร หรือความซับซ้อนของงานที่ทำอยู่ กลไกการเรนเดอร์แบบดั้งเดิมในไลบรารีอย่าง React มักประสบปัญหาในการตอบสนองความต้องการเหล่านี้ โดยเฉพาะอย่างยิ่งในระหว่างการทำงานที่ใช้ทรัพยากรสูง หรือเมื่อมีการอัปเดตหลายอย่างแย่งชิงความสนใจจากเบราว์เซอร์ นี่คือจุดที่ Concurrent Mode ของ React (ปัจจุบันมักเรียกง่ายๆ ว่า concurrency ใน React) เข้ามามีบทบาท โดยนำเสนอแนวคิดที่ปฏิวัติวงการ นั่นคือ interruptible rendering (การเรนเดอร์ที่ขัดจังหวะได้) บล็อกโพสต์นี้จะเจาะลึกถึงความซับซ้อนของ Concurrent Mode อธิบายว่า interruptible rendering คืออะไร ทำไมมันถึงเป็นตัวเปลี่ยนเกม และคุณจะใช้ประโยชน์จากมันเพื่อสร้างประสบการณ์ผู้ใช้ที่ยอดเยี่ยมสำหรับผู้ใช้ทั่วโลกได้อย่างไร

ทำความเข้าใจข้อจำกัดของการเรนเดอร์แบบดั้งเดิม

ก่อนที่เราจะเจาะลึกถึงความยอดเยี่ยมของ Concurrent Mode สิ่งสำคัญคือต้องเข้าใจความท้าทายที่เกิดจากโมเดลการเรนเดอร์แบบซิงโครนัส (synchronous) ซึ่งเป็นแบบดั้งเดิมที่ React ใช้มาโดยตลอด ในโมเดลแบบซิงโครนัส React จะประมวลผลการอัปเดต UI ทีละรายการในลักษณะที่ปิดกั้น (blocking) ลองนึกภาพแอปพลิเคชันของคุณเป็นทางหลวงเลนเดียว เมื่อมีงานเรนเดอร์เริ่มต้นขึ้น มันจะต้องเดินทางให้เสร็จสิ้นก่อนที่งานอื่นจะเริ่มได้ ซึ่งอาจนำไปสู่ปัญหาหลายอย่างที่ขัดขวาง UX:

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

ขอแนะนำ Concurrent Mode: การเปลี่ยนแปลงครั้งสำคัญ

Concurrent Mode ไม่ใช่ฟีเจอร์ที่คุณ "เปิด" ในความหมายแบบดั้งเดิม แต่เป็นโหมดการทำงานใหม่สำหรับ React ที่เปิดใช้งานคุณสมบัติต่าง ๆ เช่น interruptible rendering หัวใจหลักของ concurrency คือการช่วยให้ React สามารถจัดการงานเรนเดอร์หลายอย่างได้พร้อมกัน และสามารถขัดจังหวะ หยุดชั่วคราว และดำเนินการต่อได้ตามต้องการ สิ่งนี้สำเร็จได้ด้วยตัวจัดตารางเวลา (scheduler) ที่ซับซ้อนซึ่งจัดลำดับความสำคัญของการอัปเดตตามความเร่งด่วนและความสำคัญ

ลองนึกถึงอุปมาอุปไมยเรื่องทางหลวงของเราอีกครั้ง แต่คราวนี้มีหลายเลนและมีการจัดการจราจร Concurrent Mode ได้นำเสนอตัวควบคุมการจราจรอัจฉริยะที่สามารถ:

การเปลี่ยนแปลงพื้นฐานจากการประมวลผลแบบซิงโครนัสทีละอย่าง ไปสู่การจัดการงานแบบอะซิงโครนัสและจัดลำดับความสำคัญนี้ คือหัวใจสำคัญของ interruptible rendering

Interruptible Rendering คืออะไร?

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

แนวคิดสำคัญที่ทำให้ interruptible rendering เป็นไปได้ ประกอบด้วย:

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

คุณสมบัติหลักและวิธีการเปิดใช้งาน Concurrency

Concurrent Mode ปลดล็อกคุณสมบัติอันทรงพลังหลายอย่างที่สร้างขึ้นบนรากฐานของ interruptible rendering มาสำรวจคุณสมบัติที่สำคัญที่สุดบางส่วนกัน:

1. Suspense สำหรับการดึงข้อมูล

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

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

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

ตัวอย่างโค้ด (เพื่อการอธิบาย):

// สมมติว่ามีฟังก์ชัน fetchData ที่คืนค่า Promise
function fetchUserData() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve({ name: 'Alice' });
    }, 2000);
  });
}

// hook สำหรับดึงข้อมูลที่รองรับ Suspense (สมมติ)
function useUserData() {
  const data = fetch(url);
  if (data.status === 'pending') {
    throw new Promise(resolve => {
      // นี่คือสิ่งที่ Suspense ดักจับ
      setTimeout(() => resolve(null), 2000); 
    });
  }
  return data.value;
}

function UserProfile() {
  const userData = useUserData(); // การเรียกนี้อาจทำให้เกิดการ suspend
  return 
Welcome, {userData.name}!
; } function App() { return ( Loading user...
}> ); }

2. การรวมอัปเดตอัตโนมัติ (Automatic Batching)

Batching คือกระบวนการรวมการอัปเดต state หลายรายการให้เป็นการ re-render เพียงครั้งเดียว แต่เดิม React จะทำการ batch เฉพาะการอัปเดตที่เกิดขึ้นภายใน event handlers เท่านั้น การอัปเดตที่เริ่มต้นนอก event handlers (เช่น ภายใน promises หรือ `setTimeout`) จะไม่ถูก batch ซึ่งนำไปสู่การ re-render ที่ไม่จำเป็น

ทำงานร่วมกับ concurrency อย่างไร: ด้วย Concurrent Mode, React จะทำการ batch การอัปเดต state ทั้งหมดโดยอัตโนมัติ ไม่ว่าจะมาจากที่ใดก็ตาม ซึ่งหมายความว่าหากคุณมีการอัปเดต state หลายครั้งที่เกิดขึ้นอย่างรวดเร็ว (เช่น จากการทำงานแบบอะซิงโครนัสหลายอย่างที่เสร็จสิ้น) React จะรวมพวกมันและทำการ re-render เพียงครั้งเดียว ซึ่งช่วยปรับปรุงประสิทธิภาพและลดภาระงานจากการเรนเดอร์หลายรอบ

ตัวอย่าง: สมมติว่าคุณกำลังดึงข้อมูลจาก API สองแห่งที่แตกต่างกัน เมื่อทั้งสองเสร็จสิ้น คุณจะอัปเดต state สองส่วนแยกกัน ใน React เวอร์ชันเก่า นี่อาจทำให้เกิดการ re-render สองครั้ง ใน Concurrent Mode การอัปเดตเหล่านี้จะถูกรวมเข้าด้วยกัน ส่งผลให้เกิดการ re-render เพียงครั้งเดียวที่มีประสิทธิภาพมากขึ้น

3. Transitions

Transitions เป็นแนวคิดใหม่ที่ถูกนำมาใช้เพื่อแยกแยะระหว่างการอัปเดตที่เร่งด่วนและไม่เร่งด่วน นี่คือกลไกหลักสำหรับการเปิดใช้งาน interruptible rendering

การอัปเดตที่เร่งด่วน (Urgent Updates): คือการอัปเดตที่ต้องการการตอบสนองทันที เช่น การพิมพ์ในช่องอินพุต การคลิกปุ่ม หรือการจัดการองค์ประกอบ UI โดยตรง ควรรู้สึกว่าเกิดขึ้นทันที

การอัปเดตแบบ Transition (Transition Updates): คือการอัปเดตที่อาจใช้เวลานานกว่าและไม่ต้องการการตอบสนองทันที ตัวอย่างเช่น การเรนเดอร์หน้าใหม่หลังจากคลิกลิงก์ การกรองรายการขนาดใหญ่ หรือการอัปเดตองค์ประกอบ UI ที่เกี่ยวข้องซึ่งไม่ได้ตอบสนองต่อการคลิกโดยตรง การอัปเดตเหล่านี้สามารถถูกขัดจังหวะได้

ทำงานร่วมกับ concurrency อย่างไร: ด้วยการใช้ `startTransition` API คุณสามารถทำเครื่องหมายการอัปเดต state บางอย่างเป็น transitions ได้ จากนั้นตัวจัดตารางเวลาของ React จะจัดการการอัปเดตเหล่านี้ด้วยลำดับความสำคัญที่ต่ำกว่าและสามารถขัดจังหวะได้หากมีการอัปเดตที่เร่งด่วนกว่าเกิดขึ้น สิ่งนี้ช่วยให้มั่นใจได้ว่าในขณะที่การอัปเดตที่ไม่เร่งด่วน (เช่น การเรนเดอร์รายการขนาดใหญ่) กำลังดำเนินการอยู่ การอัปเดตที่เร่งด่วน (เช่น การพิมพ์ในช่องค้นหา) จะได้รับความสำคัญ ทำให้ UI ยังคงตอบสนองได้ดี

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

ตัวอย่างโค้ด (เพื่อการอธิบาย):

import { useState, useTransition } from 'react';

function SearchResults() {
  const [isPending, startTransition] = useTransition();
  const [query, setQuery] = useState('');
  const [results, setResults] = useState([]);

  const handleQueryChange = (e) => {
    const newQuery = e.target.value;
    setQuery(newQuery);

    // ทำเครื่องหมายการอัปเดตนี้เป็น transition
    startTransition(() => {
      // จำลองการดึงผลลัพธ์ ซึ่งสามารถถูกขัดจังหวะได้
      fetchResults(newQuery).then(res => setResults(res));
    });
  };

  return (
    
{isPending &&
Loading results...
}
    {results.map(item => (
  • {item.name}
  • ))}
); }

4. การบูรณาการกับไลบรารีและ Ecosystem

ประโยชน์ของ Concurrent Mode ไม่ได้จำกัดอยู่แค่ฟีเจอร์หลักของ React แต่ ecosystem ทั้งหมดกำลังปรับตัว ไลบรารีที่ทำงานร่วมกับ React เช่น โซลูชันการกำหนดเส้นทาง (routing) หรือเครื่องมือจัดการ state ก็สามารถใช้ประโยชน์จาก concurrency เพื่อมอบประสบการณ์ที่ราบรื่นยิ่งขึ้นได้เช่นกัน

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

วิธีเปิดใช้งานและใช้คุณสมบัติ Concurrent

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

1. เวอร์ชันของ React

คุณสมบัติ Concurrent มีให้ใช้งานใน React 18 ขึ้นไป ตรวจสอบให้แน่ใจว่าคุณใช้เวอร์ชันที่เข้ากันได้:

npm install react@latest react-dom@latest

2. Root API (`createRoot`)

วิธีหลักในการเลือกใช้คุณสมบัติ concurrent คือการใช้ `createRoot` API ใหม่เมื่อทำการ mount แอปพลิเคชันของคุณ:

// index.js หรือ main.jsx
import ReactDOM from 'react-dom/client';
import App from './App';

const container = document.getElementById('root');
const root = ReactDOM.createRoot(container);
root.render();

การใช้ `createRoot` จะเปิดใช้งานคุณสมบัติ concurrent ทั้งหมดโดยอัตโนมัติ รวมถึง automatic batching, transitions และ Suspense

หมายเหตุ: `ReactDOM.render` API แบบเก่าไม่รองรับคุณสมบัติ concurrent การย้ายไปใช้ `createRoot` เป็นขั้นตอนสำคัญในการปลดล็อก concurrency

3. การใช้งาน Suspense

ตามที่แสดงไว้ก่อนหน้านี้ การใช้งาน Suspense ทำได้โดยการครอบคอมโพเนนต์ที่ทำงานแบบอะซิงโครนัสด้วย <Suspense> และกำหนด fallback prop

แนวทางปฏิบัติที่ดีที่สุด:

4. การใช้ Transitions (`startTransition`)

ระบุการอัปเดต UI ที่ไม่เร่งด่วนและครอบด้วย startTransition

ควรใช้เมื่อใด:

ตัวอย่าง: สำหรับการกรองที่ซับซ้อนของชุดข้อมูลขนาดใหญ่ที่แสดงในตาราง คุณจะตั้งค่า state ของคำค้นหาตัวกรองแล้วเรียก `startTransition` สำหรับการกรองและการ re-render แถวตารางจริง สิ่งนี้ช่วยให้มั่นใจได้ว่าหากผู้ใช้เปลี่ยนเกณฑ์การกรองอย่างรวดเร็วอีกครั้ง การดำเนินการกรองก่อนหน้าสามารถถูกขัดจังหวะได้อย่างปลอดภัย

ประโยชน์ของ Interruptible Rendering สำหรับผู้ใช้ทั่วโลก

ข้อดีของ interruptible rendering และ Concurrent Mode จะยิ่งเด่นชัดขึ้นเมื่อพิจารณาฐานผู้ใช้ทั่วโลกที่มีเงื่อนไขเครือข่ายและความสามารถของอุปกรณ์ที่หลากหลาย

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

ความท้าทายและข้อควรพิจารณาที่อาจเกิดขึ้น

แม้ว่า Concurrent Mode จะมีข้อดีมากมาย แต่การนำไปใช้ก็มีช่วงการเรียนรู้และข้อควรพิจารณาบางประการ:

อนาคตของ React Concurrency

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

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

สรุป

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

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

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

ประเด็นสำคัญ:

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