前端面试题:H5首屏优化

120 阅读3分钟

前端面试题:H5首屏优化

面试回答要体现逻辑性和模块分析能力,这个问题最好从网络层、资源层、数据请求层和渲染层进行回答,总分总结构。

一、网络层优化:资源和传输

1. 网络协议升级

  • HTTP/2多路复用:单TCP连接并行传输多个资源,完全解决HTTP/1.1的队头阻塞问题
  • QUIC协议(HTTP/3):基于UDP实现0-RTT连接,弱网环境下性能提升40%+,尤其适合移动端H5

2. 资源分发和预加载

  • CDN加速:将静态资源(JS/CSS/图片)进行分发
  • DNS优化
    <!-- DNS预解析 -->
    <link rel="dns-prefetch" href="//static.yourcdn.com">
    <!-- TCP预连接 -->
    <link rel="preconnect" href="https://api.yourdomain.com">
    

3. 链路压缩

  • Brotli压缩:比Gzip压缩性能更好。开启Brotli压缩功能后,CDN节点会对资源进行智能压缩后返回,缩小传输文件大小,提升文件传输效率,减少带宽消耗。(需服务端支持)

二、资源层优化:减小传输体积与优化加载

1. 代码分割

// vue.config.js
module.exports = {
  chainWebpack: config => {
    config.optimization.splitChunks({
      chunks: 'all',               // 对所有chunk进行分割
      maxInitialRequests: Infinity, // 初始加载时不限制并行请求数
      minSize: 20000,              // 代码分割的最小体积(20KB)
      cacheGroups: {               // 缓存组配置
        vendor: {                  // 第三方依赖分组
          test: /[\\/]node_modules[\\/]/, // 匹配node_modules中的模块
          name(module) {
            // 提取模块名称作为chunk名称
            return `npm.${module.context.match(/.*?([\\/]|$)/)[1]}`;
          }
        }
      }
    })
  }
}

2. 静态资源优化

  • 图片懒加载: 懒加载实现原理:浏览器初始加载不获取图片资源;监听图片元素进入视口时触发加载;支持IntersectionObserver API的浏览器实现检测。
    <picture>
      <source srcset="banner.avif" type="image/avif">
      <source srcset="banner.webp" type="image/webp">
      <img src="banner.jpg" alt="促销活动" 
           loading="lazy" decoding="async">
    </picture>
    
  • 字体优化:仅加载首屏必要字重
    /* 仅加载首屏必要字重 */
    @font-face {
      font-family: 'CustomFont';
      src: url('font-regular.woff2') format('woff2');
      font-weight: 400;
      font-display: swap;
    }
    

3. 资源加载优先级控制

指令适用场景示例
preload关键CSS/字体<link rel="preload" href="critical.css" as="style">
prefetch非首屏资源Vue Router组件级prefetch
preconnect核心API域名<link rel="preconnect" href="https://api.domain.com">

三、数据请求层优化:

1. 请求方案

// 数据预取与缓存混合策略
export const useHomeData = () => {
  const { data, error } = useFetch('/api/home');
  
  // 降级方案:本地缓存 + 超时控制
  useEffect(() => {
    const timer = setTimeout(() => {
      if (!data.value) {
        const cached = localStorage.getItem('homeData');
        cached && updateData(JSON.parse(cached));
      }
    }, 300);
    
    return () => clearTimeout(timer);
  }, []);
  
  // 更新缓存
  watch(data, newVal => {
    localStorage.setItem('homeData', JSON.stringify(newVal));
  });
};

2. 分层缓存

缓存类型适用场景技术实现
强缓存静态资源Cache-Control: max-age=31536000
协商缓存API数据ETag / Last-Modified
本地存储重要数据localStorage / IndexedDB
Service Worker离线访问Workbox运行时缓存

四、渲染层优化:

1. 渲染方案

方案适用场景实现方式
SSR高SEO需求页面Nuxt.js/Next.js
SSG静态内容页面VitePress/Astro
流式渲染长内容页面Vue3 Suspense + renderToNodeStream

2. 渲染优化

  • 渲染处理:

      <!-- 内联关键CSS -->
      <style>/* critical CSS here */</style>
    
      <!-- 异步加载非关键CSS -->
      <link rel="preload" href="non-critical.css" as="style" onload="this.rel='stylesheet'">
      //​​JS执行控制​​:
      <!-- 延迟非必要脚本 -->
      <script src="analytics.js" defer></script>
    
  • 部分Hydration​​:

    	// 仅激活交互区域
      import { hydrateLazy } from '@vue-lazy-hydration';
      hydrateLazy(() => import('./InteractiveComponent.vue'));
    
  • 骨架屏:优化用户感受

性能优化总结

优化维度关键措施性能提升
网络层HTTP/2 + Brotli压缩加载时间 ↓
资源层代码分割 + 图片优化资源体积 ↓
数据层请求处理 + 本地缓存TTFB ↓
渲染层SSR + 骨架屏 + 。。。FCP ↓

面试回答思路

回答模板
“首屏优化主要是为了优化用户的体验,可以从4个方面入手:

  1. 网络层:通过CDN+HTTP/2构建高速通道,解决传输效率问题
  2. 资源层:采用Tree Shaking+资源压缩+异步加载控制包体积
  3. 数据层:实施请求合并+智能缓存策略降低内容到达时间
  4. 渲染层:使用SSR+流式渲染+渐进式Hydration加速呈现
    从这四个方向入手可以极大提高首屏展示的效果,日常可以定期使用Lighthouse进行分析...拓展。