Khi các ứng dụng web hiện đại ngày càng phức tạp, việc duy trì hiệu suất của chúng trở nên khó khăn hơn. Đó là lý do tại sao việc tối ưu hóa hiệu suất ứng dụng ngay từ đầu là rất cần thiết.
Với sự ra đời của các framework như Nextjs, một framework React phổ biến, chúng có thể tạo một ứng dụng web hoàn chỉnh chỉ trong vài phút. Nextjs cung cấp nhiều tính năng tích hợp sẵn bao gồm server-side rendering, static site generationà nhiều tối ưu hóa tích hợp sẵn để cải thiện hiệu suất ứng dụng.
Bài viết này sẽ tập trung vào việc tối ưu hóa hiệu suất build ứng dụng Next.js, giúp đẩy nhanh tốc độ build, rút ngắn thời gian phát triển và nâng cao hiệu suất tổng thể của ứng dụng.
Optimizing build là gì?
Hiệu suất build là thời gian cần thiết để build ứng dụng, hay nói cách khác là thời gian để biên dịch và tạo ra các tệp tĩnh. Một hiệu suất build nhanh giúp chúng ta lặp lại quy trình phát triển nhanh hơn, bàn giao ứng dụng cho người dùng một cách nhanh chóng và tối ưu hóa hiệu suất ứng dụng..
Nhiều yếu tố có thể ảnh hưởng đến hiệu suất build, bao gồm:
- Kích thước ứng dụng: Ứng dụng càng lớn, thời gian build càng lâu.
- Số lượng dependencies: Các dependencies không cần thiết sẽ làm tăng kích thước ứng dụng và thời gian build.
- Trang và components: Số lượng trang và components càng nhiều, thời gian build càng lâu.
Hiệu suất build chậm sẽ ảnh hưởng trực tiếp đến hiệu suất tổng thể của ứng dụng, làm giảm trải nghiệm người dùng.
Các cách tối ưu hóa hiệu suất build ứng dụng Next.js
1. Sử dụng phiên mới nhất của Nextjs
Cách đơn giản nhất để cải thiện hiệu suất build là sử dụng phiên bản ổn định mới nhất của Next.js. Nhóm phát triển Next.js thường xuyên cập nhật framework, bổ sung các tính năng và tối ưu hóa hiệu suất mới. Phiên bản ổn định mới nhất hiện nay là v14.2.
Chúng ta có thể kiểm tra phiên bản mới nhất và nâng cấp web bằng lệnh:
npm install next@latest
Lưu ý khi nâng cấp hẳn 1 version ví dụ từ 13 lên 14, Nextjs có rất nhiều sự thay đổi, vì vậy hãy đảm bảo ứng dụng hiện tại của bạn thích hợp được tốt nhất với phiên bản mới, để tránh gây lỗi.
2.Tối ưu hóa tĩnh
Nếu ứng dụng không có route động, Next.js sẽ tự động hiển thị ứng dụng dưới dạng HTML tĩnh theo mặc định. Trong trường hợp này, các trang sẽ được build một lần và được phục vụ cho tất cả người dùng, giúp giảm thời gian tải trang.
Đối với các trang có route động hoặc lấy dữ liệu từ API bên ngoài, có thể sử dụng các hàm getServerSideProps hoặc getInitialProps để prerender trang trên server, lấy dữ liệu cần thiết và gửi HTML cho máy khách. Cách này giúp cải thiện thời gian tải ban đầu và hiệu suất tổng thể của trang.
3. Code splitting
Code splitting là quá trình chia code của chúng ta thành các phần nhỏ hơn. Mỗi phần chứa code cần thiết cho một trang cụ thể.
Mặc định, Next.js sẽ tự động chia mã của chúng ta thành các khối nhỏ hơn để giảm thời gian cần thiết để tải cho ứng dụng. Điều này có nghĩa là Next.js sẽ chỉ load các mã cần thiết cho trang đó trong lần tải ban đầu.
Để tận dụng thêm lợi ích của code splitting, chúng ta có thể sử dụng dynamic imports để load code cho một trang cụ thể khi cần. Code splitting rất hữu ích cho các trang được truy cập không thường xuyên.
4.Tối ưu hoá ảnh
Chúng ta có thể sử dụng thành phần next/image, là thẻ <img> tích hợp sẵn của Next.js, để tự động tối ưu hình ảnh với tính năng lazy loading và tự động thay đổi kích thước hoặc nén hình ảnh dựa trên kích thước thiết bị.
Lazy loading là quá trình tải hình ảnh chỉ khi cần thiết, tức là khi chúng hiển thị trên màn hình. Tối ưu hình ảnh tự động giảm thời gian tải hình ảnh trong ứng dụng, từ đó cải thiện hiệu suất đáng kể.
Chúng ta cũng có thể chỉ định một số hình ảnh nên được tải ban đầu bằng cách đặt thuộc tính “priority” trên thành phần next/image thành true. Next.js sẽ ưu tiên tải những hình ảnh cần thiết mà chúng ta muốn tải đầu tiên.
5.Tối ưu font
Next.js cung cấp thành phần next/font
giúp bạn tối ưu hóa phông chữ, tự động hosting Google Fonts và tránh các vấn đề như thay đổi bố cục hoặc hiện thị văn bản.
6.Prefetching
Prefetching là việc load code cho một trang cụ thể trước khi người dùng điều hướng đến trang đó. Mặc định, khi chúng ta sử dụng thành phần Link từ next/link, Next.js sẽ tự động prefetch cho trang mà người dùng có khả năng truy cập tiếp theo.
Khi trang ban đầu được tải, các liên kết hiển thị trên màn hình sẽ được prefetch. Điều này rất hữu ích cho các trang được truy cập thường xuyên.
Đối với các trang được truy cập ít thường xuyên hơn, chúng ta có thể sử dụng thuộc tính prefetch trên thành phần Link và đặt nó thành false để vô hiệu hóa prefetching cho trang đó. Với cách tiếp cận này, mã cho trang sẽ chỉ được prefetch khi người dùng di chuột qua liên kết.
Tùy thuộc vào trường hợp sử dụng, chúng ta có thể cải thiện hiệu suất của ứng dụng bằng cách prefetch, giảm thời gian cần thiết để load cho trang tiếp theo.
7.Tối ưu hóa các script của bên thứ ba
Next.js cung cấp một thành phần next/script để tải các script của bên thứ ba. Theo mặc định, thành phần này cho phép chúng ta tải các script sớm, nhưng sau khi một số nội dung quan trọng đã tải để tránh chặn việc tải trang.
Next.js cũng đảm bảo rằng một script chỉ được tải một lần, điều này rất hữu ích cho các script được sử dụng trên nhiều trang trong ứng dụng của chúng ta. Ngay cả khi người dùng điều hướng đến một trang không sử dụng script, script sẽ không được tải lại khi người dùng điều hướng đến một trang sử dụng nó.
8.Tối ưu hóa Large Contentful Paint
Large Contentful Paint (LCP) là một số liệu Core Web Vitals đo lường thời gian cần thiết để phần tử nội dung lớn nhất trong khung nhìn hiển thị. LCP rất quan trọng vì nó đo lường tốc độ tải được cảm nhận của ứng dụng của chúng ta.
Các công cụ như Lighthouse và PageSpeed Insights của google có thể giúp chúng ta cải thiện LCP của ứng dụng. Một số cách để nâng cao LCP của ứng dụng bao gồm:
- Giảm thiểu tài nguyên chặn kết xuất: Các tài nguyên chặn kết xuất, như các tệp CSS và JavaScript, ngăn trình duyệt kết xuất trang. Giảm thiểu số lượng tài nguyên chặn kết xuất có thể cải thiện LCP của ứng dụng.
- Giảm thiểu công việc trên luồng chính: Luồng chính của ứng dụng phân tích HTML, thực thi JavaScript và kết xuất trang. Giảm thiểu lượng công việc trên luồng chính có thể cải thiện LCP của ứng dụng.
- Giảm thời gian thực thi JavaScript: JavaScript là ngôn ngữ đơn luồng, có nghĩa là chỉ một tác vụ được thực thi tại một thời điểm. Giảm lượng JavaScript thực thi trên luồng chính có thể cải thiện LCP của ứng dụng.
- Sử dụng async và thành phần next/script để tải script: Cho phép trình duyệt tải script một cách bất đồng bộ mà không chặn việc kết xuất trang cũng có thể giúp cải thiện LCP của ứng dụng.
9.Tối ưu hoá CSS và JS
Tối ưu hóa CSS và JavaScript loại bỏ các ký tự không cần thiết khỏi các tệp CSS và JavaScript của bạn mà không thay đổi chức năng của chúng. Tránh sử dụng CSS thêm các ký tự không cần thiết vào các tệp CSS.
Chúng ta cũng có thể sử dụng các công cụ như PurgeCSS để loại bỏ CSS không sử dụng khỏi ứng dụng. Điều này sẽ giảm kích thước của các tệp CSS, cải thiện LCP của ứng dụng. Tương tự, tránh sử dụng các ký tự không cần thiết trong các tệp JavaScript cải thiện LCP của ứng dụng.
10.Sử dụng phân tích bundle
Phân tích bundle là một cách tiếp cận để phân tích ứng dụng của chúng ta để giảm kích thước của nó. Với công cụ phân tích bundle, chúng ta có thể xem các mô-đun nào trong bundle ứng dụng của chúng ta chiếm nhiều dung lượng, xác định các tệp không cần thiết và tìm cách để giảm kích thước của các tệp đó hoặc xóa các tệp không sử dụng.
Một số công cụ để phân tích kích thước của ứng dụng Next.js của chúng ta bao gồm next/bundle-analyzer, webpack-bundle-analyzer và next-bundle-analyzer.
11.Loại trừ các tệp hoặc thư mục không cần thiết
Một cách khác để tối ưu hóa hiệu suất xây dựng ứng dụng Next.js của chúng ta là loại trừ các tệp hoặc thư mục không cần thiết khỏi quá trình build. Chúng ta có thể giảm thời gian build và cải thiện hiệu suất tổng thể bằng cách loại trừ các thư mục hoặc tệp cụ thể không cần thiết để hiển thị ứng dụng.
Có thể sử dụng tùy chọn exclude trong tệp next.config.js để cấu hình quá trình xây dựng để loại trừ các thư mục hoặc tệp cụ thể. Điều này cho phép chúng ta chỉ định các đường dẫn nên bị bỏ qua trong quá trình xây dựng.
Ví dụ, chúng ta có thể loại trừ các thư mục chứa các tệp phương tiện lớn, tài liệu cụ thể cho phát triển không cần thiết cho việc xây dựng sản xuất:
module.exports = {
exclude: ["**/media/**", "**/docs/**", "**/dev/**"],
};
Bằng cách loại bỏ các tài nguyên không cần thiết, chúng ta sẽ giảm lượng dữ liệu cần xử lý và bundle, dẫn đến thời gian build nhanh hơn và sử dụng tài nguyên hiệu quả hơn. Kỹ thuật tối ưu hóa này rất hữu ích khi xử lý các dự án lớn hoặc khi chúng ta có các thư mục hoặc tệp cụ thể không góp phần vào việc hiển thị.
12.Loại bỏ các dependencies không sử dụng
Các công cụ quản lý dependencies như depcheck có thể giúp xác định các dep không sử dụng. Chúng ta có thể gỡ cài đặt dependencies không sử dụng, giảm kích thước ứng dụng và cải thiện hiệu suất build.
Kết luận
Việc tối ưu hóa hiệu suất build ứng dụng Next.js là rất cần thiết để có được trải nghiệm người dùng tốt nhất. Hãy tận dụng các kỹ thuật được giới thiệu trong bài viết này để cải thiện hiệu suất build của ứng dụng Next.js, đảm bảo trải nghiệm người dùng tốt nhất và nâng cao hiệu suất tổng thể của ứng dụng.