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

วัดผล
เช่นเคย สิ่งสำคัญคือต้องวัดประสิทธิภาพของเว็บไซต์ก่อนที่จะพยายามเพิ่มการเพิ่มประสิทธิภาพใดๆ
- หากต้องการดูตัวอย่างเว็บไซต์ ให้กดดูแอป แล้วกดเต็มหน้าจอ
- กด `Control+Shift+J` (หรือ `Command+Option+J` บน Mac) เพื่อเปิดเครื่องมือสำหรับนักพัฒนาเว็บ
- คลิกแท็บเครือข่าย
- เลือกช่องทำเครื่องหมายปิดใช้แคช
- โหลดแอปซ้ำ

JavaScript ขนาด 71.2 KB เพื่อจัดเรียงตัวเลขไม่กี่ตัวในแอปพลิเคชันง่ายๆ เกิดอะไรขึ้น
ในซอร์สโค้ด (src/index.js) มีการนำเข้าและใช้ไลบรารี lodash ในแอปพลิเคชันนี้ Lodash มีฟังก์ชันยูทิลิตีที่มีประโยชน์มากมาย แต่ในที่นี้จะใช้เพียงเมธอดเดียวจากแพ็กเกจ
ข้อผิดพลาดที่พบบ่อยคือการติดตั้งและนำเข้าทรัพยากร Dependency ทั้งหมดของบุคคลที่สามซึ่งมีการใช้งานเพียงส่วนเล็กๆ เท่านั้น
เพิ่มประสิทธิภาพ
คุณลดขนาดแพ็กเกจได้หลายวิธี ดังนี้
- เขียนวิธีการจัดเรียงที่กำหนดเองแทนการนำเข้าไลบรารีของบุคคลที่สาม
- ใช้เมธอด
Array.prototype.sort()ในตัวเพื่อจัดเรียงตามตัวเลข - นำเข้าเฉพาะเมธอด
sortByจากlodashไม่ใช่นำเข้าทั้งไลบรารี - ดาวน์โหลดโค้ดสำหรับการจัดเรียงเฉพาะเมื่อผู้ใช้คลิกปุ่ม
ตัวเลือกที่ 1 และ 2 เป็นวิธีที่เหมาะสมอย่างยิ่งในการลดขนาดแพ็กเกจ (และอาจเหมาะสมที่สุดสำหรับแอปพลิเคชันจริง) อย่างไรก็ตาม เราจะไม่ใช้สิ่งเหล่านั้นในบทแนะนำนี้เพื่อจุดประสงค์ในการสอน 😈
ทั้งตัวเลือกที่ 3 และ 4 ช่วยปรับปรุงประสิทธิภาพของแอปพลิเคชันนี้ ส่วนถัดไปของ Codelab นี้จะครอบคลุมขั้นตอนเหล่านี้ เช่นเดียวกับบทแนะนำการเขียนโค้ดอื่นๆ คุณควรพยายามเขียนโค้ดด้วยตนเองแทนการคัดลอกและวาง
นำเข้าเฉพาะสิ่งที่ต้องการ
คุณต้องแก้ไขไฟล์บางไฟล์เพื่อนำเข้าเฉพาะเมธอดเดียวจาก lodash
เริ่มต้นด้วยการแทนที่ทรัพยากร Dependency นี้ใน package.json
"lodash": "^4.7.0",
ด้วย
"lodash.sortby": "^4.7.0",
ตอนนี้ใน src/index.js ให้นำเข้าโมดูลที่เฉพาะเจาะจงนี้
import "./style.css";
import _ from "lodash";
import sortBy from "lodash.sortby";
และอัปเดตวิธีจัดเรียงค่าดังนี้
form.addEventListener("submit", e => {
e.preventDefault();
const values = [input1.valueAsNumber, input2.valueAsNumber, input3.valueAsNumber];
const sortedValues = _.sortBy(values);
const sortedValues = sortBy(values);
results.innerHTML = `
<h2>
${sortedValues}
</h2>
`
});
โหลดแอปพลิเคชันซ้ำ เปิดเครื่องมือสำหรับนักพัฒนาเว็บ แล้วดูแผงเครือข่ายอีกครั้ง

สำหรับแอปพลิเคชันนี้ ขนาดแพ็กเกจลดลงมากกว่า 4 เท่าโดยใช้เวลาเพียงเล็กน้อย แต่ก็ยังมีส่วนที่ปรับปรุงได้อีก
การแยกโค้ด
webpack เป็นหนึ่งในเครื่องมือรวมโมดูลแบบโอเพนซอร์สที่ได้รับความนิยมมากที่สุดในปัจจุบัน กล่าวโดยย่อคือ Webpack จะรวมโมดูล JavaScript ทั้งหมด (รวมถึงเนื้อหาอื่นๆ) ที่ประกอบกันเป็นเว็บแอปพลิเคชันไว้ในไฟล์แบบคงที่ซึ่งเบราว์เซอร์อ่านได้
คุณสามารถแยกแพ็กเกจเดียวที่ใช้ในแอปพลิเคชันนี้ออกเป็น 2 ส่วนแยกกันได้ ดังนี้
- ส่วนแรกมีหน้าที่รับผิดชอบโค้ดที่สร้างเส้นทางเริ่มต้น
- ส่วนรองที่มีโค้ดการจัดเรียง
เมื่อใช้การนําเข้าแบบไดนามิก คุณจะสามารถโหลดแบบ Lazy Loading หรือโหลดกลุ่มรองตามต้องการได้ ในแอปพลิเคชันนี้ โค้ดที่ประกอบขึ้นเป็นกลุ่มจะโหลดได้ก็ต่อเมื่อผู้ใช้กดปุ่มเท่านั้น
เริ่มด้วยการนำเข้าการนำเข้าระดับบนสุดสำหรับเมธอดการจัดเรียงใน src/index.js ออก
import sortBy from "lodash.sortby";
และนําเข้าภายใน Listener เหตุการณ์ที่เริ่มทํางานเมื่อกดปุ่ม
form.addEventListener("submit", e => {
e.preventDefault();
import('lodash.sortby')
.then(module => module.default)
.then(sortInput())
.catch(err => { alert(err) });
});
ฟีเจอร์ import() เป็นส่วนหนึ่งของข้อเสนอ (ปัจจุบันอยู่ในขั้นที่ 3 ของกระบวนการ TC39) เพื่อรวมความสามารถในการนำเข้าโมดูลแบบไดนามิก webpack ได้รวมการรองรับฟีเจอร์นี้ไว้แล้วและเป็นไปตามไวยากรณ์เดียวกันกับที่ข้อเสนอระบุไว้
import() จะแสดงผลเป็น Promise และเมื่อแก้ไขแล้ว ระบบจะแสดงโมดูลที่เลือกซึ่งแยกออกเป็นกลุ่มแยกต่างหาก หลังจากโมดูลแสดงผลแล้ว ระบบจะใช้ module.default เพื่ออ้างอิงการส่งออกเริ่มต้นที่ lodash มีให้ Promise จะเชื่อมโยงกับ .then อื่นที่เรียกใช้เมธอด sortInput เพื่อจัดเรียงค่าอินพุต 3 ค่า ที่ส่วนท้ายของเชน Promisecatch() ใช้เพื่อจัดการกรณีที่สัญญาถูกปฏิเสธเนื่องจากข้อผิดพลาด
สิ่งสุดท้ายที่ต้องทำคือเขียนเมธอด sortInput ที่ท้ายไฟล์ ซึ่งต้องเป็นฟังก์ชันที่แสดงผลฟังก์ชันที่รับเมธอดที่นำเข้าจาก lodash.sortBy จากนั้นฟังก์ชันที่ซ้อนกันจะจัดเรียงค่าอินพุต 3 ค่าและอัปเดต DOM
const sortInput = () => {
return (sortBy) => {
const values = [
input1.valueAsNumber,
input2.valueAsNumber,
input3.valueAsNumber
];
const sortedValues = sortBy(values);
results.innerHTML = `
<h2>
${sortedValues}
</h2>
`
};
}
ตรวจสอบ
โหลดแอปพลิเคชันซ้ำเป็นครั้งสุดท้ายและจับตาดูแผงเครือข่ายอย่างใกล้ชิดอีกครั้ง ระบบจะดาวน์โหลดเฉพาะแพ็กเกจเริ่มต้นขนาดเล็กทันทีที่แอปโหลด

หลังจากกดปุ่มเพื่อจัดเรียงตัวเลขที่ป้อน ระบบจะดึงข้อมูลและเรียกใช้กลุ่มที่มีโค้ดการจัดเรียง

สังเกตว่าตัวเลขยังคงได้รับการจัดเรียง
บทสรุป
การแยกโค้ดและการโหลดแบบ Lazy Loading เป็นเทคนิคที่มีประโยชน์อย่างยิ่งในการลดขนาดแพ็กเกจเริ่มต้นของแอปพลิเคชัน ซึ่งจะส่งผลโดยตรงต่อเวลาในการโหลดหน้าเว็บที่เร็วขึ้นมาก อย่างไรก็ตาม มีสิ่งสำคัญบางอย่างที่ต้องพิจารณาก่อนที่จะรวมการเพิ่มประสิทธิภาพนี้ไว้ในแอปพลิเคชันของคุณ
UI การโหลดแบบ Lazy Loading
เมื่อโหลดโมดูลโค้ดที่เฉพาะเจาะจงแบบ Lazy Loading คุณควรพิจารณาว่าประสบการณ์การใช้งานของผู้ใช้ที่มีการเชื่อมต่อเครือข่ายที่ช้าจะเป็นอย่างไร การแยกและโหลดโค้ดจำนวนมากเมื่อผู้ใช้ส่งการดำเนินการอาจทำให้ดูเหมือนว่าแอปพลิเคชันหยุดทำงาน ดังนั้นให้พิจารณาแสดงสัญญาณบอกสถานะการโหลดบางอย่าง
การโหลดแบบ Lazy Loading สำหรับโมดูลโหนดของบุคคลที่สาม
การโหลดทรัพยากร Dependency ของบุคคลที่สามแบบ Lazy Loading ในแอปพลิเคชันอาจไม่ใช่วิธีที่ดีที่สุดเสมอไป ทั้งนี้ขึ้นอยู่กับตำแหน่งที่คุณใช้ทรัพยากรเหล่านั้น โดยปกติแล้ว ทรัพยากร Dependency ของบุคคลที่สามจะแยกออกเป็นแพ็กเกจ vendor แยกต่างหากที่แคชได้เนื่องจากไม่ได้อัปเดตบ่อยนัก อ่านข้อมูลเพิ่มเติมเกี่ยวกับวิธีที่ SplitChunksPlugin ช่วยคุณได้
การโหลดแบบ Lazy Loading ด้วยเฟรมเวิร์ก JavaScript
เฟรมเวิร์กและไลบรารียอดนิยมจำนวนมากที่ใช้ webpack มีนามธรรมเพื่อทำให้การโหลดแบบ Lazy Loading ง่ายกว่าการใช้การนำเข้าแบบไดนามิกในแอปพลิเคชันของคุณ
- การโหลดโมดูลแบบ Lazy Loading ด้วย Angular
- การแยกโค้ดด้วย React Router
- การโหลดแบบ Lazy Loading ด้วย Vue Router
แม้ว่าการทำความเข้าใจวิธีการทำงานของการนำเข้าแบบไดนามิกจะมีประโยชน์ แต่ให้ใช้วิธีที่เฟรมเวิร์ก/ไลบรารีแนะนำเสมอเพื่อโหลดโมดูลที่เฉพาะเจาะจงแบบ Lazy Loading
การโหลดล่วงหน้าและการดึงข้อมูลล่วงหน้า
หากเป็นไปได้ ให้ใช้ประโยชน์จากคำแนะนำของเบราว์เซอร์ เช่น <link rel="preload"> หรือ <link rel="prefetch"> เพื่อพยายามโหลดโมดูลที่สำคัญให้เร็วยิ่งขึ้น webpack รองรับคำแนะนำทั้ง 2 แบบผ่านการใช้ความคิดเห็นแบบ Magic ในคำสั่ง import ซึ่งอธิบายไว้อย่างละเอียดในคู่มือโหลดข้อมูลสำคัญล่วงหน้า
การโหลดแบบ Lazy Loading ไม่ได้ใช้กับโค้ดเท่านั้น
รูปภาพอาจเป็นส่วนสำคัญของแอปพลิเคชัน การโหลดแบบ Lazy Loading สำหรับเนื้อหาที่อยู่ครึ่งหน้าล่างหรืออยู่นอกวิวพอร์ตของอุปกรณ์จะช่วยเพิ่มความเร็วของเว็บไซต์ได้ อ่านข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้ได้ในคู่มือ Lazysizes