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