🚀 Cách Làm Cho App/Website Trở Nên Nhanh Và Mượt Mà Hơn

Hello mọi người lại là Slao đây!

Phần tiếp theo này chúng ta sẽ đến với cách làm cho chương trình của chúng ta có thể chạy nhanh hơn nhé.


🧑‍💻 1. Di Chuyển Code Tới Server Components

Nếu có thể, hãy di chuyển code đến Server Components để giảm tải công việc trên client.

Việc xử lý trên server giúp giảm lượng JavaScript tải xuống trình duyệt.


✂️ 2. Chia Tách (Split) Code

Nếu không thể di chuyển code đến server component, bạn vẫn có thể linh hoạt trong việc load code trên client bằng Code Splitting.

Next.js có built-in code splitting. Mỗi trang đều nhận được một đoạn mã chunk riêng và có thể chia sẻ các phần code chung.

🔎 Ví Dụ - Dynamic Import

const Modal = dynamic(() => import("./Modal"), {
  // Loading state to show while the code is loading
  // This is optional
  // If something takes a while, this is good to have!
  loading: () => Loading...,
});

export default function Page() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <>
       setIsOpen(true)}>Open Modal
      {isOpen && }
    >
  );
}

Giờ đây mã chỉ được tải khi mà người dùng nhấp vào nút, đấy gọi là Dynamic import
Đôi khi component sử dụng browser API như window hoặc document. Trong trường hợp này bạn có thể set skip server rendering

const BrowserOnlyComponent = dynamic(() => import("./Heavy"), {
  ssr: false,
});

Thành phần này sẽ chỉ tải và kết xuất trên client

🛠️ Giảm Dung Lượng Phụ Thuộc Các Dependencies

🌿 Tree Shaking

Cho phép bạn chỉ nhập những gì bạn cần. Ví dụ:

// Bad: Imports everything
import * as Icons from '@react-icons/all-files'

// Good: Only imports what you use
import { FaGithub } from '@react-icons/all-files/fa/FaGithub'

Một số thư viện như Lodash yêu cầu những cách tiếp cận khác nhau bạn cần nhập trực tiếp từ những đường dẫn cụ thể

// With lodash, use direct paths
import map from 'lodash/map'

🌿 Loading on demand

Bạn chỉ cần tải thư viện khi bạn cần nó

// Instead of importing at the top
import fuse from "fuse.js";
import imageCompression from "browser-image-compression";

// Load libraries when needed
// Example 1
async function handleSearch(query) {
  const Fuse = (await import("fuse.js")).default;
  const fuse = new Fuse(items);
  return fuse.search(query);
}

// Example 2
async function handleImageUpload(file) {
  // Only load compression library when user uploads an image
  const imageCompression = (await import("browser-image-compression")).default;
  const compressedFile = await imageCompression(file, {
    maxSizeMB: 1,
    maxWidthOrHeight: 1920,
  });
  // Upload compressedFile
}

🌿 Finding alternatives

Đôi khi có những gói, thư viện nhỏ hơn mà làm được điều tương tự:

  • moment.js (71KB)date-fns (12KB)
  • lodash (71KB)Chỉ import các hàm cần thiết
  • Thư viện biểu đồ nặngLựa chọn các thư viện nhẹ hơn

📚Tham Khảo Thêm

  • optimizePackageImports
  • Lựa chọn các chiến lược hợp lý như:
    • Streaming and Partial Rendering
    • Client-Side Rendering (CSR)
    • Incremental Static Regeneration (ISR)
    • Static Site Generation (SSG)
    • Server-Side Rendering (SSR)