หน้าเว็บและแอปพลิเคชันส่วนใหญ่ประกอบด้วยหลายส่วน การแยก JavaScript ออกเป็นหลายกลุ่มจะช่วยปรับปรุงประสิทธิภาพของหน้าเว็บแทนการส่ง JavaScript ทั้งหมดที่ประกอบขึ้นเป็นแอปพลิเคชันทันทีที่โหลดหน้าแรก
Codelab นี้แสดงวิธีใช้การแยกโค้ดเพื่อปรับปรุงประสิทธิภาพของแอปพลิเคชันง่ายๆ ที่จัดเรียงตัวเลข 3 รายการ
วัดระยะทาง
เช่นเดียวกับเคย สิ่งสำคัญคือต้องวัดประสิทธิภาพของเว็บไซต์ก่อนพยายามเพิ่มการเพิ่มประสิทธิภาพ
- หากต้องการดูตัวอย่างเว็บไซต์ ให้กดดูแอป แล้วกดเต็มหน้าจอ
- กดแป้น Control+Shift+J (หรือ Command+Option+J ใน Mac) เพื่อเปิดเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์
- คลิกแท็บเครือข่าย
- เลือกช่องทำเครื่องหมายปิดใช้แคช
- โหลดแอปซ้ำ
JavaScript มูลค่า 71.2 KB เพียงเพื่อจัดเรียงตัวเลข 2-3 ตัวในแอปพลิเคชันง่ายๆ What gives?
ในซอร์สโค้ด (src/index.js
) ระบบจะนําเข้าและใช้ไลบรารี lodash
ในแอปพลิเคชันนี้ Lodash มีฟังก์ชันยูทิลิตีที่มีประโยชน์มากมาย แต่เราใช้เพียงเมธอดเดียวจากแพ็กเกจนี้
การติดตั้งและนําเข้าทรัพยากรของบุคคลที่สามทั้งหมดเมื่อใช้เพียงส่วนเล็กๆ เท่านั้นเป็นข้อผิดพลาดที่พบบ่อย
เพิ่มประสิทธิภาพ
การลดขนาดแพ็กเกจทำได้หลายวิธี ดังนี้
- เขียนวิธีการจัดเรียงที่กำหนดเองแทนการนําเข้าคลังภาพของบุคคลที่สาม
- ใช้เมธอด
Array.prototype.sort()
ในตัวเพื่อจัดเรียงตามตัวเลข - นำเข้าเฉพาะเมธอด
sortBy
จากlodash
ไม่ใช่ทั้งไลบรารี - ดาวน์โหลดโค้ดสำหรับการจัดเรียงเฉพาะเมื่อผู้ใช้คลิกปุ่ม
ตัวเลือกที่ 1 และ 2 เป็นวิธีที่เหมาะอย่างยิ่งในการลดขนาดแพ็กเกจ (และน่าจะเหมาะสมที่สุดสำหรับการใช้งานจริง) แต่เราจะไม่ใช้ข้อมูลเหล่านั้นในบทแนะนำนี้เพื่อประโยชน์ด้านการสอน 😈
ทั้ง 2 ตัวเลือกนี้จะช่วยปรับปรุงประสิทธิภาพของแอปพลิเคชันนี้ ส่วนถัดไปของโค้ดแล็บนี้จะอธิบายขั้นตอนเหล่านี้ เช่นเดียวกับบทแนะนำการเขียนโค้ดอื่นๆ พยายามเขียนโค้ดด้วยตนเองเสมอแทนที่จะคัดลอกและวาง
นำเข้าเฉพาะสิ่งที่ต้องการ
คุณต้องแก้ไขไฟล์ 2-3 ไฟล์เพื่อนําเข้าเฉพาะวิธีการเดียวจาก lodash
เริ่มต้นด้วยการแทนที่ข้อกําหนดนี้ใน 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>
`
});
โหลดแอปพลิเคชันซ้ำ เปิดเครื่องมือสำหรับนักพัฒนาเว็บ และดูที่แผงเครือข่ายอีกครั้ง
สําหรับแอปพลิเคชันนี้ ขนาด Bundle ลดลงกว่า 4 เท่าโดยแทบไม่ต้องทําอะไรเลย แต่ยังคงมีช่องว่างในการปรับปรุงอีก
การแยกโค้ด
webpack เป็นหนึ่งในเครื่องมือรวมโมดูลแบบโอเพนซอร์สที่ได้รับความนิยมมากที่สุดในปัจจุบัน กล่าวโดยย่อคือ เครื่องมือนี้จะรวมโมดูล JavaScript ทั้งหมด (รวมถึงชิ้นงานอื่นๆ) ที่ประกอบกันเป็นเว็บแอปพลิเคชันไว้ในไฟล์แบบคงที่ที่เบราว์เซอร์อ่านได้
คุณสามารถแยกกลุ่มเดียวที่ใช้ในแอปพลิเคชันนี้ออกเป็น 2 กลุ่มแยกกันได้ ดังนี้
- 1 คนรับผิดชอบโค้ดที่ประกอบเป็นเส้นทางเริ่มต้น
- ข้อมูลโค้ดรองที่มีโค้ดการจัดเรียง
เมื่อใช้การนําเข้าแบบไดนามิก คุณสามารถโหลดข้อมูลส่วนย่อยแบบ 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()
จะแสดงผลพรอมต์ และเมื่อพรอมต์ดำเนินการเสร็จแล้ว ระบบจะแสดงโมดูลที่เลือกซึ่งแยกออกเป็นกลุ่มแยกต่างหาก หลังจากระบบแสดงผลโมดูลแล้ว ระบบจะใช้ module.default
เพื่ออ้างอิงการส่งออกเริ่มต้นที่ lodash มีให้ Promise ดังกล่าวจะเชื่อมโยงกับ .then
อีกรายการหนึ่งที่เรียกใช้เมธอด sortInput
เพื่อจัดเรียงค่าอินพุต 3 ค่า เมื่อสิ้นสุดเชนการยืนยันcatch()
ใช้เพื่อจัดการกรณีที่ระบบปฏิเสธ Promise เนื่องด้วยข้อผิดพลาด
ขั้นตอนสุดท้ายที่ต้องทำคือเขียนเมธอด 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>
`
};
}
ติดตามดู
โหลดแอปพลิเคชันอีกครั้งเป็นครั้งสุดท้ายและคอยสังเกตแผงเครือข่ายอีกครั้ง ระบบจะดาวน์โหลดเฉพาะ App Bundle ขนาดเล็กชุดแรกทันทีที่โหลดแอป
หลังจากกดปุ่มเพื่อจัดเรียงตัวเลขที่ป้อน ระบบจะดึงข้อมูลและเรียกใช้กลุ่มที่มีโค้ดการจัดเรียง
โปรดสังเกตว่าตัวเลขยังคงจัดเรียงอยู่
บทสรุป
การแยกโค้ดและการโหลดแบบเลื่อนเวลาอาจเป็นประโยชน์อย่างยิ่งในการลดขนาด App Bundle เริ่มต้นของแอปพลิเคชัน ซึ่งอาจส่งผลให้เวลาในการโหลดหน้าเว็บเร็วขึ้นมาก อย่างไรก็ตาม มีข้อสําคัญบางประการที่ควรพิจารณาก่อนรวมการเพิ่มประสิทธิภาพนี้ไว้ในแอปพลิเคชัน
UI การโหลดแบบ Lazy Loading
เมื่อใช้การโหลดโมดูลโค้ดแบบ Lazy สิ่งสำคัญคือต้องพิจารณาประสบการณ์การใช้งานของผู้ใช้ที่มีการเชื่อมต่อเครือข่ายที่ช้า การแยกและโหลดโค้ดจำนวนมากเมื่อผู้ใช้ส่งการดําเนินการอาจทําให้ดูเหมือนว่าแอปพลิเคชันหยุดทํางาน ดังนั้นให้พิจารณาแสดงตัวบ่งชี้การโหลด
การโหลดโมดูลโหนดของบุคคลที่สามแบบ Lazy Loading
การโหลดแบบ Lazy Load ทรัพยากรของบุคคลที่สามในแอปพลิเคชันอาจไม่ใช่แนวทางที่ดีที่สุดเสมอไป ทั้งนี้ขึ้นอยู่กับตำแหน่งที่คุณใช้ทรัพยากร โดยปกติแล้ว ระบบจะแยกข้อกําหนดของบุคคลที่สามออกเป็นvendor
แพ็กเกจแยกต่างหากที่สามารถแคชได้ เนื่องจากมีการอัปเดตไม่บ่อยนัก อ่านเพิ่มเติมเกี่ยวกับวิธีที่ SplitChunksPlugin ช่วยคุณดำเนินการนี้ได้
การโหลดเมื่อจำเป็นด้วยเฟรมเวิร์ก JavaScript
เฟรมเวิร์กและไลบรารียอดนิยมหลายรายการที่ใช้ webpack มีการแยกความคิดเพื่อให้การโหลดแบบเลื่อนเวลาทำงานง่ายขึ้นกว่าการใช้การนําเข้าแบบไดนามิกในช่วงกลางของแอปพลิเคชัน
- การโหลดโมดูลแบบ Lazy Loading ด้วย Angular
- การแยกโค้ดด้วย React Router
- การโหลดแบบ Lazy Loading ด้วย Vue Router
แม้ว่าการทำความเข้าใจวิธีการทํางานของการนําเข้าแบบไดนามิกจะมีประโยชน์ แต่ให้ใช้วิธีการที่เฟรมเวิร์ก/ไลบรารีแนะนําเสมอเพื่อโหลดโมดูลที่เฉพาะเจาะจงแบบ Lazy Load
การโหลดล่วงหน้าและการดึงข้อมูลล่วงหน้า
หากเป็นไปได้ ให้ใช้ประโยชน์จากคำแนะนำของเบราว์เซอร์ เช่น <link rel="preload">
หรือ <link rel="prefetch">
เพื่อพยายามโหลดโมดูลที่สำคัญให้เร็วขึ้น webpack รองรับทั้ง 2 คำแนะนำผ่านการใช้ความคิดเห็นแบบมายากลในคำสั่งการนําเข้า ซึ่งอธิบายไว้อย่างละเอียดในคู่มือโหลดข้อมูลส่วนสําคัญล่วงหน้า
การโหลดแบบ Lazy Loading มากกว่าโค้ด
รูปภาพเป็นส่วนสำคัญของแอปพลิเคชัน การโหลดแบบ Lazy Loading องค์ประกอบที่อยู่ด้านล่างของหน้าจอหรือนอกวิวพอร์ตของอุปกรณ์จะช่วยเพิ่มความเร็วของเว็บไซต์ได้ อ่านข้อมูลเพิ่มเติมได้ในคู่มือ Lazysizes