Câu chuyện tái cấu trúc tech stack của Facebook
(engineering.fb.com)Facebook, khởi đầu với PHP đơn giản, đã chuyển sang React + Relay(GraphQL) để phù hợp với thiết kế mới lần này; đây là quá trình và những bài học rút ra
Áp dụng các nguyên tắc cơ bản cho một ứng dụng nhanh ở từng mảng CSS, JS, Data, Navigation
-
Chỉ truyền những tài nguyên cần thiết và truyền nhanh nhất có thể
-
Trải nghiệm kỹ thuật phục vụ trải nghiệm người dùng
CSS
-
Giảm 80% CSS bằng Atomic CSS, đồng thời thay đổi để không phải tải về CSS không cần thiết
-
Dùng rems để hỗ trợ khả năng truy cập; để giảm lỗi khi chuyển đổi thủ công từ px → rems, công cụ build sẽ tự động chuyển đổi
-
Dùng biến CSS cho Theming (dark mode)
-
Dùng Inline SVG để tránh hiện tượng nhấp nháy (thay vì đưa file SVG vào
img). Nhờ đó cũng có thể đổi màu ngay trong runtime
JS
- Chia nhỏ code JS thành 3 tầng và truyền theo từng giai đoạn
Tier 1. Bố cục cơ bản để hiển thị nhanh UI Skeleton khi tải
Tier 2. JS để render đầy đủ toàn bộ nội dung đang thấy trên màn hình. Phải hoạt động hoàn chỉnh, và dù code có tiếp tục tải sau Tier 2 thì bố cục màn hình cũng không được thay đổi
Tier 3. Mọi thứ cần sau khi màn hình đã hiển thị. Code logging, đăng ký cập nhật thời gian thực, v.v.
-
500KB JS được tách thành 50KB Tier 1, 150KB Tier 2, 300KB Tier 3 → tạo hiệu quả là việc tải và hiển thị màn hình hoàn tất rất nhanh
-
Nhờ việc phân tách, khi A/B test cũng có thể cấu hình để mỗi bên chỉ nhận phần code cần thiết
-
Tận dụng tính năng của Relay giúp xây dựng ứng dụng React hướng dữ liệu, thay đổi để chỉ tải các component cần thiết tùy theo dữ liệu sẽ được lấy về
-
Áp dụng cơ chế JS Budget riêng cho từng Product. Đặt ngân sách dựa trên mục tiêu hiệu năng, ràng buộc kỹ thuật và các cân nhắc về sản phẩm. Ngăn code phình to theo thời gian.
Data
-
Dùng Relay để chuẩn hóa toàn bộ việc fetch dữ liệu bằng GraphQL
-
Nhờ Relay, có thể tải song song trước các dữ liệu cần thiết ngay từ giai đoạn request trang. Giúp hiển thị nhanh trên màn hình
-
Dùng @stream, một phần mở rộng nội bộ của GraphQL, để gửi dữ liệu tuần tự trong một query duy nhất cho những thứ như News Feed mà không cần nhiều round trip
-
Dùng @defer + React Suspense để tải sau những dữ liệu chưa cần ngay lập tức
Navigation
-
Khi điều hướng SPA, xây dựng Route Map để giảm thời gian tải tài nguyên và số round trip khi tải trang mới
-
Chia nhỏ và tải thông tin Route vào Route Map nhanh nhất có thể mỗi khi cần
-
Prefetch tài nguyên sớm nhất có thể (prefetch khi hover, lấy code và dữ liệu khi mousedown, và khi click thì thay đổi state của React)
-
Thay vì hiển thị màn hình trống giữa các lần điều hướng, tận dụng React Suspense transition để tiếp tục hiển thị Route cũ trước khi lấy Route mới
-
Dùng EntryPoints (một file nhỏ bọc điểm phân nhánh code và data query) để song song hóa việc tải code và dữ liệu
2 bình luận
Những điều rút ra từ CSS của thiết kế mới trên Facebook https://vi.news.hada.io/topic?id=1819
Bạn cũng nên tham khảo thêm bài viết đó.
Relay - Ứng dụng khách GraphQL sẵn sàng cho môi trường production dành cho React https://relay.dev/