ใน Codelab นี้ ให้ปรับปรุงประสิทธิภาพของแอปพลิเคชันต่อไปนี้โดย จะนำทรัพยากร Dependency ที่ไม่ได้ใช้และไม่จำเป็นออก
วัดระยะทาง
คุณควรวัดว่าเว็บไซต์ทำงานได้ดีเพียงใดก่อน การเพิ่มการเพิ่มประสิทธิภาพ
- หากต้องการดูตัวอย่างเว็บไซต์ ให้กดดูแอป แล้วกด เต็มหน้าจอ
ไปคลิกลูกแมวตัวโปรดของคุณได้เลย ของ Firebase Realtime Database คือ ที่ใช้ในแอปพลิเคชันนี้ ซึ่งเป็นเหตุผลว่าทำไมคะแนนจึงมีการอัปเดตแบบเรียลไทม์และ ซิงค์ข้อมูลกับผู้ใช้คนอื่นๆ ทั้งหมดที่ใช้แอปพลิเคชันนี้ 🐈
- กด "Control+Shift+J" (หรือ "Command+Option+J" ใน Mac) เพื่อเปิดเครื่องมือสำหรับนักพัฒนาเว็บ
- คลิกแท็บเครือข่าย
- เลือกช่องทำเครื่องหมายปิดใช้แคช
- โหลดแอปซ้ำ
กำลังจัดส่ง JavaScript มูลค่าเกือบ 1 MB เพื่อโหลดแอปพลิเคชันง่ายๆ นี้!
ดูคำเตือนโปรเจ็กต์ในเครื่องมือสำหรับนักพัฒนาเว็บ
- คลิกแท็บคอนโซล
- ตรวจสอบว่าได้เปิดใช้
Warnings
ในเมนูแบบเลื่อนลง "ระดับ" ข้าง อินพุตFilter
- ดูคำเตือนที่แสดงอยู่
Firebase ซึ่งเป็นหนึ่งในไลบรารีที่ใช้ในแอปพลิเคชันนี้ ที่ดีโดยการแสดงคำเตือนเพื่อให้นักพัฒนาทราบว่าไม่ควรนำเข้า ทั้งแพ็กเกจ แต่แสดงเฉพาะคอมโพเนนต์ที่ใช้ กล่าวคือ มี ไลบรารีที่ไม่ได้ใช้ซึ่งสามารถนำออกในแอปพลิเคชันนี้เพื่อโหลด ได้เร็วขึ้น
นอกจากนี้ยังมีกรณีอื่นๆ เมื่อมีการใช้ไลบรารีหนึ่งๆ แต่อาจจะมี ทางเลือกที่ง่ายกว่า แนวคิดของการนำไลบรารีที่ไม่จำเป็นออกคือ สำรวจต่อไปในบทแนะนำนี้
กำลังวิเคราะห์แพ็กเกจ
มีทรัพยากร Dependency หลัก 2 อย่างในแอปพลิเคชัน ได้แก่
- Firebase: แพลตฟอร์มที่มอบ บริการที่มีประโยชน์สำหรับ iOS, Android หรือเว็บแอปพลิเคชัน นี่คือเรียลไทม์ Database ใช้เพื่อ จัดเก็บและซิงค์ข้อมูลของลูกแมวแต่ละตัวแบบเรียลไทม์
- Moment.js: ไลบรารียูทิลิตีที่ช่วยให้คุณ
จัดการวันที่ใน JavaScript วันเกิดของลูกแมวแต่ละตัวจะเก็บอยู่ใน
ระบบจะใช้ฐานข้อมูล Firebase และ
moment
เพื่อคำนวณอายุในหน่วยสัปดาห์
ทรัพยากร Dependency เพียง 2 รายการจะทำให้แพ็กเกจมีขนาดเกือบ 1 MB ได้อย่างไร เอาล่ะ เหตุผลหนึ่งก็คือ ทรัพยากร Dependency สามารถอ้างอิง ทรัพยากร Dependency จึงมีมากกว่าแค่ 2 อย่างหากทุกๆ ความลึก/สาขาของ ทรัพยากร Dependency "ต้นไม้" ด้วย เป็นเรื่องง่ายที่แอปพลิเคชันจะมีขนาดใหญ่ ค่อนข้างเร็วหากรวมทรัพยากร Dependency ไว้หลายรายการ
วิเคราะห์ Bundler เพื่อรับไอเดียที่ดียิ่งขึ้น มีตัวเลือกช่วงวันที่
เครื่องมือที่ชุมชนสร้างขึ้นแบบต่างๆ ซึ่งช่วยในเรื่องดังกล่าวได้ เช่น
webpack-bundle-analyzer
แพ็กเกจสำหรับเครื่องมือนี้รวมอยู่ในแอปในฐานะ devDependency
แล้ว
"devDependencies": {
//...
"webpack-bundle-analyzer": "^2.13.1"
},
ซึ่งหมายความว่าจะใช้ในไฟล์การกำหนดค่า Webpack ได้โดยตรง
นำเข้าไว้ที่จุดเริ่มต้นของ webpack.config.js
:
const path = require("path");
//...
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
.BundleAnalyzerPlugin;
จากนั้นเพิ่มเป็นปลั๊กอินที่ส่วนท้ายสุดของไฟล์ภายในอาร์เรย์ plugins
module.exports = {
//...
plugins: [
//...
new BundleAnalyzerPlugin()
]
};
เมื่อแอปพลิเคชันโหลดใหม่ คุณจะเห็นภาพของ แทนตัวแอป
ถึงจะไม่น่ารักเท่าเห็นลูกแมวตัวน้อย 🐱 แต่ก็ยังมีประโยชน์สุดๆ อยู่ดี เมื่อวางเมาส์บนแพ็กเกจใดแพ็กเกจหนึ่ง ขนาดแพ็กเกจจะแสดงขึ้นมา 3 ขนาด ได้หลายวิธีดังนี้
ขนาดสถิติ | ปรับขนาดก่อนการลดขนาดหรือการบีบอัด |
---|---|
ขนาดที่แยกวิเคราะห์ | ขนาดจริงของแพ็กเกจภายในแพ็กเกจหลังจากทำการคอมไพล์แล้ว Webpack เวอร์ชัน 4 (ที่ใช้ในแอปพลิเคชันนี้) ช่วยลด ที่คอมไพล์โดยอัตโนมัติแล้ว ซึ่งเป็นเหตุผลว่าทำไมตัวเลขนี้จึงน้อยกว่าค่าสถิติ ขนาด |
ขนาด Gzip | ขนาดของแพ็กเกจหลังจากบีบอัดด้วยการเข้ารหัส gzip ช่วงเวลานี้ โดยจะมีอยู่ในคู่มือแยกต่างหาก |
เครื่องมือ Webpack-bundle-analyzer ช่วยให้ระบุรายการที่ไม่มีการใช้งานหรือ แพ็กเกจที่ไม่จำเป็น ซึ่งรวมกันเป็นแพ็กเกจจำนวนมาก
นำแพ็กเกจที่ไม่ได้ใช้ออก
ภาพนี้แสดงให้เห็นว่าแพ็กเกจ firebase
มีอีกจำนวนมากอีก
แทนที่จะเป็นแค่ฐานข้อมูล ซึ่งรวมถึงแพ็กเกจเพิ่มเติม เช่น
firestore
auth
storage
messaging
functions
ทั้งหมดนี้เป็นบริการที่ยอดเยี่ยมจาก Firebase (และอ้างอิงถึง เอกสารประกอบ เพื่อดูข้อมูลเพิ่มเติม) แต่ไม่มีการใช้แอปพลิเคชันใดๆ ในแอปพลิเคชันเลย ดังนั้นจึงมี โดยไม่ต้องมีการนำเข้าทั้งหมด
เปลี่ยนกลับการเปลี่ยนแปลงใน webpack.config.js
เพื่อดูแอปพลิเคชันอีกครั้ง:
- นำ
BundleAnalyzerPlugin
ออกจากรายการปลั๊กอิน
plugins: [
//...
new BundleAnalyzerPlugin()
];
- แล้วนำการนำเข้าที่ไม่ได้ใช้ออกจากด้านบนของไฟล์ดังนี้
const path = require("path");
//...
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
ขณะนี้แอปพลิเคชันควรจะโหลดได้ตามปกติแล้ว แก้ไข src/index.js
เพื่ออัปเดต
การนำเข้า Firebase
import firebase from 'firebase';
import firebase from 'firebase/app';
import 'firebase/database';
ตอนนี้เมื่อโหลดแอปซ้ำ คำเตือนเครื่องมือสำหรับนักพัฒนาเว็บจะไม่แสดงขึ้น กำลังเปิด แผงเครือข่ายของเครื่องมือสำหรับนักพัฒนาเว็บยังแสดงขนาดแพ็กเกจที่ลดลงได้ดีอีกด้วย ดังนี้
ขนาดมากกว่าครึ่งหนึ่งของแพ็กเกจถูกนำออกไปแล้ว Firebase มี
และทำให้นักพัฒนาซอฟต์แวร์มีตัวเลือกในการรวมเฉพาะบริการ
ที่จำเป็น ในแอปพลิเคชันนี้ มีการใช้เพียง firebase/database
ในการจัดเก็บและซิงค์
ข้อมูลทั้งหมด การนำเข้า firebase/app
ซึ่งตั้งค่าแพลตฟอร์ม API สำหรับ
บริการแต่ละอย่าง
เป็นสิ่งจำเป็นเสมอ
ไลบรารียอดนิยมอื่นๆ อีกมากมาย เช่น lodash
ยังช่วยให้นักพัฒนาซอฟต์แวร์สามารถ
เลือกนำเข้าส่วนต่างๆ ของแพ็กเกจ โดยไม่ต้องทำงานอะไรมาก
อัปเดตการนำเข้าไลบรารีในแอปพลิเคชันให้รวมเฉพาะสิ่งที่กำลังใช้อยู่
อาจส่งผลให้ประสิทธิภาพดีขึ้นอย่างมาก
แม้ว่าขนาดของแพ็กเกจจะลดลงเล็กน้อย แต่ ที่ต้องทำ! 😈
การนำแพ็กเกจที่ไม่จำเป็นออก
การนำเข้าส่วนต่างๆ ของไลบรารี moment
ต่างจาก Firebase ตรงที่ทำเป็น
ได้อย่างง่ายดาย แต่สามารถลบออกได้ทั้งหมดหรือไม่
วันเกิดของลูกแมวน่ารักๆ แต่ละตัวจะจัดเก็บในรูปแบบ Unix (มิลลิวินาที) ใน ฐานข้อมูล Firebase
นี่คือการประทับเวลาของวันที่และเวลาที่ระบุด้วยจำนวน มิลลิวินาทีที่ผ่านไปตั้งแต่วันที่ 1 มกราคม 1970 เวลา 00:00 น. UTC หากการตั้งค่าปัจจุบัน สามารถคำนวณวันที่และเวลาในรูปแบบเดียวกันได้ ซึ่งเป็นฟังก์ชันขนาดเล็กที่จะช่วย อายุของลูกแมวแต่ละตัว สัปดาห์ก็น่าจะสร้างได้
และเช่นเคย อย่าพยายามคัดลอกและวางขณะทําตามในส่วนนี้ เริ่มภายในวันที่
กำลังนำ moment
ออกจากการนำเข้าใน src/index.js
import firebase from 'firebase/app';
import 'firebase/database';
import * as moment from 'moment';
มี Listener เหตุการณ์ของ Firebase ที่จัดการการเปลี่ยนแปลงค่าในฐานข้อมูลของเรา ดังนี้
favoritesRef.on("value", (snapshot) => { ... })
จากด้านบนนี้ ให้ใส่ฟังก์ชันเล็กๆ เพื่อคำนวณจำนวนสัปดาห์จาก วันที่ที่ระบุ:
const ageInWeeks = birthDate => {
const WEEK_IN_MILLISECONDS = 1000 * 60 * 60 * 24 * 7;
const diff = Math.abs((new Date).getTime() - birthDate);
return Math.floor(diff / WEEK_IN_MILLISECONDS);
}
ในฟังก์ชันนี้ ความแตกต่างในหน่วยมิลลิวินาทีระหว่างวันที่ปัจจุบันกับ
เวลา (new Date).getTime()
และวันเกิด (อาร์กิวเมนต์ birthDate
แล้ว
เป็นมิลลิวินาที) คำนวณและหารด้วยจำนวนมิลลิวินาทีใน
สัปดาห์เดียว
สุดท้าย คุณสามารถนำอินสแตนซ์ทั้งหมดของ moment
ออกจาก Listener เหตุการณ์ได้โดย
โดยใช้ฟังก์ชันนี้แทน
favoritesRef.on("value", (snapshot) => { const { kitties, favorites, names, birthDates } = snapshot.val(); favoritesScores = favorites; kittiesList.innerHTML = kitties.map((kittiePic, index) => {const birthday = moment(birthDates[index]);return ` <li> <img src=${kittiePic} onclick="favKittie(${index})"> <div class="extra"> <div class="details"> <p class="name">${names[index]}</p><p class="age">${moment().diff(birthday, 'weeks')} weeks old</p><p class="age">${ageInWeeks(birthDates[index])} weeks old</p> </div> <p class="score">${favorites[index]} ❤</p> </div> </li> `}) });
ตอนนี้ให้โหลดแอปพลิเคชันซ้ำและดูแผงเครือข่ายอีกครั้ง
ขนาดของชุดของเราลดลงมากกว่าครึ่งอีกครั้ง!
บทสรุป
เมื่อใช้ Codelab นี้ คุณควรเข้าใจวิธีวิเคราะห์ แพ็กเกจใดแพ็กเกจหนึ่งโดยเฉพาะ และเหตุผลที่การนำแพ็กเกจที่ไม่ได้ใช้หรือไม่จำเป็นออกจึงมีประโยชน์อย่างมาก แพ็กเกจของคุณ ก่อนที่คุณจะเริ่มเพิ่มประสิทธิภาพแอปพลิเคชันด้วยเทคนิคนี้ แต่สิ่งนี้อาจซับซ้อนกว่ามากเมื่อ แอปพลิเคชัน
สำหรับการนำไลบรารีที่ไม่ได้ใช้ออก ให้ลองค้นหาว่าส่วนใดของ มีการใช้และส่วนใดที่ไม่ได้ใช้ สำหรับการมองลึกลับ พัสดุที่ดูเหมือนว่าไม่ได้มีการใช้งานที่ใดเลย ให้ถอยหลังไป 1 ก้าว แล้วตรวจสอบ ทรัพยากร Dependency ระดับบนสุดที่อาจต้องการ พยายามหาวิธีที่จะ แยกส่วนออกจากกัน
เมื่อพูดถึงการนำไลบรารีที่ไม่จำเป็นออก อาจมีสิ่งต่างๆ เพิ่มเติมกว่านี้
มีความซับซ้อน การทำงานอย่างใกล้ชิดกับทีมของคุณ เป็นสิ่งสำคัญและดูว่ามี
เพื่อลดความซับซ้อนของฐานของโค้ดบางส่วน กำลังนำ moment
ออกจากส่วนนี้
อาจดูเหมือนว่าเป็นสิ่งที่ควรทำทุกครั้ง
หากมีเขตเวลาและสถานที่อื่นๆ ที่จำเป็นต้องจัดการ หรือ
จะเป็นอย่างไรถ้ามีการปรับเปลี่ยนวันที่ที่ซับซ้อนกว่านี้ อาจทำให้มีโอกาสอย่างมาก
ยุ่งยากเมื่อจัดการและแยกวิเคราะห์วันที่/เวลา และไลบรารี เช่น moment
และ date-fns
ช่วยให้การดำเนินการนี้ง่ายขึ้นอย่างมาก
ทุกอย่างมีทั้งข้อดี และสิ่งสำคัญคือต้องวัดว่า ความซับซ้อนและความพยายามในการเปิดตัวโซลูชันที่กำหนดเองแทนที่ต้องอาศัย ไลบรารีของบุคคลที่สาม