Luyện Phỏng Vấn IT — 2000+ Câu Hỏi Phỏng Vấn IT Có Đáp Án 2026

Danh mục

Performance iconPerformance

Ba Core Web Vitals: LCP (<2.5s, loading), INP (<200ms, interactivity — thay FID từ 3/2024), CLS (<0.1, visual stability) — ảnh hưởng SEO ranking từ 2021.

  • Ba Core Web Vitals là bộ metrics của Google đo trải nghiệm người dùng thực tế, ảnh hưởng đến SEO ranking từ 2021.
  • Ba metrics: LCP (Largest Contentful Paint — loading performance, target <2.5s: good, >4s: poor; đo thời gian render phần tử lớn nhất trong viewport); INP (Interaction to Next Paint — thay thế FID từ tháng 3/2024, target <200ms: good, >500ms: poor; đo total delay từ user interaction đến next paint cho tất cả interactions trong session, không chỉ first); CLS (Cumulative Layout Shift — visual stability, target <0.1: good, >0.25: poor; đo mức độ layout shift unexpected).
  • Đo lường: PageSpeed Insights (field data từ Chrome UX Report + lab data từ Lighthouse), Search Console Core Web Vitals report, web-vitals JavaScript library (import { getLCP, getINP, getCLS } from 'web-vitals').
  • Quan trọng: field data (real users) khác lab data (controlled) — optimize cho field data.
  • TTFB (Time to First Byte) không phải Core Web Vital nhưng ảnh hưởng LCP mạnh; FCP (First Contentful Paint) là diagnostic metric.

Cải thiện LCP: preload hero image, không lazy-load LCP element, serve WebP/AVIF, dùng fetchpriority="high", cải thiện TTFB với CDN — đây thường là nguyên nhân chính cho LCP >2.5s.

  • LCP đo thời gian render phần tử lớn nhất trong viewport — thường là hero image, large text block, video poster.
  • Candidates: img, image trong CSS background, video (poster), block-level text.
  • Cải thiện TTFB trước (ảnh hưởng LCP nhất): server response time, CDN, edge caching.
  • Image optimization: serve WebP/AVIF (25-50% nhỏ hơn JPEG), đúng kích thước (không serve 2000px cho 400px container), dùng responsive images với srcset.
  • Preload LCP image: <link rel='preload' as='image' href='hero.webp'> trong <head> — critical vì browser discover image late trong parsing.
  • Không lazy load LCP image: loading='lazy' trên hero image làm tăng LCP đáng kể — chỉ lazy load below-fold.
  • Eliminate render-blocking resources: defer/async non-critical JS, inline critical CSS, preconnect đến third-party domains. fetchpriority='high' attribute trên LCP image hint browser prioritize fetch.
  • Next.js next/image tự động: format conversion, responsive sizes, lazy load by default (priority prop để disable cho LCP image).
  • Thường gặp: LCP image discovered late vì được set bằng CSS background-image — browser không discover cho đến khi parse CSS; dùng <img> thay vì CSS background cho LCP element.

Fix CLS: luôn set width/height trên images/videos, reserve space cho dynamic content, dùng font-display: swap với size-adjust, dùng transform thay vì top/margin cho animations.

  • CLS đo mức độ layout shift unexpected trong quá trình loading — score là sum của (impact fraction * distance fraction) cho mỗi shift.
  • Target <0.1; >0.25 là poor.
  • Nguyên nhân phổ biến và fix: Images/videos không có dimensions — luôn set width/height attributes (aspect-ratio CSS tự tính) hoặc dùng aspect-ratio: 16/9 container; browser reserve space trước khi image load.
  • Fonts gây FOUT (Flash of Unstyled Text) khi web font load — dùng font-display: swap với size-adjust để match fallback font metrics; font-display: optional skip web font nếu không cached (zero CLS nhưng có thể không dùng web font); preload critical fonts.
  • Dynamically injected content (banners, cookie notices, ads) shift content — reserve space trước bằng min-height container; không inject content above existing content sau page load.
  • Dynamic ads: Google Ads có thể gây CLS — fix bằng reserve fixed space cho ad slot.
  • Infinite scroll: thêm items dưới thay vì trên viewport. transform: translateY() thay vì top/margin cho animations — transform không trigger layout.
  • CLS sau interaction (300ms window) không tính vào score — UX vẫn tệ nhưng không penalty.
  • Debugging: Chrome DevTools Performance panel, Layout Shift Regions (Rendering tab).

Lazy loading với loading="lazy" cho images, React.lazy() + Suspense cho components, next/dynamic cho Next.js — không lazy load LCP image và đừng lazy load quá nhiều (waterfall).

  • Lazy loading trì hoãn loading resources cho đến khi thực sự cần — giảm initial load time và Time to Interactive.
  • Images: <img loading='lazy'> attribute là native browser lazy loading, browser load image khi cần thiết khi scroll đến; không dùng cho LCP image (dùng loading='eager' hoặc priority).
  • Components trong React: const HeavyChart = React.lazy(() => import('./HeavyChart')) kết hợp <Suspense fallback={<Spinner/>}> — chunk được split tự động và load on demand; dùng cho large components, chart libraries, editors. next/dynamic trong Next.js: const DynamicMap = dynamic(() => import('./Map'), { loading: () => <p>Loading...</p>, ssr: false }) — thêm ssr: false để skip server-side rendering cho browser-only components.
  • Route-based lazy loading: React Router <Suspense> + React.lazy() mỗi route là chunk riêng — standard approach.
  • Preloading: sau lazy load, có thể preload chunk trước khi user navigate: import('./HeavyPage') trong onMouseEnter — reduce perceived latency.
  • Intersection Observer API: detect khi element vào viewport để trigger lazy load — basis của nhiều lazy loading libraries.
  • Trade-off: lazy loading adds waterfall (request phải chờ parent component render) — cẩn thận với critical path; chỉ lazy load truly non-critical components.

Route-based code splitting là chiến lược đầu tiên — mỗi route là chunk riêng; dùng bundle analyzer để tìm large deps có alternatives nhỏ hơn; prefetch chunks cho next likely navigation.

  • Code splitting chia bundle thành chunks nhỏ hơn — load initial chunk nhỏ hơn, load thêm chunks on demand.
  • Dynamic import() là foundation: import('./module') trả về Promise, bundler tự tạo separate chunk.
  • Chiến lược: Route-based splitting — mỗi route là chunk riêng, user chỉ download code cho route đang visit; pattern chuẩn với React Router và React.lazy().
  • Component-based splitting — lazy load heavy components (rich text editor, PDF viewer, 3D rendering) chỉ khi cần.
  • Vendor splitting: tách node_modules thành vendor chunk — ít thay đổi hơn app code, cache lâu hơn; Vite tự động split vendor; Webpack SplitChunksPlugin cấu hình.
  • Shared chunks: code dùng ở nhiều routes tách thành shared chunk — tránh duplicate code trong nhiều chunks.
  • Prefetching và preloading: <link rel='prefetch'> cho next likely navigation (browser idle), <link rel='preload'> cho current route critical resources; Webpack magic comments: import(/ webpackPrefetch: true / './NextPage').
  • Analysis: Webpack Bundle Analyzer, vite-bundle-visualizer, source-map-explorer để xem chunk composition và identify optimization opportunities.

Pitfall: quá nhiều chunks nhỏ tệ hơn một chunk lớn do HTTP request overhead — HTTP/2 multiplexing giảm vấn đề này nhưng có limits.

HTTP caching giảm bandwidth và latency bằng cách lưu responses tại browser hoặc CDN.

  • Cache-Control directives: max-age=3600 (cache 1 giờ trước khi stale); no-cache (phải revalidate với server trước khi dùng — không phải 'không cache'); no-store (không cache bao giờ, sensitive data); public (CDN có thể cache); private (chỉ browser cache, không CDN); immutable (content không bao giờ thay đổi, skip revalidation kể cả khi max-age expired — dùng với content-hashed assets).
  • Static assets strategy: Cache-Control: public, max-age=31536000, immutable cho files có content hash trong tên (bundle.abc123.js) — cache 1 năm, không bao giờ revalidate.
  • HTML: Cache-Control: no-cache — revalidate mỗi lần nhưng serve từ cache nếu ETag match.
  • Conditional requests: ETag (hash của content) và Last-Modified (timestamp); client gửi If-None-Match/If-Modified-Since trong request; nếu không thay đổi, server trả 304 Not Modified (no body) — tiết kiệm bandwidth.
  • Stale-While-Revalidate: Cache-Control: max-age=60, stale-while-revalidate=300 — serve stale content trong 5 phút trong khi revalidate background; zero latency impact.
  • CDN caching: Cloudflare, Vercel Edge Network cache responses — đặt s-maxage khác max-age để CDN cache lâu hơn browser.
  • Cache busting: thay đổi URL khi content thay đổi (content hash, query string ?v=2).

Image optimization là một trong các cách hiệu quả nhất để giảm page weight và cải thiện LCP.

  • Modern formats: WebP nhỏ hơn JPEG 25-34%, AVIF nhỏ hơn 50% nhưng encode chậm hơn; dùng <picture> element với fallback cho browser không support.
  • Responsive images: srcset='image-400.webp 400w, image-800.webp 800w' với sizes='(max-width: 600px) 400px, 800px' — browser chọn đúng size cho device; next/image tự động generate.
  • Correct sizing: không serve 2000px image cho 400px container — lãng phí bandwidth 25x; dùng Image CDN (Cloudinary, Imgix) để resize on demand theo URL params.
  • Compression: lossy (JPEG quality 80 thường indistinguishable từ 100), lossless (PNG, WebP lossless); tools: Squoosh, Sharp (Node.js), ImageMagick.
  • Lazy loading: loading='lazy' cho below-fold images; không lazy load LCP image.
  • Preload LCP: <link rel='preload' as='image' href='hero.webp' imagesrcset='...' imagesizes='...'> cho critical images.
  • LQIP (Low Quality Image Placeholder): show tiny blurred placeholder trong khi load — next/image placeholder='blur' prop.
  • CDN và edge: serve images từ locations gần users; modern Image CDNs auto-convert format, resize, compress based on device.
  • Sprites: combine nhiều icons thành một file — giảm HTTP requests; ngày nay SVG sprites hoặc icon fonts phổ biến hơn.

Lighthouse là công cụ của Google đánh giá website theo 4 tiêu chí:

  • Performance: lazy load images (loading='lazy'), code splitting với React.lazy, compress assets (gzip/brotli), preload fonts quan trọng.
  • Accessibility: mọi image có alt text, color contrast đủ ratio, dùng ARIA cho interactive elements.
  • Best Practices: dùng HTTPS, không console errors, không deprecated APIs.
  • SEO: meta tags đầy đủ (title, description), semantic HTML (h1, nav, main), sitemap.xml.

Mục tiêu: Performance > 90, Accessibility > 90. Đo bằng Chrome DevTools tab Lighthouse hoặc PageSpeed Insights.

Web Vitals là ba chỉ số chính mà Google dùng để đánh giá trải nghiệm người dùng thực tế trên website. LCP (Largest Contentful Paint) đo thời gian hiển thị phần tử lớn nhất, cần dưới 2.5 giây — tối ưu bằng cách preload hero image, inline critical CSS, và giảm server response time.

CLS (Cumulative Layout Shift) đo mức độ nhảy layout, cần dưới 0.1 — khắc phục bằng cách luôn set width/height cho images, reserve space cho quảng cáo và dynamic content, dùng font-display: swap để tránh font gây layout shift.

INP (Interaction to Next Paint) đo độ phản hồi khi user tương tác, cần dưới 200ms — cải thiện bằng cách break long tasks thành chunks nhỏ hơn, defer non-critical JavaScript, và dùng Web Workers cho tính toán nặng. Đo các chỉ số này bằng Chrome DevTools tab Performance hoặc thư viện web-vitals trong code.

LCP (Largest Contentful Paint) đo thời gian phần tử lớn nhất hiển thị trên màn hình, phản ánh tốc độ tải trực quan. INP (Interaction to Next Paint) đo thời gian phản hồi của tất cả tương tác trong suốt vòng đời trang, không chỉ tương tác đầu tiên — thay thế FID từ tháng 3/2024 trong Core Web Vitals. CLS (Cumulative Layout Shift) đo mức độ dịch chuyển layout bất ngờ, ảnh hưởng đến trải nghiệm ổn định thị giác. TTFB (Time to First Byte) đo thời gian từ lúc gửi request đến khi nhận byte đầu tiên từ server.

Để tối ưu: lazy load hình ảnh, code splitting, minify tài nguyên, cache hiệu quả, dùng CDN, và tối ưu server response time.

Browser rendering pipeline gồm các bước:

  1. parse HTML thành DOM tree,
  2. parse CSS thành CSSOM tree,
  3. kết hợp DOM và CSSOM thành render tree,
  4. tính toán layout (vị trí, kích thước),
  5. paint (vẽ pixel),
  6. composite (ghép các layer)

Critical rendering path là chuỗi bước tối thiểu trình duyệt phải hoàn thành trước khi hiển thị trang — CSS và JavaScript mặc định sẽ block quá trình render.

Tối ưu bằng cách: inline critical CSS, defer hoặc async cho JavaScript, giảm kích thước CSS/JS, và dùng DevTools Coverage để tìm code không sử dụng.