Hướng dẫn Flutter Performance Optimization (rebuild, jank, R8, ProGuard)

Tóm tắt nhanh
Tìm hiểu các kỹ thuật tối ưu hiệu suất Flutter: giảm rebuilds, loại bỏ jank, và sử dụng R8/ProGuard để tối ưu app size.
Mục lục bài viết (39)
- 1. Giảm Rebuilds không cần thiết
- Vấn đề:
- Giải pháp:
- 2. Loại bỏ Jank (Frame Drops)
- Jank là gì?
- Nguyên nhân:
- Giải pháp:
- 3. Tối ưu Images
- 1. Sử dụng Image.asset với cache
- 2. Sử dụng cached_network_image
- 3. Lazy load images
- 4. Tối ưu Lists
- 1. Sử dụng ListView.builder
- 2. Sử dụng itemExtent
- 3. Sử dụng addAutomaticKeepAlives
- 5. R8 và ProGuard
- R8 (Android)
- ProGuard (Android)
- 6. Build Optimization
- 1. Split APKs
- 2. Enable Tree Shaking
- 3. Remove Unused Assets
- 7. Memory Optimization
- 1. Dispose Resources
- 2. Weak References
- 8. Performance Monitoring
- 1. Flutter DevTools
- 2. Timeline
- Best Practices
- 1. Const Everything
- 2. Avoid setState trong build()
- 3. Use Keys đúng cách
- Đo trước khi tối ưu
- Bốn nguyên nhân gây chậm phổ biến nhất
- Những chỗ KHÔNG nên tối ưu
- Ngăn chặn hỏi phục về hiệu năng
- Kết luận
- Tóm tắt:
- Học Flutter bài bản theo lộ trình

Performance là yếu tố quan trọng quyết định trải nghiệm người dùng. Bài viết này sẽ hướng dẫn bạn các kỹ thuật tối ưu hiệu suất Flutter từ cơ bản đến nâng cao.
1. Giảm Rebuilds không cần thiết
Vấn đề:
Widget rebuild quá nhiều lần làm giảm performance:
[object Object]Giải pháp:
1. Sử dụng const constructors
[object Object]2. Tách StatefulWidget nhỏ
[object Object]3. Sử dụng ValueNotifier
[object Object]2. Loại bỏ Jank (Frame Drops)
Jank là gì?
Jank xảy ra khi frame render mất hơn 16ms (60 FPS) hoặc 8ms (120 FPS).
Nguyên nhân:
- Heavy computations trên UI thread
- Large widget trees
- Expensive rebuilds
- Synchronous operations
Giải pháp:
1. Sử dụng compute() cho heavy tasks
[object Object]2. Lazy Loading
[object Object]3. Sử dụng RepaintBoundary
[object Object]4. Debounce và Throttle
[object Object]3. Tối ưu Images
1. Sử dụng Image.asset với cache
[object Object]2. Sử dụng cached_network_image
[object Object]3. Lazy load images
[object Object]4. Tối ưu Lists
1. Sử dụng ListView.builder
[object Object]2. Sử dụng itemExtent
[object Object]3. Sử dụng addAutomaticKeepAlives
[object Object]5. R8 và ProGuard
R8 (Android)
R8 là công cụ shrink và obfuscate code cho Android.
Setup:
[object Object]ProGuard Rules:
[object Object]ProGuard (Android)
ProGuard giúp:
- Shrink: Xóa code không dùng
- Obfuscate: Làm khó đọc code
- Optimize: Tối ưu bytecode
6. Build Optimization
1. Split APKs
[object Object]2. Enable Tree Shaking
[object Object]3. Remove Unused Assets
[object Object]7. Memory Optimization
1. Dispose Resources
[object Object]2. Weak References
[object Object]8. Performance Monitoring
1. Flutter DevTools
[object Object]2. Timeline
[object Object]Best Practices
1. Const Everything
[object Object]2. Avoid setState trong build()
[object Object]3. Use Keys đúng cách
[object Object]Đo trước khi tối ưu
Quy tắc đầu tiên và cũng là quy tắc quan trọng nhất: không tối ưu theo cảm giác. Hầu hết thời gian của nhóm bị dùng cho những chỗ không phải nguyên nhân, và việc tối ưu sai chỗ còn có thể làm code khó đọc hơn mà không cải thiện gì.
Quy trình đúng gồm ba bước:
- Tái hiện vấn đề trên máy thật ở chế độ phát hành hoặc profile. Chế độ gỡ lỗi chậm hơn nhiều lần và số đo không dùng được để kết luận.
- Xác định vấn đề nằm ở luồng giao diện hay luồng vẽ. Nếu ở luồng giao diện, nguyên nhân thường là code chạy quá nhiều hoặc vẽ lại quá mức. Nếu ở luồng vẽ, nguyên nhân thường là ảnh quá lớn, bóng đổ phức tạp, hoặc hiệu ứng nặng.
- Sửa một chỗ, đo lại, rồi mới sửa tiếp. Việc sửa nhiều chỗ cùng lúc khiến bạn không biết thay đổi nào thật sự có tác dụng.
Một mẹo thực tế: ghi lại số đo trước và sau mỗi thay đổi vào phần mô tả yêu cầu hợp nhất. Sau vài tháng, nhóm sẽ có dữ liệu thật về những gì ảnh hưởng tới hiệu năng của sản phẩm.
Bốn nguyên nhân gây chậm phổ biến nhất
Kinh nghiệm từ nhiều dự án cho thấy bốn nguyên nhân dưới đây chiếm phần lớn vấn đề về tốc độ:
1. Vẽ lại quá nhiều. Một thay đổi nhỏ ở cấp cao làm cả cây giao diện dựng lại. Cách xử lý: thu hẹp phạm vi lắng nghe, tách thành phần, dùng giá trị const cho phần tĩnh.
2. Ảnh sai kích thước. Đây là nguyên nhân phổ biến nhất gây tốn bộ nhớ và giật khi cuộn. Hãy yêu cầu ảnh đúng kích thước hiển thị, và dùng bộ nhớ đệm theo kích thước cho các danh sách dài.
3. Danh sách không tải lười. Danh sách dựng toàn bộ phần tử sẽ chậm ngay cả khi mỗi phần tử đơn giản. Ngoài việc dùng danh sách có tải lười, hãy đặt chiều cao cố định cho dòng nếu có thể.
4. Tính toán nặng trên luồng giao diện. Việc phân tích dữ liệu lớn, xử lý ảnh hay mã hoá đều có thể làm khựng giao diện. Những việc này nên chuyển sang luồng nền.
Những chỗ KHÔNG nên tối ưu
Tối ưu quá mức gây thiệt hại thật, vì nó làm code khó đọc và khó sửa hơn:
- Màn hình đã mượt. Nếu không có số liệu cho thấy vấn đề, đừng thêm lớp bộ nhớ đệm hoặc cơ chế phức tạp.
- Hàm chỉ chạy khi người dùng bấm nút. Việc tối ưu vài phần nghìn giây ở đây không có ý nghĩa.
- Đoạn code chạy khi khởi động nhưng chỉ vài chục mili giây. Trừ khi khởi động chậm rõ rệt, đừng đánh đổi tính rõ ràng của code.
Tiêu chí quyết định luôn là số đo. Nếu bạn không nêu được con số cụ thể trước và sau, rất có thể thay đổi đó không cần thiết.
Ngăn chặn hỏi phục về hiệu năng
Hiệu năng thường bị xuống cấp dần theo từng thay đổi nhỏ. Ba cách giữ ổn định:
- Kiểm tra hiệu năng ở những màn hình quan trọng trước mỗi bản phát hành, theo cùng một cách mỗi lần để có thể so sánh.
- Ghi lại ngưỡng kích thước tệp phát hành. Khi kích thước tăng đột biến, nguyên nhân thường là một thư viện mới được thêm vào.
- Kiểm tra kích thước ảnh trong quy trình đóng góp mã, vì ảnh là nguyên nhân phổ biến nhất và cũng dễ kiểm tra nhất.
Kết luận
Tối ưu performance giúp:
- ✅ Ứng dụng mượt mà hơn
- ✅ Giảm memory usage
- ✅ Giảm app size
- ✅ Trải nghiệm người dùng tốt hơn
Tóm tắt:
- Reduce Rebuilds: Const widgets, tách StatefulWidget
- Eliminate Jank: compute(), lazy loading, debounce
- Optimize Images: Cache, resize, lazy load
- Optimize Lists: ListView.builder, itemExtent
- R8/ProGuard: Shrink và obfuscate code
- Memory: Dispose resources, weak references
- Monitoring: DevTools, Timeline
Áp dụng các kỹ thuật này sẽ giúp ứng dụng Flutter của bạn nhanh và mượt mà hơn!
Học Flutter bài bản theo lộ trình
Nếu bạn muốn học có người sửa bài thay vì tự ghép tài liệu, Flutter Hướng Nghiệp đào tạo theo 3 cấp:
- Flutter Cơ Bản — Dart, widget, giao diện, 28 buổi.
- Flutter Nâng Cao — state management, REST API, Firebase, 28 buổi.
- Flutter Chuyên Sâu — back-end, AI/ML, publish lên store, 53 buổi.
Lớp online trực tiếp qua Zoom/Google Meet, có bản ghi lại — không bắt buộc đến cơ sở.
Xem lịch khai giảng hoặc so sánh 5 cách học lập trình mobile nếu còn phân vân.
