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