Câu hỏi và trả lời PV hay cho FE Senior/Principal
Câu hỏi và trả lời PV hay cho FE Senior/Principal
1) So sánh React và Vue như thế nào? Khi nào chọn React, khi nào chọn Vue?
Mình thường so sánh theo 5 tiêu chí: hệ sinh thái, mức chuẩn hoá, độ linh hoạt kiến trúc, learning curve/team fit, mục tiêu sản phẩm (scale/long-term).
React
-
Ưu: hệ sinh thái cực lớn (Next.js, React Query, TanStack, nhiều UI libs), nhiều lựa chọn kiến trúc; cộng đồng rộng → dễ tuyển; thích hợp sản phẩm scale lớn, multi-team.
-
Nhược: “quá tự do” → nếu thiếu chuẩn hoá dễ loạn (state, data fetching, folder structure, patterns). Hiện nay phải dựa mạnh vào conventions (Next App Router, React Query, ESLint rules, design system…).
Mình chọn React khi:
-
Sản phẩm scale lớn, nhiều squad cùng phát triển, cần “ecosystem leverage” (Next.js, tooling, monitoring, performance tooling).
-
Cần SSR/SSG/ISR mạnh (SEO, landing pages, content-heavy, B2C).
-
Team đã có “React maturity” hoặc cần tuyển nhanh.
Vue (Vue 3)
-
Ưu: framework “batteries included” hơn (router, state Pinia, conventions rõ), DX mượt; Composition API khá mạnh và gọn.
-
Nhược: ecosystem nhỏ hơn React (nhưng vẫn tốt); tuyển dụng tuỳ thị trường.
Mình chọn Vue khi:
-
Team cần onboard nhanh, muốn convention rõ ràng để ít tranh luận.
-
Dự án enterprise/dashboard nội bộ, tốc độ delivery quan trọng.
-
Có sẵn codebase Vue hoặc team core mạnh Vue.
Cách chốt câu phỏng vấn:
“React mạnh về hệ sinh thái và scale multi-team; Vue mạnh về DX và convention giúp team chạy nhanh. Mình chọn dựa trên team fit + nhu cầu SSR/SEO + mức độ chuẩn hoá cần thiết.”
2) Thiết kế kiến trúc frontend dự án lớn? Cấu trúc thư mục và chia module?
Mình đã làm kiến trúc theo hướng domain-driven (feature/module), ưu tiên: dễ scale theo squad, giảm coupling, dễ test và refactor.
Nguyên tắc mình hay dùng
-
Tách theo domain/feature thay vì tách theo “type” (components/pages/utils) quá sớm.
-
Public API cho mỗi module: chỉ export từ
index.tsđể kiểm soát phụ thuộc. -
Layer rõ ràng: UI ↔ application ↔ domain ↔ infrastructure.
-
Tránh shared bừa bãi: “shared” chỉ chứa thứ thật sự generic (design system, primitives).
Ví dụ cấu trúc (React/Next hoặc Vue/Nuxt đều áp dụng được)
Chia module như thế nào?
-
Module theo business capability (auth, user, billing, report…).
-
Nếu scale rất lớn: có thể tiến tới micro-frontend (Module Federation / single-spa) nhưng chỉ khi:
-
tổ chức nhiều team độc lập,
-
release cadence khác nhau,
-
và có năng lực vận hành (CI/CD, versioning, shared deps).
-
Câu chốt:
“Mình ưu tiên module theo domain + public API rõ + dependency rule (module A không import sâu module B). Nhờ vậy dự án lớn vẫn giữ được tính maintainable.”
3) Kinh nghiệm với NextJS/NuxtJS? Khi nào SSR, khi nào CSR?
Kinh nghiệm Next/Nuxt
-
Dùng để tận dụng routing + SSR/SSG/ISR + bundling + optimization.
-
Thực tế mình hay phối:
SSR/SSG cho trang cần SEO/first load, và CSR cho phần app dashboard.
Khi nào SSR?
-
SEO quan trọng (marketing pages, listing public).
-
Time-to-Content cần nhanh trên mạng yếu.
-
Nội dung phụ thuộc request (auth, geo, personalization) mà vẫn cần HTML render ban đầu.
-
Cần tốt cho share preview, bots, social crawlers.
Khi nào CSR?
-
App kiểu internal tool / dashboard, đăng nhập rồi mới dùng.
-
Dữ liệu realtime, tương tác nhiều, SEO không quan trọng.
-
Muốn giảm tải server render, đơn giản hoá caching SSR.
Bonus: SSG/ISR (nếu bạn muốn ghi điểm)
-
SSG: nội dung ít thay đổi, build ra static.
-
ISR: nội dung thay đổi theo chu kỳ, muốn “static nhưng có refresh”.
Câu chốt:
“Mình chọn SSR/SSG/ISR khi cần SEO + first content; CSR cho ứng dụng nặng tương tác sau login. Với Next/Nuxt mình hay dùng hybrid để tối ưu tổng thể.”
4) State management trong ứng dụng lớn (Redux, Zustand, Pinia, Vuex…)
Mình phân loại state trước, rồi mới chọn tool.
4 loại state mình tách
-
Server state (data từ API, cache, sync): ưu tiên React Query/TanStack Query (React) hoặc tương đương bên Vue.
-
UI state cục bộ (modal, toggle, input): dùng useState/ref tại component.
-
Client global state (auth info, theme, permission, feature flags…): dùng store nhẹ (Zustand/Redux Toolkit hoặc Pinia).
-
Form state: dùng form libs (React Hook Form / vee-validate…) + schema validation.
Tool lựa chọn
-
Redux Toolkit: khi cần chuẩn hoá nghiêm, debug tốt, middleware, complex workflows.
-
Zustand: nhẹ, ít boilerplate, rất hợp global client state vừa phải.
-
Pinia (Vue): default choice hiện đại, modular, devtools tốt.
-
Vuex: nếu legacy.
Nguyên tắc quan trọng
-
Đừng đưa server state vào Redux/Pinia nếu không cần → dễ phình store, khó cache invalidation.
-
Normalize data khi entity lớn và tái sử dụng nhiều (users, products…).
-
Quy định naming + boundaries: store theo domain, không “global store bự”.
Câu chốt:
“Mình tách server state ra khỏi client state. Server state dùng query-cache; global client state chỉ giữ những thứ thật sự cross-cutting.”
5) Tối ưu performance cho React/Vue có lượng user lớn?
Mình tối ưu theo 3 lớp: rendering, network/data, bundle/runtime, kèm observability.
Rendering / UI
-
Tránh re-render lan truyền:
-
React: memoization đúng chỗ (
memo,useMemo,useCallback) nhưng chỉ khi đo thấy cần. -
Tách component: “smart vs dumb”, hạn chế props drilling hoặc context khiến re-render rộng.
-
-
Virtualization cho list lớn (react-window/react-virtual; Vue tương đương).
-
Debounce/throttle input search, resize, scroll handlers.
-
Giảm work ở main thread: web worker cho xử lý nặng.
Network / Data
-
Cache & revalidate:
-
Dùng TanStack Query: caching, dedupe request, staleTime, retry.
-
-
Pagination / infinite scroll thay vì load all.
-
Prefetch route/data cho trang tiếp theo (Next/Nuxt hỗ trợ tốt).
-
HTTP caching / CDN cho assets và API response phù hợp.
Bundle / Runtime
-
Code splitting theo route/feature; lazy load những phần ít dùng (chart lib, editor…).
-
Tree-shaking đúng, tránh import “cả library”.
-
Tối ưu ảnh: responsive images, next/image hoặc nuxt image module.
-
SSR/SSG cho trang public để cải thiện LCP.
Observability (đây là điểm senior hay có)
-
Đặt performance budget (JS size, LCP/INP/CLS).
-
Dùng tooling: Lighthouse, Web Vitals, profiling React DevTools, runtime monitoring (Sentry/Datadog…).
-
Tối ưu dựa trên metrics thật chứ không “tối ưu cảm tính”.
Câu chốt:
“Mình tối ưu theo số đo: Web Vitals + profiling. Ưu tiên giảm work render, tối ưu cache data và chia nhỏ bundle; sau đó mới đến micro-optimizations.”