ลบโค้ดที่ไม่ได้ใช้

ใน Codelab นี้ ให้ปรับปรุงประสิทธิภาพของแอปพลิเคชันต่อไปนี้โดย จะนำทรัพยากร Dependency ที่ไม่ได้ใช้และไม่จำเป็นออก

ภาพหน้าจอแอป

วัดระยะทาง

คุณควรวัดว่าเว็บไซต์ทำงานได้ดีเพียงใดก่อน การเพิ่มการเพิ่มประสิทธิภาพ

  • หากต้องการดูตัวอย่างเว็บไซต์ ให้กดดูแอป แล้วกด เต็มหน้าจอ เต็มหน้าจอ

ไปคลิกลูกแมวตัวโปรดของคุณได้เลย ของ Firebase Realtime Database คือ ที่ใช้ในแอปพลิเคชันนี้ ซึ่งเป็นเหตุผลว่าทำไมคะแนนจึงมีการอัปเดตแบบเรียลไทม์และ ซิงค์ข้อมูลกับผู้ใช้คนอื่นๆ ทั้งหมดที่ใช้แอปพลิเคชันนี้ 🐈

  1. กด "Control+Shift+J" (หรือ "Command+Option+J" ใน Mac) เพื่อเปิดเครื่องมือสำหรับนักพัฒนาเว็บ
  2. คลิกแท็บเครือข่าย
  3. เลือกช่องทำเครื่องหมายปิดใช้แคช
  4. โหลดแอปซ้ำ

ขนาดแพ็กเกจดั้งเดิมที่ 992 KB

กำลังจัดส่ง 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()
  ]
};

เมื่อแอปพลิเคชันโหลดใหม่ คุณจะเห็นภาพของ แทนตัวแอป

เครื่องมือวิเคราะห์ Bundle ของ Webpack

ถึงจะไม่น่ารักเท่าเห็นลูกแมวตัวน้อย 🐱 แต่ก็ยังมีประโยชน์สุดๆ อยู่ดี เมื่อวางเมาส์บนแพ็กเกจใดแพ็กเกจหนึ่ง ขนาดแพ็กเกจจะแสดงขึ้นมา 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';

ตอนนี้เมื่อโหลดแอปซ้ำ คำเตือนเครื่องมือสำหรับนักพัฒนาเว็บจะไม่แสดงขึ้นมา กำลังเปิด แผงเครือข่ายของเครื่องมือสำหรับนักพัฒนาเว็บยังแสดงขนาดแพ็กเกจที่ลดลงได้ดีอีกด้วย ดังนี้

ลดขนาดแพ็กเกจลงเหลือ 480 KB

ขนาดมากกว่าครึ่งหนึ่งของแพ็กเกจถูกนำออกไปแล้ว Firebase มี และทำให้นักพัฒนาซอฟต์แวร์มีตัวเลือกในการรวมเฉพาะบริการ ที่จำเป็น ในแอปพลิเคชันนี้ มีการใช้เพียง firebase/database ในการจัดเก็บและซิงค์ ข้อมูลทั้งหมด การนำเข้า firebase/app ซึ่งตั้งค่าแพลตฟอร์ม API สำหรับ บริการแต่ละอย่าง เป็นสิ่งจำเป็นเสมอ

ไลบรารียอดนิยมอื่นๆ อีกมากมาย เช่น lodash ยังช่วยให้นักพัฒนาซอฟต์แวร์สามารถ เลือกนำเข้าส่วนต่างๆ ของแพ็กเกจ โดยไม่ต้องทำงานอะไรมาก อัปเดตการนำเข้าไลบรารีในแอปพลิเคชันให้รวมเฉพาะสิ่งที่กำลังใช้อยู่ อาจส่งผลให้ประสิทธิภาพดีขึ้นอย่างมาก

แม้ว่าขนาดของแพ็กเกจจะลดลงเล็กน้อย แต่ ที่ต้องทำ! 😈

การนำแพ็กเกจที่ไม่จำเป็นออก

การนำเข้าส่วนต่างๆ ของไลบรารี moment ต่างจาก Firebase ตรงที่ทำเป็น ได้อย่างง่ายดาย แต่สามารถลบออกได้ทั้งหมดหรือไม่

วันเกิดของลูกแมวน่ารักๆ แต่ละตัวจะจัดเก็บในรูปแบบ Unix (มิลลิวินาที) ใน ฐานข้อมูล Firebase

วันเกิดที่จัดเก็บในรูปแบบ Unix

นี่คือการประทับเวลาของวันที่และเวลาที่ระบุด้วยจำนวน มิลลิวินาทีที่ผ่านไปตั้งแต่วันที่ 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>
    `})
});

ตอนนี้ให้โหลดแอปพลิเคชันซ้ำและดูแผงเครือข่ายอีกครั้ง

แพ็กเกจมีขนาดลดลงเหลือ 225 KB

ขนาดของชุดของเราลดลงมากกว่าครึ่งอีกครั้ง!

บทสรุป

เมื่อใช้ Codelab นี้ คุณควรเข้าใจวิธีวิเคราะห์ แพ็กเกจใดแพ็กเกจหนึ่งโดยเฉพาะ และเหตุผลที่การนำแพ็กเกจที่ไม่ได้ใช้หรือไม่จำเป็นออกจึงมีประโยชน์อย่างมาก แพ็กเกจของคุณ ก่อนที่คุณจะเริ่มเพิ่มประสิทธิภาพแอปพลิเคชันด้วยเทคนิคนี้ แต่สิ่งนี้อาจซับซ้อนกว่ามากเมื่อ แอปพลิเคชัน

สำหรับการนำไลบรารีที่ไม่ได้ใช้ออก ให้ลองค้นหาว่าส่วนใดของ มีการใช้และส่วนใดที่ไม่ได้ใช้ สำหรับการมองลึกลับ พัสดุที่ดูเหมือนว่าไม่ได้มีการใช้งานที่ใดเลย ให้ถอยหลังไป 1 ก้าว แล้วตรวจสอบ ทรัพยากร Dependency ระดับบนสุดที่อาจต้องการ พยายามหาวิธีที่จะ แยกส่วนออกจากกัน

เมื่อพูดถึงการนำไลบรารีที่ไม่จำเป็นออก อาจมีสิ่งต่างๆ เพิ่มเติมกว่านี้ มีความซับซ้อน การทำงานอย่างใกล้ชิดกับทีมของคุณ เป็นสิ่งสำคัญและดูว่ามี เพื่อลดความซับซ้อนของฐานของโค้ดบางส่วน กำลังนำ moment ออกจากส่วนนี้ อาจดูเหมือนว่าเป็นสิ่งที่ควรทำทุกครั้ง หากมีเขตเวลาและสถานที่อื่นๆ ที่จำเป็นต้องจัดการ หรือ จะเป็นอย่างไรถ้ามีการปรับเปลี่ยนวันที่ที่ซับซ้อนกว่านี้ อาจทำให้มีโอกาสอย่างมาก ยุ่งยากเมื่อจัดการและแยกวิเคราะห์วันที่/เวลา และไลบรารี เช่น moment และ date-fns ช่วยให้การดำเนินการนี้ง่ายขึ้นอย่างมาก

ทุกอย่างมีทั้งข้อดี และสิ่งสำคัญคือต้องวัดว่า ความซับซ้อนและความพยายามในการเปิดตัวโซลูชันที่กำหนดเองแทนที่ต้องอาศัย ไลบรารีของบุคคลที่สาม