26年前端面试高频场景题全解析(含实战方案与资源推荐)

一、设备与浏览器环境检测

1.1 用户设备类型判断

在跨端开发中,准确识别用户设备类型是实现响应式布局的基础。传统方案依赖navigator.userAgent字符串解析,但存在维护成本高、容易被篡改的问题。现代方案推荐使用User-Agent Client Hints API,通过响应头Accept-CH: Sec-CH-UA-Platform获取标准化设备信息。

  1. // 示例:通过Client Hints获取设备类型
  2. async function getDeviceType() {
  3. const hints = await fetch('/api/hints', {
  4. headers: { 'Accept-CH': 'Sec-CH-UA-Platform' }
  5. });
  6. const platform = hints.headers.get('Sec-CH-UA-Platform');
  7. return /Android|iPhone/i.test(platform) ? 'mobile' : 'desktop';
  8. }

1.2 页面可见性检测

Page Visibility API可有效监测用户是否处于当前标签页,常用于视频播放暂停、数据上报优化等场景。通过监听visibilitychange事件,结合document.visibilityState属性实现:

  1. document.addEventListener('visibilitychange', () => {
  2. if (document.visibilityState === 'hidden') {
  3. console.log('页面进入后台');
  4. // 暂停非关键任务
  5. } else {
  6. console.log('页面回到前台');
  7. // 恢复任务执行
  8. }
  9. });

二、性能优化实战

2.1 长任务(Long Task)监控

主线程阻塞超过50ms的任务会被标记为长任务,直接影响页面响应速度。使用PerformanceObserver监听longtask条目:

  1. const observer = new PerformanceObserver((list) => {
  2. list.getEntries().forEach(entry => {
  3. console.warn(`Long task detected: ${entry.duration}ms`);
  4. // 可上报至监控系统
  5. });
  6. });
  7. observer.observe({ entryTypes: ['longtask'] });

2.2 静态资源加载耗时统计

全站资源性能监控需结合PerformanceResourceTiming接口,通过performance.getEntriesByType('resource')获取所有资源加载数据:

  1. function logResourceTimings() {
  2. const resources = performance.getEntriesByType('resource');
  3. resources.forEach(res => {
  4. console.log({
  5. name: res.name,
  6. duration: res.duration,
  7. initiatorType: res.initiatorType
  8. });
  9. });
  10. }
  11. // 在页面卸载前触发
  12. window.addEventListener('beforeunload', logResourceTimings);

2.3 大文件分片上传优化

分片上传需解决三个核心问题:分片大小选择、并发控制、断点续传。推荐采用动态分片策略:

  1. const CHUNK_SIZE = 5 * 1024 * 1024; // 初始5MB
  2. async function uploadFile(file) {
  3. const totalChunks = Math.ceil(file.size / CHUNK_SIZE);
  4. const uploadTasks = [];
  5. for (let i = 0; i < totalChunks; i++) {
  6. const start = i * CHUNK_SIZE;
  7. const end = Math.min(start + CHUNK_SIZE, file.size);
  8. const chunk = file.slice(start, end);
  9. uploadTasks.push(
  10. fetch('/upload', {
  11. method: 'POST',
  12. body: chunk,
  13. headers: { 'Content-Range': `bytes ${start}-${end-1}/${file.size}` }
  14. })
  15. );
  16. }
  17. await Promise.all(uploadTasks);
  18. }

三、工程化实践方案

3.1 防重复请求机制

实现请求防重需结合请求标识与锁机制。推荐使用AbortController取消重复请求:

  1. const pendingRequests = new Map();
  2. async function fetchWithLock(url, options) {
  3. if (pendingRequests.has(url)) {
  4. pendingRequests.get(url).abort();
  5. }
  6. const controller = new AbortController();
  7. pendingRequests.set(url, controller);
  8. try {
  9. const response = await fetch(url, {
  10. ...options,
  11. signal: controller.signal
  12. });
  13. pendingRequests.delete(url);
  14. return response;
  15. } catch (err) {
  16. if (err.name !== 'AbortError') {
  17. pendingRequests.delete(url);
  18. throw err;
  19. }
  20. }
  21. }

3.2 精准埋点数据上报

浏览器关闭前的埋点上报需使用navigator.sendBeacon(),该方法允许在页面卸载阶段可靠发送小数据量请求:

  1. window.addEventListener('beforeunload', () => {
  2. const analyticsData = JSON.stringify({
  3. event: 'page_exit',
  4. timestamp: Date.now()
  5. });
  6. const success = navigator.sendBeacon(
  7. '/api/analytics',
  8. analyticsData
  9. );
  10. if (!success) {
  11. // 降级方案:使用同步XMLHttpRequest或localStorage暂存
  12. localStorage.setItem('pendingAnalytics', analyticsData);
  13. }
  14. });

3.3 Git错误定位技巧

当需要定位引入错误的commit时,可使用git bisect进行二分查找:

  1. # 启动二分查找
  2. git bisect start
  3. # 标记已知的正确commit
  4. git bisect good v1.0.0
  5. # 标记已知的错误commit
  6. git bisect bad main
  7. # 自动测试脚本(需自定义)
  8. git bisect run ./test-script.sh

四、进阶资源推荐

  1. 刷题平台:某代码托管平台提供的前端面试题库(含200+场景题)
  2. 性能工具:行业常见技术方案的Lighthouse集成方案
  3. 监控系统:开源APM工具集,支持自定义Long Task监控
  4. 学习路径:前端性能优化专项课程(涵盖Resource Timing API深度解析)

掌握这些核心场景题的解决思路,不仅能应对面试挑战,更能在实际项目中提升开发质量。建议结合具体业务场景进行实践验证,持续优化技术方案。