Mẹo tối ưu hoá webpack webpack

Do hoàn cảnh xô đẩy nên tôi ngoài việc “Trên thông A.I, dưới thạo M.L”, phải đá sang MEARN stack. Sau một thời gian dùng webpack để build thì song song với việc nhàn hạ thì tôi đã gặp ác mộng khi dung lượng của file bundle càng ngày càng phình ra ảnh hưởng lớn tới tốc độ tải trang web. Bài này  tập trung về giải pháp tối ưu hoá dung lượng bundle.

1. Giới thiệu nhanh về webpack

Hiện tại các website đang tiến tới xu hướng trở thành những web app với các đặc tính sau:

  • Sử dụng Javascrip nhiều hơn
  • Hạn chế phát triển full-page reload, tập trung single-page app.
  • Webbrower hỗ trợ được nhiều công nghệ mới

Vì vậy webpack là 1 công cụ hữu hiệu để quản số lượng source code khổng lồ phía client-side.

Do mục đích của bài viết chỉ tập trung về việc tối ưu hóa dung lượng của bundle được webpack tạo ra, nên tôi xin phép sẽ không đi sâu vào việc giới thiệu webpack ở đây.

2. Vấn đề phát sinh

Khó có thể chấp nhận được 1 file bundle.js có dung lượng 8 MB (chưa minify) hoặc 5 MB (đã minify) dẫn tới việc tải file này mất ~4 phút từ server Mỹ, dẫn đến thời gian người dùng chờ tải trang web thành 1 cực hình.

Dưới đây là quá trình build file từ webpack.

File bundle.js nặng 8.58 MB khi chưa thực hiện minify

Dung lượng giảm xuống còn 5.08 MB khi thực hiện minify:

Sau quá trình trên tôi đã tạo ra 1 file bundle.js duy nhất, chứa toàn bộ source code của phía frontend (trừ các file ảnh).

Mổ xẻ nội dung file bundle.js này sẽ giúp tôi phán đoán được dung lượng các thành phần cấu tạo nên file:

Có 3 thành phần chiếm phần lớn dung lượng của file bundle.js này

  • font chữ
  • node_module
  • source code dự án

Hừm, việc nhét tất cả resouce vào 1 file được cái lợi nhàn hạ trước mắt cuối cùng cũng đã biến thành cơn ác mộng của những người làm lập trình chân chính

 

Ok, ngừng kêu la, gạt nước mũi và bắt tay vào việc giải quyết vấn đề

Nội dung file webpack.config.js hiện tại như sau:

  • Chỉ sử dụng 1 entry JS duy nhất

  • Đưa toàn bộ các file css, font chữ vào bundle

  • Tất cả source code được gộp chung vào 1 file duy nhất bundle.js

Ok, việc này khá tương đồng với 3 thành phần chiếm phần lớn dung lượng file bundle.js như đã phân tích bên trên.

Lọ mọ tra cứu trên mạng, tôi tổng hợp được rất nhiều phương án của con nhà người ta, tuy nhiên dưới đây là cách tôi đã áp dụng:

  • Phân chia nhỏ entry point cho những page riêng biệt.
  • Đưa toàn bộ những library dùng chung vào 1 file (vendor.js), file này sẽ được cache lại nên khi load những trang khác sẽ nhanh hơn.

Tuy nhiên bản chất của phương pháp trên chỉ là chia để trị, thay vì 1 file code to thì tôi chia ra nhiều file nhỏ và tải theo từng page cho phù hợp, tổng lại thì bundle size cũng không khác như cũ là bao nhiêu. Nhưng tốc độ sẽ được cải thiện rất nhiều do các file nhỏ sẽ được tải song song.

Sau rất nhiều lần thử sai , file webpack.config.js của tôi cuối cùng như sau:

Trong đó có những cải tiến chính như sau

-> Chuyển môi trường build sang production, giúp loại bỏ bớt các thành phần thừa chỉ dùng để test trong quá trình phát triển

-> Thực hiện minify các file javascript, việc này tương đương với việc chạy câu lệnh build webpack  -p

-> Tối ưu hóa việc sử dụng thư viện moment.js

=> Chia nhỏ webpack thành các file react.bundle.js chưa toàn bộ source code của thư viện react và vendor.bundle.js chứa toàn bộ thư viện còn lại

-> Loại bỏ toàn bộ font chữ ra khỏi bundle.

Thử build lại webpack và tận hưởng thành quả nào 🙂

Wow, ít nhất thì màu xám nhàm chán của file bundle.js đã thành xanh xanh đỏ đỏ cho em nhỏ nó mừng!!!

Nhìn thì có vẻ đẹp, còn dung lượng của file thì sao?

Dung lượng các file nhỏ đã giảm đáng kể và thời gian tải về không quá 1.84 s

 

 

TUYỆT VỜI !!!!!

 

Có phải là đã xong việc chưa nhỉ?

Nếu tinh ý, các bạn có thể thấy tôi có comment đoạn code sau

Mục đích của đoạn code này nhằm quy định dung lượng tối tiểu/ tối đa của 1 file khi file bundle sẽ được chia thành nhiều file khi CHỈ dựa vào kích thước đã được quy định sẵn.

Boom!, nếu tôi sử dụng đoạn code trên, file bundle của tôi sẽ thành thế này

 

Việc có nên chia nhỏ như thế này không, tôi sẽ để lại đôc giả tự trả lời nhé 🙂

 

3. Tóm lại

Tôi đã phân tích cách tôi giảm thời gian tải trang từ ~4 phút xuống còn 1.84 giây bằng cách tùy chỉnh lại file webpack.config.js.

Trên mạng có khá nhiều hướng dẫn với các cách tiếp cận khác nhau, tuy nhiên đối với dự án của tôi, thì cách trên là hiệu quả nhất 🙂

Các bạn có cách nào hiệu quả thì comment trao đổi nhé

in Tech


[Web API] Tạo PHP web service cho ứng dụng mobile client