我将从多个方面介绍页面性能优化的具体方法:

  1. 资源加载优化
<!-- 关键资源预加载 -->
<head>
  <!-- 预加载关键CSS -->
  <link rel="preload" href="critical.css" as="style">
  <!-- 预加载字体 -->
  <link rel="preload" href="fonts/custom.woff2" as="font" crossorigin>
  <!-- DNS预解析 -->
  <link rel="dns-prefetch" href="//api.example.com">
  <!-- 预连接 -->
  <link rel="preconnect" href="https://api.example.com">
</head>
  1. 图片优化策略
<!-- 响应式图片 -->
<picture>
  <source srcset="image-large.webp" media="(min-width: 800px)" type="image/webp">
  <source srcset="image-small.webp" media="(max-width: 799px)" type="image/webp">
  <img src="image-fallback.jpg" alt="描述" loading="lazy">
</picture>

<!-- 使用CSS处理小图片 -->
<style>
.icon {
  width: 20px;
  height: 20px;
  background-image: url('data:image/svg+xml;base64,...');
}
</style>
  1. 懒加载实现
// 图片懒加载
function lazyLoad() {
  const images = document.querySelectorAll('img[data-src]');
  const imageObserver = new IntersectionObserver((entries, observer) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        const img = entry.target;
        img.src = img.dataset.src;
        img.removeAttribute('data-src');
        observer.unobserve(img);
      }
    });
  });

  images.forEach(img => imageObserver.observe(img));
}

// 组件懒加载
const routes = [
  {
    path: '/dashboard',
    component: () => import(/* webpackChunkName: "dashboard" */ './views/Dashboard.vue')
  }
];
  1. 代码分割与缓存策略
// webpack配置
module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all'
        },
        common: {
          name: 'common',
          minChunks: 2,
          chunks: 'all',
          priority: -20
        }
      }
    }
  }
};

// Service Worker缓存
const CACHE_NAME = 'v1';
self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(CACHE_NAME).then(cache => {
      return cache.addAll([
        '/',
        '/styles/main.css',
        '/scripts/main.js'
      ]);
    })
  );
});
  1. CSS优化
/* 关键CSS内联 */
<style>
  /* 首屏关键样式 */
  .header {
    /* 样式 */
  }
</style>

/* 使用CSS containment优化渲染性能 */
.component {
  contain: content;
}

/* 避免@import */
/* 不推荐 */
@import url('other.css');

/* 推荐 */
<link rel="stylesheet" href="other.css">
  1. JavaScript优化
// 防抖函数
function debounce(fn, delay) {
  let timer = null;
  return function(...args) {
    clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  };
}

// 异步加载非关键JavaScript
function loadScript(src) {
  return new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.src = src;
    script.defer = true;
    script.onload = resolve;
    script.onerror = reject;
    document.body.appendChild(script);
  });
}
  1. 虚拟列表实现
<template>
  <div class="virtual-list" :style="{ height: totalHeight + 'px' }">
    <div class="virtual-list-content" 
         :style="{ transform: `translateY(${startOffset}px)` }">
      <div v-for="item in visibleItems" 
           :key="item.id" 
           :style="{ height: itemHeight + 'px' }">
        {{ item.content }}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [], // 所有数据
      itemHeight: 50, // 每项高度
      visibleCount: 10 // 可视区域显示数量
    }
  },
  computed: {
    totalHeight() {
      return this.items.length * this.itemHeight;
    },
    visibleItems() {
      const start = Math.floor(this.scrollTop / this.itemHeight);
      const end = start + this.visibleCount;
      return this.items.slice(start, end);
    },
    startOffset() {
      return Math.floor(this.scrollTop / this.itemHeight) * this.itemHeight;
    }
  }
}
</script>
  1. 性能监控
// 性能监控实现
const performanceMonitor = {
  init() {
    // 监控页面加载性能
    window.addEventListener('load', () => {
      const timing = performance.getEntriesByType('navigation')[0];
      const metrics = {
        DNS: timing.domainLookupEnd - timing.domainLookupStart,
        TCP: timing.connectEnd - timing.connectStart,
        TTFB: timing.responseStart - timing.requestStart,
        DomReady: timing.domContentLoadedEventEnd - timing.navigationStart,
        Load: timing.loadEventEnd - timing.navigationStart
      };
      this.sendMetrics(metrics);
    });

    // 监控资源加载性能
    const observer = new PerformanceObserver((list) => {
      const entries = list.getEntries();
      entries.forEach(entry => {
        if (entry.initiatorType === 'resource') {
          console.log(`Resource ${entry.name} took ${entry.duration}ms to load`);
        }
      });
    });
    observer.observe({ entryTypes: ['resource'] });
  },

  sendMetrics(metrics) {
    // 发送性能数据到分析服务器
    navigator.sendBeacon('/analytics', JSON.stringify(metrics));
  }
};
  1. 渲染优化
// 使用RequestAnimationFrame优化动画
function animate() {
  requestAnimationFrame(() => {
    // 执行动画
    animate();
  });
}

// 优化DOM操作
function batchDOMUpdates() {
  // 创建文档片段
  const fragment = document.createDocumentFragment();
  const items = getItems(); // 获取数据
  
  items.forEach(item => {
    const div = document.createElement('div');
    div.textContent = item;
    fragment.appendChild(div);
  });
  
  // 一次性添加到DOM
  document.getElementById('container').appendChild(fragment);
}
  1. Webpack构建优化
// webpack.config.js
module.exports = {
  // 多进程打包
  module: {
    rules: [
      {
        test: /\.js$/,
        use: 'thread-loader'
      }
    ]
  },
  
  // 压缩优化
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        parallel: true,
        terserOptions: {
          compress: {
            drop_console: true
          }
        }
      })
    ]
  },
  
  // 缓存
  cache: {
    type: 'filesystem'
  }
};

核心优化点总结:

  1. 加载优化:
  • 资源预加载和预连接
  • 图片懒加载和优化
  • 代码分割
  • 缓存策略
  1. 渲染优化:
  • 虚拟列表
  • CSS性能优化
  • 避免重排重绘
  • 使用DocumentFragment
  1. 执行优化:
  • 防抖节流
  • 异步加载
  • Web Workers
  • 代码优化
  1. 构建优化:
  • 压缩资源
  • Tree Shaking
  • 多进程打包
  • 缓存优化
  1. 监控和分析:
  • 性能指标采集
  • 性能监控系统
  • 性能分析工具