วิธีปรับจูน React ให้ทำงานเร็วขึ้นแบบมือโปร ไม่ต้องเดา

8 นาที 14 views บันทึกเป็น PDF
วิธีปรับจูน React ให้ทำงานเร็วขึ้นแบบมือโปร ไม่ต้องเดา

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

ทำไม React ถึงช้า และเราจะรู้ได้ยังไง

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

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

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

อย่าเพิ่งรีบปรับจูน (Premature Optimization)

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

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

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

หยุดการ Render ซ้ำโดยไม่จำเป็น

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

ลองดูตัวอย่างการแก้ปัญหาเมื่อมีการส่งข้อมูลใหม่เข้าไปในส่วนประกอบลูก:

// แบบที่ผิด: สร้างฟังก์ชันใหม่ทุกครั้งที่ Render
function ProductList({ products }) {
  return <List items={products} onSelect={(id) => track(id)} />;
}

// แบบที่ถูก: ใช้ useCallback เพื่อคงค่าฟังก์ชันเดิมไว้
function ProductList({ products }) {
  const handleSelect = useCallback((id) => track(id), []);
  return <List items={products} onSelect={handleSelect} />;
}

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

เลือกสิ่งที่ควรจำ (Memoization)

เครื่องมืออย่าง React.memo, useMemo และ useCallback มีไว้เพื่อช่วยรักษา Referential Identity (การคงค่าอ้างอิงเดิมของตัวแปรไว้) เราควรใช้เครื่องมือเหล่านี้เมื่อส่วนประกอบลูกมีการคำนวณที่หนักมาก หรือได้รับข้อมูลที่เปลี่ยนค่าตลอดเวลาจนทำให้เกิดการวาดใหม่แบบไม่หยุดหย่อน

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

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

ลดขนาดของ JavaScript ที่ต้องส่งให้ผู้ใช้งาน

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

เราสามารถใช้คำสั่ง lazy และ Suspense เพื่อโหลดหน้าเว็บเฉพาะส่วนที่ผู้ใช้กำลังดูอยู่ได้:

import { lazy, Suspense } from 'react';

// โหลดคอมโพเนนต์เฉพาะตอนที่จำเป็นต้องใช้
const Editor = lazy(() => import('./Editor'));

export function Panel() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <Editor />
    </Suspense>
  );
}

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

ย้ายงานไปไว้ที่ Server

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

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

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

สรุป: ขั้นตอนสู่ความเร็วที่ทำได้จริง

การทำให้เว็บเร็วไม่ใช่เรื่องของเวทมนตร์ แต่เป็นเรื่องของการมีวินัยในการเขียนโค้ด เริ่มต้นด้วยการ 1. วัดผลก่อนเสมอ 2. แก้เฉพาะจุดที่ช้าจริง 3. ลดการวาดหน้าจอซ้ำ 4. ลดขนาดไฟล์ที่โหลด และ 5. ใช้เซิร์ฟเวอร์ช่วยประมวลผล เพียงเท่านี้คุณก็จัดการปัญหาความเร็วได้เกือบ 90% แล้ว

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

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


ที่มา: A Practical Guide to React Performance — DEV Community

แชร์บทความ

Facebook X LINE

บทความที่เกี่ยวข้อง

จัดการเซิร์ฟเวอร์ผ่าน VS Code ให้ง่ายขึ้นด้วย Easy SSH พร้อมฟีเจอร์โหลดไฟล์ผ่านคลิกเดียว

จัดการเซิร์ฟเวอร์ผ่าน VS Code ให้ง่ายขึ้นด้วย Easy SSH พร้อมฟีเจอร์โหลดไฟล์ผ่านคลิกเดียว

เบื่อไหมที่ต้องสลับหน้าจอไปมาเพื่อจัดการเซิร์ฟเวอร์? มาลองใช้ Easy SSH ปลั๊กอิน VS Code ที่ช่วยให้คุณรีโมทผ่าน Terminal ได้สะดวก แถมโหลดไฟล์ได้ง่ายแค่กด Ctrl+click

ที่มา: DEV Community

25 minutes ago 11 นาที
0 views
วิธีดึงข้อมูลราคาจาก Google Hotels ด้วย API สำหรับนักพัฒนา

วิธีดึงข้อมูลราคาจาก Google Hotels ด้วย API สำหรับนักพัฒนา

อยากทำแอปท่องเที่ยวแต่ดึงข้อมูลราคาจาก Google Hotels ไม่ได้? มาดูวิธีใช้ Apify Actor ช่วยดึงข้อมูลแบบอัตโนมัติด้วย Python ง่ายๆ ไม่ต้องกลัวเว็บพัง

ที่มา: DEV Community

3 hours ago 8 นาที
3 views
วิธีเช็กความพร้อมโปรเจกต์ก่อนปล่อยงานจริงด้วย ReleaseReady

วิธีเช็กความพร้อมโปรเจกต์ก่อนปล่อยงานจริงด้วย ReleaseReady

เคยไหม? โค้ดรันได้ในเครื่องแต่พอปล่อยจริงกลับพัง! มาดูวิธีตรวจสอบความพร้อมของโปรเจกต์ก่อนอัปขึ้น GitHub ด้วยเครื่องมือ ReleaseReady กัน

ที่มา: DEV Community

7 hours ago 9 นาที
3 views