คู่มือฉบับสมบูรณ์เพื่อปรับปรุงประสิทธิภาพแอปพลิเคชัน React โดยการป้องกันการเรนเดอร์ซ้ำที่ไม่จำเป็น เรียนรู้เทคนิคต่างๆ เช่น memoization, PureComponent, shouldComponentUpdate และอื่นๆ เพื่อประสิทธิภาพที่ดีขึ้น
การปรับปรุงประสิทธิภาพการเรนเดอร์ของ React: การป้องกันการเรนเดอร์ซ้ำที่ไม่จำเป็นอย่างเชี่ยวชาญ
React ซึ่งเป็นไลบรารี JavaScript ที่ทรงพลังสำหรับการสร้างส่วนต่อประสานกับผู้ใช้ บางครั้งอาจประสบปัญหาคอขวดด้านประสิทธิภาพเนื่องจากการเรนเดอร์ซ้ำที่มากเกินไปหรือไม่จำเป็น ในแอปพลิเคชันที่ซับซ้อนซึ่งมีคอมโพเนนต์จำนวนมาก การเรนเดอร์ซ้ำเหล่านี้อาจทำให้ประสิทธิภาพลดลงอย่างมาก ส่งผลให้ประสบการณ์ของผู้ใช้ช้าลง คู่มือนี้จะให้ภาพรวมที่ครอบคลุมเกี่ยวกับเทคนิคในการป้องกันการเรนเดอร์ซ้ำที่ไม่จำเป็นใน React เพื่อให้แน่ใจว่าแอปพลิเคชันของคุณรวดเร็ว มีประสิทธิภาพ และตอบสนองได้ดีสำหรับผู้ใช้ทั่วโลก
ทำความเข้าใจการเรนเดอร์ซ้ำใน React
ก่อนที่จะลงลึกในเทคนิคการปรับปรุงประสิทธิภาพ สิ่งสำคัญคือต้องเข้าใจว่ากระบวนการเรนเดอร์ของ React ทำงานอย่างไร เมื่อ state หรือ props ของคอมโพเนนต์เปลี่ยนแปลง React จะกระตุ้นให้เกิดการเรนเดอร์ซ้ำของคอมโพเนนต์นั้นและคอมโพเนนต์ลูก กระบวนการนี้เกี่ยวข้องกับการอัปเดต Virtual DOM และเปรียบเทียบกับเวอร์ชันก่อนหน้าเพื่อกำหนดชุดการเปลี่ยนแปลงที่น้อยที่สุดที่จะนำไปใช้กับ DOM จริง
อย่างไรก็ตาม ไม่ใช่ทุกการเปลี่ยนแปลงของ state หรือ prop จะจำเป็นต้องมีการอัปเดต DOM หาก Virtual DOM ใหม่เหมือนกับเวอร์ชันก่อนหน้า การเรนเดอร์ซ้ำนั้นก็เป็นการสิ้นเปลืองทรัพยากรโดยเปล่าประโยชน์ การเรนเดอร์ซ้ำที่ไม่จำเป็นเหล่านี้ใช้ทรัพยากร CPU อันมีค่าและอาจนำไปสู่ปัญหาด้านประสิทธิภาพ โดยเฉพาะอย่างยิ่งในแอปพลิเคชันที่มีโครงสร้างคอมโพเนนต์ที่ซับซ้อน
การระบุการเรนเดอร์ซ้ำที่ไม่จำเป็น
ขั้นตอนแรกในการปรับปรุงประสิทธิภาพการเรนเดอร์คือการระบุว่ามันเกิดขึ้นที่ไหน React มีเครื่องมือหลายอย่างที่จะช่วยคุณในเรื่องนี้:
1. React Profiler
React Profiler ซึ่งมีอยู่ในส่วนขยาย React DevTools สำหรับ Chrome และ Firefox ช่วยให้คุณสามารถบันทึกและวิเคราะห์ประสิทธิภาพของคอมโพเนนต์ React ของคุณได้ มันให้ข้อมูลเชิงลึกว่าคอมโพเนนต์ใดกำลังเรนเดอร์ซ้ำ ใช้เวลานานเท่าใดในการเรนเดอร์ และทำไมถึงเรนเดอร์ซ้ำ
ในการใช้ Profiler เพียงแค่เปิดใช้งานปุ่ม "Record" ใน DevTools และโต้ตอบกับแอปพลิเคชันของคุณ หลังจากบันทึกแล้ว Profiler จะแสดงแผนภูมิเปลวไฟ (flame chart) ที่แสดงภาพโครงสร้างคอมโพเนนต์และเวลาในการเรนเดอร์ คอมโพเนนต์ที่ใช้เวลาเรนเดอร์นานหรือเรนเดอร์ซ้ำบ่อยๆ คือเป้าหมายหลักในการปรับปรุงประสิทธิภาพ
2. Why Did You Render?
"Why Did You Render?" เป็นไลบรารีที่แก้ไข React เพื่อแจ้งเตือนคุณเกี่ยวกับการเรนเดอร์ซ้ำที่อาจไม่จำเป็นโดยการบันทึก props ที่เฉพาะเจาะจงซึ่งเป็นสาเหตุของการเรนเดอร์ซ้ำลงในคอนโซล สิ่งนี้มีประโยชน์อย่างมากในการระบุสาเหตุที่แท้จริงของปัญหาการเรนเดอร์ซ้ำ
ในการใช้ "Why Did You Render?" ให้ติดตั้งเป็น dependency สำหรับการพัฒนา:
npm install @welldone-software/why-did-you-render --save-dev
จากนั้น นำเข้าสู่ไฟล์เริ่มต้นของแอปพลิเคชันของคุณ (เช่น index.js):
import whyDidYouRender from '@welldone-software/why-did-you-render';
if (process.env.NODE_ENV === 'development') {
whyDidYouRender(React, {
include: [/.*/]
});
}
โค้ดนี้จะเปิดใช้งาน "Why Did You Render?" ในโหมดพัฒนาและบันทึกข้อมูลเกี่ยวกับการเรนเดอร์ซ้ำที่อาจไม่จำเป็นลงในคอนโซล
3. Console.log Statements
เทคนิคง่ายๆ แต่ได้ผลคือการเพิ่มคำสั่ง console.log
ภายในเมธอด render
ของคอมโพเนนต์ของคุณ (หรือในส่วน body ของ functional component) เพื่อติดตามว่าเมื่อใดที่มันกำลังเรนเดอร์ซ้ำ แม้ว่าจะไม่ซับซ้อนเท่า Profiler หรือ "Why Did You Render?" แต่วิธีนี้สามารถช่วยชี้ให้เห็นคอมโพเนนต์ที่เรนเดอร์ซ้ำบ่อยกว่าที่คาดไว้ได้อย่างรวดเร็ว
เทคนิคในการป้องกันการเรนเดอร์ซ้ำที่ไม่จำเป็น
เมื่อคุณระบุคอมโพเนนต์ที่ก่อให้เกิดปัญหาด้านประสิทธิภาพได้แล้ว คุณสามารถใช้เทคนิคต่างๆ เพื่อป้องกันการเรนเดอร์ซ้ำที่ไม่จำเป็นได้:
1. Memoization
Memoization เป็นเทคนิคการปรับปรุงประสิทธิภาพที่ทรงพลังซึ่งเกี่ยวข้องกับการแคชผลลัพธ์ของการเรียกใช้ฟังก์ชันที่สิ้นเปลืองทรัพยากรและส่งคืนผลลัพธ์ที่แคชไว้เมื่อมีการใช้ input เดิมอีกครั้ง ใน React สามารถใช้ memoization เพื่อป้องกันไม่ให้คอมโพเนนต์เรนเดอร์ซ้ำหาก props ของมันไม่มีการเปลี่ยนแปลง
ก. React.memo
React.memo
เป็น higher-order component ที่ทำการ memoize ให้กับ functional component มันจะเปรียบเทียบ props ปัจจุบันกับ props ก่อนหน้าแบบตื้น (shallow comparison) และจะเรนเดอร์คอมโพเนนต์ซ้ำก็ต่อเมื่อ props มีการเปลี่ยนแปลงเท่านั้น
ตัวอย่าง:
const MyComponent = React.memo(function MyComponent(props) {
return <div>{props.data}</div>;
});
โดยค่าเริ่มต้น React.memo
จะทำการเปรียบเทียบ props ทั้งหมดแบบตื้น คุณสามารถระบุฟังก์ชันการเปรียบเทียบแบบกำหนดเองเป็นอาร์กิวเมนต์ที่สองของ React.memo
เพื่อปรับแต่งตรรกะการเปรียบเทียบได้
const MyComponent = React.memo(function MyComponent(props) {
return <div>{props.data}</div>;
}, (prevProps, nextProps) => {
// คืนค่า true ถ้า props เท่ากัน, false ถ้า props ต่างกัน
return prevProps.data === nextProps.data;
});
ข. useMemo
useMemo
เป็น React hook ที่ทำการ memoize ผลลัพธ์ของการคำนวณ มันรับฟังก์ชันและอาร์เรย์ของ dependencies เป็นอาร์กิวเมนต์ ฟังก์ชันจะถูกเรียกใช้ใหม่ก็ต่อเมื่อ dependencies ตัวใดตัวหนึ่งมีการเปลี่ยนแปลง และผลลัพธ์ที่ memoize ไว้จะถูกส่งคืนในการเรนเดอร์ครั้งถัดๆ ไป
useMemo
มีประโยชน์อย่างยิ่งสำหรับการ memoize การคำนวณที่สิ้นเปลืองทรัพยากร หรือการสร้างการอ้างอิงที่คงที่ไปยังอ็อบเจกต์หรือฟังก์ชันที่ส่งเป็น props ไปยังคอมโพเนนต์ลูก
ตัวอย่าง:
const memoizedValue = useMemo(() => {
// ทำการคำนวณที่สิ้นเปลืองทรัพยากรที่นี่
return computeExpensiveValue(a, b);
}, [a, b]);
2. PureComponent
PureComponent
เป็นคลาสพื้นฐานสำหรับคอมโพเนนต์ React ที่มีการเปรียบเทียบ props และ state แบบตื้นในเมธอด shouldComponentUpdate
ของมัน หาก props และ state ไม่มีการเปลี่ยนแปลง คอมโพเนนต์จะไม่เรนเดอร์ซ้ำ
PureComponent
เป็นตัวเลือกที่ดีสำหรับคอมโพเนนต์ที่ขึ้นอยู่กับ props และ state ของมันในการเรนเดอร์เท่านั้น และไม่ได้พึ่งพา context หรือปัจจัยภายนอกอื่นๆ
ตัวอย่าง:
class MyComponent extends React.PureComponent {
render() {
return <div>{this.props.data}</div>;
}
}
หมายเหตุสำคัญ: PureComponent
และ React.memo
ทำการเปรียบเทียบแบบตื้น (shallow comparison) ซึ่งหมายความว่าพวกมันจะเปรียบเทียบเพียงการอ้างอิงของอ็อบเจกต์และอาร์เรย์เท่านั้น ไม่ใช่เนื้อหาภายใน หาก props หรือ state ของคุณมีอ็อบเจกต์หรืออาร์เรย์ที่ซ้อนกันอยู่ คุณอาจต้องใช้เทคนิคเช่น immutability เพื่อให้แน่ใจว่าการเปลี่ยนแปลงจะถูกตรวจจับได้อย่างถูกต้อง
3. shouldComponentUpdate
เมธอด lifecycle shouldComponentUpdate
ช่วยให้คุณสามารถควบคุมได้ด้วยตนเองว่าคอมโพเนนต์ควรจะเรนเดอร์ซ้ำหรือไม่ เมธอดนี้จะได้รับ next props และ next state เป็นอาร์กิวเมนต์ และควรคืนค่า true
หากคอมโพเนนต์ควรเรนเดอร์ซ้ำ หรือ false
หากไม่ควร
แม้ว่า shouldComponentUpdate
จะให้การควบคุมการเรนเดอร์ซ้ำได้มากที่สุด แต่ก็ต้องใช้ความพยายามด้วยตนเองมากที่สุดเช่นกัน คุณต้องเปรียบเทียบ props และ state ที่เกี่ยวข้องอย่างระมัดระวังเพื่อตัดสินว่าจำเป็นต้องเรนเดอร์ซ้ำหรือไม่
ตัวอย่าง:
class MyComponent extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
// เปรียบเทียบ props และ state ที่นี่
return nextProps.data !== this.props.data || nextState.count !== this.state.count;
}
render() {
return <div>{this.props.data}</div>;
}
}
ข้อควรระวัง: การใช้งาน shouldComponentUpdate
ที่ไม่ถูกต้องอาจนำไปสู่พฤติกรรมที่ไม่คาดคิดและบักได้ ตรวจสอบให้แน่ใจว่าตรรกะการเปรียบเทียบของคุณครอบคลุมและคำนึงถึงปัจจัยที่เกี่ยวข้องทั้งหมด
4. useCallback
useCallback
เป็น React hook ที่ทำการ memoize คำจำกัดความของฟังก์ชัน มันรับฟังก์ชันและอาร์เรย์ของ dependencies เป็นอาร์กิวเมนต์ ฟังก์ชันจะถูกกำหนดใหม่ก็ต่อเมื่อ dependencies ตัวใดตัวหนึ่งมีการเปลี่ยนแปลง และฟังก์ชันที่ memoize ไว้จะถูกส่งคืนในการเรนเดอร์ครั้งถัดๆ ไป
useCallback
มีประโยชน์อย่างยิ่งสำหรับการส่งผ่านฟังก์ชันเป็น props ไปยังคอมโพเนนต์ลูกที่ใช้ React.memo
หรือ PureComponent
โดยการ memoize ฟังก์ชัน คุณสามารถป้องกันไม่ให้คอมโพเนนต์ลูกเรนเดอร์ซ้ำโดยไม่จำเป็นเมื่อคอมโพเนนต์แม่เรนเดอร์ซ้ำ
ตัวอย่าง:
const handleClick = useCallback(() => {
// จัดการเหตุการณ์การคลิก
console.log('Clicked!');
}, []);
5. Immutability
Immutability เป็นแนวคิดการเขียนโปรแกรมที่เกี่ยวข้องกับการปฏิบัติต่อข้อมูลว่าไม่สามารถเปลี่ยนแปลงได้ หมายความว่าข้อมูลนั้นไม่สามารถเปลี่ยนแปลงได้หลังจากที่ถูกสร้างขึ้น เมื่อทำงานกับข้อมูลที่ไม่เปลี่ยนรูป การแก้ไขใดๆ จะส่งผลให้เกิดการสร้างโครงสร้างข้อมูลใหม่แทนที่จะแก้ไขโครงสร้างข้อมูลที่มีอยู่เดิม
Immutability มีความสำคัญอย่างยิ่งต่อการปรับปรุงประสิทธิภาพการเรนเดอร์ของ React เพราะมันช่วยให้ React สามารถตรวจจับการเปลี่ยนแปลงใน props และ state ได้อย่างง่ายดายโดยใช้การเปรียบเทียบแบบตื้น หากคุณแก้ไขอ็อบเจกต์หรืออาร์เรย์โดยตรง React จะไม่สามารถตรวจจับการเปลี่ยนแปลงได้เนื่องจากการอ้างอิงไปยังอ็อบเจกต์หรืออาร์เรย์นั้นยังคงเหมือนเดิม
คุณสามารถใช้ไลบรารีอย่าง Immutable.js หรือ Immer เพื่อทำงานกับข้อมูลที่ไม่เปลี่ยนรูปใน React ไลบรารีเหล่านี้มีโครงสร้างข้อมูลและฟังก์ชันที่ช่วยให้การสร้างและจัดการข้อมูลที่ไม่เปลี่ยนรูปง่ายขึ้น
ตัวอย่างการใช้ Immer:
import { useImmer } from 'use-immer';
function MyComponent() {
const [data, setData] = useImmer({
name: 'John',
age: 30
});
const updateName = () => {
setData(draft => {
draft.name = 'Jane';
});
};
return (
<div>
<p>Name: {data.name}</p>
<button onClick={updateName}>Update Name</button>
</div>
);
}
6. การแบ่งโค้ด (Code Splitting) และการโหลดแบบ Lazy (Lazy Loading)
การแบ่งโค้ดเป็นเทคนิคที่เกี่ยวข้องกับการแบ่งโค้ดของแอปพลิเคชันของคุณออกเป็นส่วนเล็กๆ ที่สามารถโหลดได้ตามความต้องการ สิ่งนี้สามารถปรับปรุงเวลาในการโหลดเริ่มต้นของแอปพลิเคชันของคุณได้อย่างมาก เนื่องจากเบราว์เซอร์ต้องการดาวน์โหลดเฉพาะโค้ดที่จำเป็นสำหรับมุมมองปัจจุบันเท่านั้น
React มีการสนับสนุนในตัวสำหรับการแบ่งโค้ดโดยใช้ฟังก์ชัน React.lazy
และคอมโพเนนต์ Suspense
React.lazy
ช่วยให้คุณสามารถนำเข้าคอมโพเนนต์แบบไดนามิก ในขณะที่ Suspense
ช่วยให้คุณสามารถแสดง UI สำรองในขณะที่คอมโพเนนต์กำลังโหลด
ตัวอย่าง:
import React, { Suspense } from 'react';
const MyComponent = React.lazy(() => import('./MyComponent'));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<MyComponent />
</Suspense>
);
}
7. การใช้ Keys อย่างมีประสิทธิภาพ
เมื่อเรนเดอร์รายการขององค์ประกอบใน React สิ่งสำคัญคือต้องระบุ key ที่ไม่ซ้ำกันให้กับแต่ละองค์ประกอบ Keys ช่วยให้ React ระบุได้ว่าองค์ประกอบใดมีการเปลี่ยนแปลง ถูกเพิ่ม หรือถูกลบออก ทำให้สามารถอัปเดต DOM ได้อย่างมีประสิทธิภาพ
หลีกเลี่ยงการใช้ดัชนีของอาร์เรย์เป็น key เนื่องจากอาจเปลี่ยนแปลงได้เมื่อลำดับขององค์ประกอบในอาร์เรย์เปลี่ยนแปลง ซึ่งนำไปสู่การเรนเดอร์ซ้ำที่ไม่จำเป็น ให้ใช้ตัวระบุที่ไม่ซ้ำกันสำหรับแต่ละองค์ประกอบแทน เช่น ID จากฐานข้อมูลหรือ UUID ที่สร้างขึ้น
8. การปรับปรุงประสิทธิภาพการใช้ Context
React Context เป็นวิธีการแชร์ข้อมูลระหว่างคอมโพเนนต์โดยไม่ต้องส่ง props ผ่านทุกระดับของโครงสร้างคอมโพเนนต์อย่างชัดเจน อย่างไรก็ตาม การใช้ Context มากเกินไปอาจนำไปสู่ปัญหาด้านประสิทธิภาพ เนื่องจากคอมโพเนนต์ใดๆ ที่ใช้ Context จะเรนเดอร์ซ้ำทุกครั้งที่ค่า Context เปลี่ยนแปลง
เพื่อปรับปรุงประสิทธิภาพการใช้ Context ให้พิจารณากลยุทธ์เหล่านี้:
- ใช้ Context หลายๆ อันที่มีขนาดเล็กกว่า: แทนที่จะใช้ Context ขนาดใหญ่เพียงอันเดียวเพื่อเก็บข้อมูลทั้งหมดของแอปพลิเคชัน ให้แบ่งออกเป็น Context ที่เล็กกว่าและเฉพาะเจาะจงมากขึ้น ซึ่งจะช่วยลดจำนวนคอมโพเนนต์ที่ต้องเรนเดอร์ซ้ำเมื่อค่า Context ที่เฉพาะเจาะจงมีการเปลี่ยนแปลง
- Memoize ค่า Context: ใช้
useMemo
เพื่อ memoize ค่าที่จัดเตรียมโดย Context provider ซึ่งจะช่วยป้องกันการเรนเดอร์ซ้ำที่ไม่จำเป็นของผู้บริโภค Context หากค่าไม่ได้เปลี่ยนแปลงจริงๆ - พิจารณาทางเลือกอื่นแทน Context: ในบางกรณี โซลูชันการจัดการ state อื่นๆ เช่น Redux หรือ Zustand อาจเหมาะสมกว่า Context โดยเฉพาะสำหรับแอปพลิเคชันที่ซับซ้อนซึ่งมีคอมโพเนนต์จำนวนมากและมีการอัปเดต state บ่อยครั้ง
ข้อควรพิจารณาสำหรับผู้ใช้ทั่วโลก
เมื่อปรับปรุงประสิทธิภาพแอปพลิเคชัน React สำหรับผู้ชมทั่วโลก สิ่งสำคัญคือต้องพิจารณาปัจจัยต่อไปนี้:
- ความเร็วเครือข่ายที่แตกต่างกัน: ผู้ใช้ในภูมิภาคต่างๆ อาจมีความเร็วเครือข่ายที่แตกต่างกันอย่างมาก ปรับปรุงแอปพลิเคชันของคุณเพื่อลดปริมาณข้อมูลที่ต้องดาวน์โหลดและถ่ายโอนผ่านเครือข่าย พิจารณาใช้เทคนิคต่างๆ เช่น การปรับปรุงประสิทธิภาพรูปภาพ การแบ่งโค้ด และการโหลดแบบ lazy
- ความสามารถของอุปกรณ์: ผู้ใช้อาจเข้าถึงแอปพลิเคชันของคุณบนอุปกรณ์ที่หลากหลาย ตั้งแต่สมาร์ทโฟนระดับไฮเอนด์ไปจนถึงอุปกรณ์รุ่นเก่าที่มีประสิทธิภาพน้อยกว่า ปรับปรุงแอปพลิเคชันของคุณให้ทำงานได้ดีบนอุปกรณ์หลากหลายประเภท พิจารณาใช้เทคนิคต่างๆ เช่น การออกแบบที่ตอบสนอง (responsive design) รูปภาพที่ปรับเปลี่ยนได้ และการทำโปรไฟล์ประสิทธิภาพ
- การแปลภาษา (Localization): หากแอปพลิเคชันของคุณมีการแปลสำหรับหลายภาษา ตรวจสอบให้แน่ใจว่ากระบวนการแปลไม่ได้ทำให้เกิดคอขวดด้านประสิทธิภาพ ใช้ไลบรารีการแปลที่มีประสิทธิภาพและหลีกเลี่ยงการเขียนสตริงข้อความลงในคอมโพเนนต์โดยตรง
ตัวอย่างจากสถานการณ์จริง
ลองพิจารณาตัวอย่างจากสถานการณ์จริงสองสามตัวอย่างว่าเทคนิคการปรับปรุงประสิทธิภาพเหล่านี้สามารถนำไปประยุกต์ใช้ได้อย่างไร:
1. รายการสินค้าอีคอมเมิร์ซ
ลองนึกภาพเว็บไซต์อีคอมเมิร์ซที่มีหน้ารายการสินค้าที่แสดงสินค้าหลายร้อยรายการ สินค้าแต่ละรายการจะถูกเรนเดอร์เป็นคอมโพเนนต์แยกต่างหาก
หากไม่มีการปรับปรุงประสิทธิภาพ ทุกครั้งที่ผู้ใช้กรองหรือจัดเรียงรายการสินค้า คอมโพเนนต์สินค้าทั้งหมดจะเรนเดอร์ซ้ำ ซึ่งนำไปสู่ประสบการณ์ที่ช้าและกระตุก เพื่อปรับปรุงสิ่งนี้ คุณสามารถใช้ React.memo
เพื่อ memoize คอมโพเนนต์สินค้า เพื่อให้แน่ใจว่าพวกมันจะเรนเดอร์ซ้ำก็ต่อเมื่อ props ของมัน (เช่น ชื่อสินค้า ราคา รูปภาพ) เปลี่ยนแปลงเท่านั้น
2. ฟีดโซเชียลมีเดีย
ฟีดโซเชียลมีเดียมักจะแสดงรายการโพสต์ ซึ่งแต่ละโพสต์มีคอมเมนต์ การกดไลค์ และองค์ประกอบเชิงโต้ตอบอื่นๆ การเรนเดอร์ฟีดทั้งหมดใหม่ทุกครั้งที่ผู้ใช้กดไลค์โพสต์หรือเพิ่มคอมเมนต์จะไม่มีประสิทธิภาพ
เพื่อปรับปรุงสิ่งนี้ คุณสามารถใช้ useCallback
เพื่อ memoize ตัวจัดการเหตุการณ์ (event handlers) สำหรับการกดไลค์และคอมเมนต์โพสต์ ซึ่งจะช่วยป้องกันไม่ให้คอมโพเนนต์โพสต์เรนเดอร์ซ้ำโดยไม่จำเป็นเมื่อตัวจัดการเหตุการณ์เหล่านี้ถูกเรียกใช้
3. แดชบอร์ดแสดงข้อมูล
แดชบอร์ดแสดงข้อมูลมักจะแสดงแผนภูมิและกราฟที่ซับซ้อนซึ่งมีการอัปเดตข้อมูลใหม่บ่อยครั้ง การเรนเดอร์แผนภูมิเหล่านี้ใหม่ทุกครั้งที่ข้อมูลเปลี่ยนแปลงอาจสิ้นเปลืองทรัพยากรในการคำนวณ
เพื่อปรับปรุงสิ่งนี้ คุณสามารถใช้ useMemo
เพื่อ memoize ข้อมูลของแผนภูมิและเรนเดอร์แผนภูมิซ้ำก็ต่อเมื่อข้อมูลที่ memoize ไว้มีการเปลี่ยนแปลงเท่านั้น ซึ่งจะช่วยลดจำนวนการเรนเดอร์ซ้ำลงอย่างมากและปรับปรุงประสิทธิภาพโดยรวมของแดชบอร์ด
แนวทางปฏิบัติที่ดีที่สุด
นี่คือแนวทางปฏิบัติที่ดีที่สุดที่ควรจำไว้เมื่อปรับปรุงประสิทธิภาพการเรนเดอร์ของ React:
- ทำโปรไฟล์แอปพลิเคชันของคุณ: ใช้ React Profiler หรือ "Why Did You Render?" เพื่อระบุคอมโพเนนต์ที่ก่อให้เกิดปัญหาด้านประสิทธิภาพ
- เริ่มต้นจากสิ่งที่ทำได้ง่ายที่สุดก่อน: มุ่งเน้นไปที่การปรับปรุงประสิทธิภาพของคอมโพเนนต์ที่เรนเดอร์ซ้ำบ่อยที่สุดหรือใช้เวลาในการเรนเดอร์นานที่สุด
- ใช้ memoization อย่างรอบคอบ: อย่า memoize ทุกคอมโพเนนต์ เพราะ memoization เองก็มีต้นทุน ควร memoize เฉพาะคอมโพเนนต์ที่ก่อให้เกิดปัญหาด้านประสิทธิภาพจริงๆ เท่านั้น
- ใช้ immutability: ใช้โครงสร้างข้อมูลที่ไม่เปลี่ยนรูปเพื่อให้ React ตรวจจับการเปลี่ยนแปลงใน props และ state ได้ง่ายขึ้น
- ทำให้คอมโพเนนต์มีขนาดเล็กและมีหน้าที่เฉพาะเจาะจง: คอมโพเนนต์ที่เล็กกว่าและมีหน้าที่เฉพาะเจาะจงจะง่ายต่อการปรับปรุงประสิทธิภาพและบำรุงรักษา
- ทดสอบการปรับปรุงประสิทธิภาพของคุณ: หลังจากใช้เทคนิคการปรับปรุงประสิทธิภาพแล้ว ให้ทดสอบแอปพลิเคชันของคุณอย่างละเอียดเพื่อให้แน่ใจว่าการปรับปรุงนั้นได้ผลตามที่ต้องการและไม่ได้ทำให้เกิดบักใหม่
สรุป
การป้องกันการเรนเดอร์ซ้ำที่ไม่จำเป็นมีความสำคัญอย่างยิ่งต่อการปรับปรุงประสิทธิภาพของแอปพลิเคชัน React โดยการทำความเข้าใจว่ากระบวนการเรนเดอร์ของ React ทำงานอย่างไรและใช้เทคนิคที่อธิบายไว้ในคู่มือนี้ คุณสามารถปรับปรุงการตอบสนองและประสิทธิภาพของแอปพลิเคชันของคุณได้อย่างมาก ซึ่งจะมอบประสบการณ์ผู้ใช้ที่ดีขึ้นสำหรับผู้ใช้ทั่วโลก อย่าลืมทำโปรไฟล์แอปพลิเคชันของคุณ ระบุคอมโพเนนต์ที่ก่อให้เกิดปัญหาด้านประสิทธิภาพ และใช้เทคนิคการปรับปรุงประสิทธิภาพที่เหมาะสมเพื่อแก้ไขปัญหาเหล่านั้น โดยการปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุดเหล่านี้ คุณสามารถมั่นใจได้ว่าแอปพลิเคชัน React ของคุณจะรวดเร็ว มีประสิทธิภาพ และสามารถปรับขนาดได้ โดยไม่คำนึงถึงความซับซ้อนหรือขนาดของโค้ดเบสของคุณ