9.1 服务端渲染缓存策略

9.1.1 多级缓存架构

// cache/CacheManager.js
const LRU = require('lru-cache')
const Redis = require('ioredis')
const crypto = require('crypto')

class CacheManager {
  constructor(options = {}) {
    this.options = {
      redis: {
        host: process.env.REDIS_HOST || 'localhost',
        port: process.env.REDIS_PORT || 6379,
        password: process.env.REDIS_PASSWORD,
        db: 0
      },
      memory: {
        max: 1000,
        maxAge: 5 * 60 * 1000 // 5分钟
      },
      page: {
        max: 5000,
        maxAge: 15 * 60 * 1000 // 15分钟
      },
      component: {
        max: 10000,
        maxAge: 30 * 60 * 1000 // 30分钟
      },
      ...options
    }

    this.initializeCaches()
  }

  initializeCaches() {
    // Redis缓存
    this.redis = new Redis(this.options.redis)
    
    // 内存缓存
    this.memoryCache = new LRU(this.options.memory)
    
    // 页面缓存
    this.pageCache = new LRU(this.options.page)
    
    // 组件缓存
    this.componentCache = new LRU(this.options.component)
    
    // 数据缓存
    this.dataCache = new LRU({
      max: 2000,
      maxAge: 10 * 60 * 1000 // 10分钟
    })
  }

  // 生成缓存键
  generateKey(prefix, data) {
    const hash = crypto
      .createHash('md5')
      .update(JSON.stringify(data))
      .digest('hex')
    return `${prefix}:${hash}`
  }

  // 页面缓存
  async getPage(key) {
    // 先检查内存缓存
    let cached = this.pageCache.get(key)
    if (cached) {
      return { data: cached, source: 'memory' }
    }

    // 检查Redis缓存
    try {
      cached = await this.redis.get(`page:${key}`)
      if (cached) {
        const data = JSON.parse(cached)
        // 回写到内存缓存
        this.pageCache.set(key, data)
        return { data, source: 'redis' }
      }
    } catch (error) {
      console.error('Redis get error:', error)
    }

    return null
  }

  async setPage(key, data, ttl = 900) {
    // 设置内存缓存
    this.pageCache.set(key, data)

    // 设置Redis缓存
    try {
      await this.redis.setex(`page:${key}`, ttl, JSON.stringify(data))
    } catch (error) {
      console.error('Redis set error:', error)
    }
  }

  // 组件缓存
  getComponent(key) {
    return this.componentCache.get(key)
  }

  setComponent(key, data) {
    this.componentCache.set(key, data)
  }

  // 数据缓存
  async getData(key) {
    // 先检查内存
    let cached = this.dataCache.get(key)
    if (cached) {
      return { data: cached, source: 'memory' }
    }

    // 检查Redis
    try {
      cached = await this.redis.get(`data:${key}`)
      if (cached) {
        const data = JSON.parse(cached)
        this.dataCache.set(key, data)
        return { data, source: 'redis' }
      }
    } catch (error) {
      console.error('Redis get error:', error)
    }

    return null
  }

  async setData(key, data, ttl = 600) {
    this.dataCache.set(key, data)
    
    try {
      await this.redis.setex(`data:${key}`, ttl, JSON.stringify(data))
    } catch (error) {
      console.error('Redis set error:', error)
    }
  }

  // 智能缓存失效
  async invalidate(pattern) {
    // 清除内存缓存
    if (pattern.includes('page')) {
      this.pageCache.reset()
    }
    if (pattern.includes('component')) {
      this.componentCache.reset()
    }
    if (pattern.includes('data')) {
      this.dataCache.reset()
    }

    // 清除Redis缓存
    try {
      const keys = await this.redis.keys(pattern)
      if (keys.length > 0) {
        await this.redis.del(...keys)
      }
    } catch (error) {
      console.error('Redis invalidate error:', error)
    }
  }

  // 缓存统计
  getStats() {
    return {
      memory: {
        size: this.memoryCache.length,
        max: this.memoryCache.max
      },
      page: {
        size: this.pageCache.length,
        max: this.pageCache.max
      },
      component: {
        size: this.componentCache.length,
        max: this.componentCache.max
      },
      data: {
        size: this.dataCache.length,
        max: this.dataCache.max
      }
    }
  }

  // 预热缓存
  async warmup(routes) {
    console.log('开始缓存预热...')
    
    for (const route of routes) {
      try {
        // 这里可以调用渲染函数来预热页面缓存
        console.log(`预热路由: ${route}`)
        // await this.renderAndCache(route)
      } catch (error) {
        console.error(`预热失败 ${route}:`, error)
      }
    }
    
    console.log('缓存预热完成')
  }
}

module.exports = CacheManager

9.1.2 智能缓存策略

// cache/SmartCache.js
class SmartCache {
  constructor(cacheManager) {
    this.cache = cacheManager
    this.hitRates = new Map()
    this.accessPatterns = new Map()
  }

  // 记录访问模式
  recordAccess(key, hit = false) {
    const now = Date.now()
    
    // 记录命中率
    if (!this.hitRates.has(key)) {
      this.hitRates.set(key, { hits: 0, total: 0 })
    }
    
    const stats = this.hitRates.get(key)
    stats.total++
    if (hit) stats.hits++
    
    // 记录访问模式
    if (!this.accessPatterns.has(key)) {
      this.accessPatterns.set(key, [])
    }
    
    const pattern = this.accessPatterns.get(key)
    pattern.push(now)
    
    // 只保留最近1小时的访问记录
    const oneHourAgo = now - 60 * 60 * 1000
    this.accessPatterns.set(key, pattern.filter(time => time > oneHourAgo))
  }

  // 计算缓存优先级
  calculatePriority(key) {
    const hitRate = this.getHitRate(key)
    const frequency = this.getAccessFrequency(key)
    const recency = this.getRecency(key)
    
    // 综合评分:命中率 * 0.4 + 访问频率 * 0.4 + 最近访问 * 0.2
    return hitRate * 0.4 + frequency * 0.4 + recency * 0.2
  }

  getHitRate(key) {
    const stats = this.hitRates.get(key)
    if (!stats || stats.total === 0) return 0
    return stats.hits / stats.total
  }

  getAccessFrequency(key) {
    const pattern = this.accessPatterns.get(key)
    if (!pattern) return 0
    
    const now = Date.now()
    const oneHourAgo = now - 60 * 60 * 1000
    const recentAccesses = pattern.filter(time => time > oneHourAgo)
    
    return recentAccesses.length / 60 // 每分钟访问次数
  }

  getRecency(key) {
    const pattern = this.accessPatterns.get(key)
    if (!pattern || pattern.length === 0) return 0
    
    const lastAccess = Math.max(...pattern)
    const now = Date.now()
    const timeDiff = now - lastAccess
    
    // 最近访问的权重更高
    return Math.max(0, 1 - timeDiff / (60 * 60 * 1000))
  }

  // 智能TTL计算
  calculateTTL(key, baseTime = 300) {
    const priority = this.calculatePriority(key)
    const frequency = this.getAccessFrequency(key)
    
    // 高优先级和高频访问的内容缓存时间更长
    let ttl = baseTime
    
    if (priority > 0.8) {
      ttl *= 3 // 高优先级缓存3倍时间
    } else if (priority > 0.5) {
      ttl *= 2 // 中等优先级缓存2倍时间
    }
    
    if (frequency > 10) {
      ttl *= 2 // 高频访问缓存2倍时间
    }
    
    return Math.min(ttl, 3600) // 最大1小时
  }

  // 预测性缓存
  async predictiveCache(userContext) {
    const predictions = this.predictNextPages(userContext)
    
    for (const prediction of predictions) {
      if (prediction.probability > 0.7) {
        // 预加载高概率页面
        await this.preloadPage(prediction.route)
      }
    }
  }

  predictNextPages(userContext) {
    // 基于用户行为预测下一个可能访问的页面
    const { currentRoute, userAgent, referrer, sessionData } = userContext
    
    const predictions = []
    
    // 基于路由模式预测
    if (currentRoute === '/products') {
      predictions.push({
        route: '/products/category/electronics',
        probability: 0.6,
        reason: 'common_navigation'
      })
    }
    
    if (currentRoute.startsWith('/product/')) {
      predictions.push({
        route: '/cart',
        probability: 0.4,
        reason: 'purchase_flow'
      })
    }
    
    // 基于用户历史行为预测
    if (sessionData && sessionData.viewedCategories) {
      sessionData.viewedCategories.forEach(category => {
        predictions.push({
          route: `/products/category/${category}`,
          probability: 0.3,
          reason: 'user_interest'
        })
      })
    }
    
    return predictions.sort((a, b) => b.probability - a.probability)
  }

  async preloadPage(route) {
    try {
      // 检查是否已缓存
      const cacheKey = this.cache.generateKey('page', { route })
      const cached = await this.cache.getPage(cacheKey)
      
      if (!cached) {
        // 异步预加载
        setTimeout(async () => {
          try {
            // 这里调用实际的渲染函数
            console.log(`预加载页面: ${route}`)
            // await renderPage(route)
          } catch (error) {
            console.error(`预加载失败 ${route}:`, error)
          }
        }, 100)
      }
    } catch (error) {
      console.error(`预加载错误 ${route}:`, error)
    }
  }

  // 缓存分析报告
  generateReport() {
    const report = {
      timestamp: new Date().toISOString(),
      totalKeys: this.hitRates.size,
      topPerformers: [],
      lowPerformers: [],
      recommendations: []
    }
    
    // 分析性能
    for (const [key, stats] of this.hitRates.entries()) {
      const hitRate = stats.hits / stats.total
      const frequency = this.getAccessFrequency(key)
      const priority = this.calculatePriority(key)
      
      const item = { key, hitRate, frequency, priority }
      
      if (hitRate > 0.8 && frequency > 5) {
        report.topPerformers.push(item)
      } else if (hitRate < 0.3 && frequency > 1) {
        report.lowPerformers.push(item)
      }
    }
    
    // 生成建议
    if (report.lowPerformers.length > 0) {
      report.recommendations.push({
        type: 'cache_strategy',
        message: `发现${report.lowPerformers.length}个低效缓存项,建议调整缓存策略`
      })
    }
    
    if (report.topPerformers.length > 10) {
      report.recommendations.push({
        type: 'cache_expansion',
        message: '高效缓存项较多,建议增加缓存容量'
      })
    }
    
    return report
  }
}

module.exports = SmartCache

9.2 流式渲染

9.2.1 流式SSR实现

// streaming/StreamRenderer.js
const { Readable } = require('stream')
const { createBundleRenderer } = require('vue-server-renderer')

class StreamRenderer {
  constructor(serverBundle, options = {}) {
    this.renderer = createBundleRenderer(serverBundle, {
      ...options,
      runInNewContext: false
    })
  }

  // 流式渲染
  renderToStream(context) {
    return new Promise((resolve, reject) => {
      const stream = this.renderer.renderToStream(context)
      const chunks = []
      
      stream.on('data', chunk => {
        chunks.push(chunk)
      })
      
      stream.on('end', () => {
        resolve(Buffer.concat(chunks).toString())
      })
      
      stream.on('error', reject)
    })
  }

  // 渐进式流式渲染
  async progressiveRender(context, res) {
    try {
      // 发送HTML头部
      const htmlStart = this.getHTMLStart(context)
      res.write(htmlStart)
      
      // 创建渲染流
      const renderStream = this.renderer.renderToStream(context)
      
      // 处理流数据
      renderStream.on('data', chunk => {
        res.write(chunk)
      })
      
      renderStream.on('end', () => {
        // 发送HTML尾部
        const htmlEnd = this.getHTMLEnd(context)
        res.write(htmlEnd)
        res.end()
      })
      
      renderStream.on('error', error => {
        console.error('Stream render error:', error)
        res.status(500).end('Render Error')
      })
      
    } catch (error) {
      console.error('Progressive render error:', error)
      res.status(500).end('Server Error')
    }
  }

  // 分块渲染
  async chunkRender(context, res) {
    const chunks = await this.getChunks(context)
    
    // 发送初始HTML
    res.write(this.getHTMLStart(context))
    
    // 逐个渲染组件块
    for (const chunk of chunks) {
      try {
        const html = await this.renderChunk(chunk, context)
        res.write(html)
        
        // 添加延迟以模拟渐进加载
        if (chunk.priority === 'low') {
          await this.delay(50)
        }
      } catch (error) {
        console.error(`Chunk render error for ${chunk.name}:`, error)
        res.write(`<!-- Error rendering ${chunk.name} -->`)
      }
    }
    
    res.write(this.getHTMLEnd(context))
    res.end()
  }

  async getChunks(context) {
    // 分析路由组件,确定渲染优先级
    const route = context.url
    
    const chunks = [
      {
        name: 'header',
        component: 'AppHeader',
        priority: 'high',
        critical: true
      },
      {
        name: 'navigation',
        component: 'AppNavigation',
        priority: 'high',
        critical: true
      },
      {
        name: 'main-content',
        component: 'MainContent',
        priority: 'high',
        critical: true
      },
      {
        name: 'sidebar',
        component: 'AppSidebar',
        priority: 'medium',
        critical: false
      },
      {
        name: 'footer',
        component: 'AppFooter',
        priority: 'low',
        critical: false
      }
    ]
    
    // 根据路由调整优先级
    if (route.startsWith('/product/')) {
      chunks.find(c => c.name === 'main-content').priority = 'critical'
    }
    
    return chunks.sort((a, b) => {
      const priorityOrder = { critical: 0, high: 1, medium: 2, low: 3 }
      return priorityOrder[a.priority] - priorityOrder[b.priority]
    })
  }

  async renderChunk(chunk, context) {
    // 这里实现具体的组件渲染逻辑
    // 可以使用缓存、并行渲染等优化技术
    
    const cacheKey = `chunk:${chunk.name}:${context.url}`
    
    // 检查缓存
    if (this.cache) {
      const cached = await this.cache.getComponent(cacheKey)
      if (cached) {
        return cached
      }
    }
    
    // 渲染组件
    const html = await this.renderComponent(chunk.component, context)
    
    // 缓存结果
    if (this.cache && !chunk.critical) {
      await this.cache.setComponent(cacheKey, html)
    }
    
    return html
  }

  async renderComponent(componentName, context) {
    // 模拟组件渲染
    return `<div class="${componentName.toLowerCase()}">
      <!-- ${componentName} content -->
    </div>`
  }

  getHTMLStart(context) {
    return `<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <title>${context.title || 'Vue SSR App'}</title>
  ${context.renderResourceHints()}
  ${context.renderStyles()}
</head>
<body>
  <div id="app">`
  }

  getHTMLEnd(context) {
    return `  </div>
  ${context.renderState()}
  ${context.renderScripts()}
</body>
</html>`
  }

  delay(ms) {
    return new Promise(resolve => setTimeout(resolve, ms))
  }
}

module.exports = StreamRenderer

9.2.2 客户端流式激活

// client/streaming-hydration.js
class StreamingHydration {
  constructor() {
    this.pendingComponents = new Set()
    this.hydratedComponents = new Set()
    this.observers = new Map()
  }

  // 初始化流式激活
  init() {
    this.setupIntersectionObserver()
    this.setupMutationObserver()
    this.startHydration()
  }

  // 设置交叉观察器
  setupIntersectionObserver() {
    if (!window.IntersectionObserver) return
    
    this.intersectionObserver = new IntersectionObserver(
      (entries) => {
        entries.forEach(entry => {
          if (entry.isIntersecting) {
            this.hydrateComponent(entry.target)
          }
        })
      },
      {
        rootMargin: '50px 0px',
        threshold: 0.1
      }
    )
  }

  // 设置变化观察器
  setupMutationObserver() {
    this.mutationObserver = new MutationObserver((mutations) => {
      mutations.forEach(mutation => {
        mutation.addedNodes.forEach(node => {
          if (node.nodeType === Node.ELEMENT_NODE) {
            this.scanForComponents(node)
          }
        })
      })
    })
    
    this.mutationObserver.observe(document.body, {
      childList: true,
      subtree: true
    })
  }

  // 开始激活过程
  startHydration() {
    // 优先激活关键组件
    this.hydrateCriticalComponents()
    
    // 延迟激活非关键组件
    requestIdleCallback(() => {
      this.hydrateNonCriticalComponents()
    })
  }

  // 激活关键组件
  hydrateCriticalComponents() {
    const criticalComponents = document.querySelectorAll('[data-critical="true"]')
    
    criticalComponents.forEach(element => {
      this.hydrateComponent(element)
    })
  }

  // 激活非关键组件
  hydrateNonCriticalComponents() {
    const nonCriticalComponents = document.querySelectorAll('[data-component]:not([data-critical="true"])')
    
    nonCriticalComponents.forEach(element => {
      if (this.isInViewport(element)) {
        this.hydrateComponent(element)
      } else {
        this.intersectionObserver.observe(element)
      }
    })
  }

  // 激活单个组件
  async hydrateComponent(element) {
    const componentName = element.getAttribute('data-component')
    
    if (this.hydratedComponents.has(element) || this.pendingComponents.has(element)) {
      return
    }
    
    this.pendingComponents.add(element)
    
    try {
      // 动态导入组件
      const component = await this.loadComponent(componentName)
      
      // 创建Vue实例并挂载
      const instance = this.createComponentInstance(component, element)
      await this.mountComponent(instance, element)
      
      this.hydratedComponents.add(element)
      element.setAttribute('data-hydrated', 'true')
      
      // 触发激活事件
      this.emitHydrationEvent(element, componentName)
      
    } catch (error) {
      console.error(`Failed to hydrate component ${componentName}:`, error)
    } finally {
      this.pendingComponents.delete(element)
    }
  }

  // 动态加载组件
  async loadComponent(componentName) {
    const componentMap = {
      'AppHeader': () => import('../components/AppHeader.vue'),
      'AppNavigation': () => import('../components/AppNavigation.vue'),
      'MainContent': () => import('../components/MainContent.vue'),
      'AppSidebar': () => import('../components/AppSidebar.vue'),
      'AppFooter': () => import('../components/AppFooter.vue')
    }
    
    const loader = componentMap[componentName]
    if (!loader) {
      throw new Error(`Unknown component: ${componentName}`)
    }
    
    const module = await loader()
    return module.default || module
  }

  // 创建组件实例
  createComponentInstance(component, element) {
    const props = this.extractProps(element)
    const data = this.extractData(element)
    
    return new Vue({
      ...component,
      propsData: props,
      data() {
        return {
          ...data,
          ...(typeof component.data === 'function' ? component.data() : component.data || {})
        }
      }
    })
  }

  // 提取属性
  extractProps(element) {
    const propsData = element.getAttribute('data-props')
    return propsData ? JSON.parse(propsData) : {}
  }

  // 提取数据
  extractData(element) {
    const data = element.getAttribute('data-state')
    return data ? JSON.parse(data) : {}
  }

  // 挂载组件
  async mountComponent(instance, element) {
    return new Promise((resolve, reject) => {
      try {
        instance.$mount(element)
        
        // 等待下一个tick确保挂载完成
        instance.$nextTick(() => {
          resolve(instance)
        })
      } catch (error) {
        reject(error)
      }
    })
  }

  // 检查元素是否在视口中
  isInViewport(element) {
    const rect = element.getBoundingClientRect()
    return (
      rect.top >= 0 &&
      rect.left >= 0 &&
      rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
      rect.right <= (window.innerWidth || document.documentElement.clientWidth)
    )
  }

  // 扫描新添加的组件
  scanForComponents(element) {
    const components = element.querySelectorAll('[data-component]:not([data-hydrated])')
    
    components.forEach(component => {
      if (this.isInViewport(component)) {
        this.hydrateComponent(component)
      } else {
        this.intersectionObserver.observe(component)
      }
    })
  }

  // 触发激活事件
  emitHydrationEvent(element, componentName) {
    const event = new CustomEvent('component:hydrated', {
      detail: {
        element,
        componentName,
        timestamp: Date.now()
      }
    })
    
    element.dispatchEvent(event)
    document.dispatchEvent(event)
  }

  // 获取激活统计
  getStats() {
    return {
      hydrated: this.hydratedComponents.size,
      pending: this.pendingComponents.size,
      total: document.querySelectorAll('[data-component]').length
    }
  }

  // 清理资源
  destroy() {
    if (this.intersectionObserver) {
      this.intersectionObserver.disconnect()
    }
    
    if (this.mutationObserver) {
      this.mutationObserver.disconnect()
    }
    
    this.pendingComponents.clear()
    this.hydratedComponents.clear()
  }
}

// 初始化流式激活
if (typeof window !== 'undefined') {
  const hydration = new StreamingHydration()
  
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', () => {
      hydration.init()
    })
  } else {
    hydration.init()
  }
  
  // 暴露到全局以便调试
  window.__STREAMING_HYDRATION__ = hydration
}

export default StreamingHydration

9.3 微前端集成

9.3.1 微前端架构设计

// microfrontend/MicroFrontendManager.js
class MicroFrontendManager {
  constructor() {
    this.apps = new Map()
    this.routes = new Map()
    this.sharedDependencies = new Map()
    this.eventBus = new EventTarget()
  }

  // 注册微前端应用
  registerApp(config) {
    const {
      name,
      entry,
      routes,
      container,
      activeWhen,
      props = {},
      sandbox = true
    } = config

    const app = {
      name,
      entry,
      routes,
      container,
      activeWhen,
      props,
      sandbox,
      status: 'NOT_LOADED',
      instance: null,
      sandboxInstance: null
    }

    this.apps.set(name, app)
    
    // 注册路由
    routes.forEach(route => {
      this.routes.set(route, name)
    })

    console.log(`Registered micro frontend: ${name}`)
  }

  // 加载微前端应用
  async loadApp(name) {
    const app = this.apps.get(name)
    if (!app) {
      throw new Error(`App ${name} not found`)
    }

    if (app.status === 'LOADED' || app.status === 'LOADING') {
      return app
    }

    app.status = 'LOADING'

    try {
      // 创建沙箱环境
      if (app.sandbox) {
        app.sandboxInstance = this.createSandbox(app)
      }

      // 加载应用资源
      const resources = await this.loadResources(app.entry)
      
      // 执行应用代码
      const appExports = await this.executeApp(resources, app)
      
      app.instance = appExports
      app.status = 'LOADED'
      
      // 触发加载完成事件
      this.emitEvent('app:loaded', { name, app })
      
      return app
    } catch (error) {
      app.status = 'LOAD_ERROR'
      console.error(`Failed to load app ${name}:`, error)
      throw error
    }
  }

  // 挂载微前端应用
  async mountApp(name, props = {}) {
    const app = await this.loadApp(name)
    
    if (app.status !== 'LOADED') {
      throw new Error(`App ${name} is not loaded`)
    }

    try {
      // 准备挂载容器
      const container = this.prepareContainer(app.container)
      
      // 合并属性
      const mountProps = {
        ...app.props,
        ...props,
        container,
        eventBus: this.eventBus
      }

      // 调用应用的mount方法
      if (app.instance && typeof app.instance.mount === 'function') {
        await app.instance.mount(mountProps)
        app.status = 'MOUNTED'
        
        this.emitEvent('app:mounted', { name, app })
      }
    } catch (error) {
      console.error(`Failed to mount app ${name}:`, error)
      throw error
    }
  }

  // 卸载微前端应用
  async unmountApp(name) {
    const app = this.apps.get(name)
    if (!app || app.status !== 'MOUNTED') {
      return
    }

    try {
      // 调用应用的unmount方法
      if (app.instance && typeof app.instance.unmount === 'function') {
        await app.instance.unmount()
      }

      // 清理容器
      this.cleanupContainer(app.container)
      
      // 清理沙箱
      if (app.sandboxInstance) {
        app.sandboxInstance.destroy()
      }

      app.status = 'UNMOUNTED'
      
      this.emitEvent('app:unmounted', { name, app })
    } catch (error) {
      console.error(`Failed to unmount app ${name}:`, error)
    }
  }

  // 创建沙箱环境
  createSandbox(app) {
    return new Sandbox({
      name: app.name,
      globals: this.getSharedGlobals()
    })
  }

  // 获取共享的全局变量
  getSharedGlobals() {
    return {
      Vue: window.Vue,
      VueRouter: window.VueRouter,
      Vuex: window.Vuex,
      axios: window.axios,
      // 其他共享依赖
      ...Object.fromEntries(this.sharedDependencies)
    }
  }

  // 加载应用资源
  async loadResources(entry) {
    if (typeof entry === 'string') {
      // 单个入口文件
      return await this.loadScript(entry)
    } else if (Array.isArray(entry)) {
      // 多个资源文件
      const resources = await Promise.all(
        entry.map(url => this.loadScript(url))
      )
      return resources.join('\n')
    } else if (typeof entry === 'object') {
      // 详细配置
      const { js = [], css = [] } = entry
      
      // 加载CSS
      await Promise.all(css.map(url => this.loadCSS(url)))
      
      // 加载JS
      const scripts = await Promise.all(js.map(url => this.loadScript(url)))
      return scripts.join('\n')
    }
  }

  // 加载脚本
  async loadScript(url) {
    return new Promise((resolve, reject) => {
      fetch(url)
        .then(response => response.text())
        .then(resolve)
        .catch(reject)
    })
  }

  // 加载样式
  async loadCSS(url) {
    return new Promise((resolve, reject) => {
      const link = document.createElement('link')
      link.rel = 'stylesheet'
      link.href = url
      link.onload = resolve
      link.onerror = reject
      document.head.appendChild(link)
    })
  }

  // 执行应用代码
  async executeApp(code, app) {
    const sandbox = app.sandboxInstance
    
    if (sandbox) {
      return sandbox.execute(code)
    } else {
      // 直接执行(不推荐用于生产环境)
      return new Function('return ' + code)()
    }
  }

  // 准备挂载容器
  prepareContainer(selector) {
    let container
    
    if (typeof selector === 'string') {
      container = document.querySelector(selector)
    } else {
      container = selector
    }
    
    if (!container) {
      throw new Error(`Container not found: ${selector}`)
    }
    
    // 清空容器
    container.innerHTML = ''
    
    return container
  }

  // 清理容器
  cleanupContainer(selector) {
    const container = typeof selector === 'string' 
      ? document.querySelector(selector) 
      : selector
      
    if (container) {
      container.innerHTML = ''
    }
  }

  // 路由匹配
  matchRoute(path) {
    for (const [route, appName] of this.routes.entries()) {
      if (this.isRouteMatch(path, route)) {
        return appName
      }
    }
    return null
  }

  isRouteMatch(path, route) {
    // 简单的路由匹配逻辑
    if (route === path) return true
    if (route.endsWith('*')) {
      const prefix = route.slice(0, -1)
      return path.startsWith(prefix)
    }
    return false
  }

  // 事件发射
  emitEvent(type, detail) {
    const event = new CustomEvent(type, { detail })
    this.eventBus.dispatchEvent(event)
  }

  // 事件监听
  addEventListener(type, listener) {
    this.eventBus.addEventListener(type, listener)
  }

  // 移除事件监听
  removeEventListener(type, listener) {
    this.eventBus.removeEventListener(type, listener)
  }

  // 获取应用状态
  getAppStatus(name) {
    const app = this.apps.get(name)
    return app ? app.status : 'NOT_FOUND'
  }

  // 获取所有应用
  getAllApps() {
    return Array.from(this.apps.values())
  }
}

// 沙箱实现
class Sandbox {
  constructor(options = {}) {
    this.name = options.name || 'sandbox'
    this.globals = options.globals || {}
    this.iframe = null
    this.context = null
  }

  // 创建沙箱环境
  create() {
    // 使用iframe创建隔离环境
    this.iframe = document.createElement('iframe')
    this.iframe.style.display = 'none'
    document.body.appendChild(this.iframe)
    
    this.context = this.iframe.contentWindow
    
    // 注入共享依赖
    Object.assign(this.context, this.globals)
  }

  // 执行代码
  execute(code) {
    if (!this.context) {
      this.create()
    }
    
    try {
      return this.context.eval(code)
    } catch (error) {
      console.error(`Sandbox execution error in ${this.name}:`, error)
      throw error
    }
  }

  // 销毁沙箱
  destroy() {
    if (this.iframe) {
      document.body.removeChild(this.iframe)
      this.iframe = null
      this.context = null
    }
  }
}

module.exports = MicroFrontendManager

9.3.2 微前端路由集成

// microfrontend/MicroFrontendRouter.js
class MicroFrontendRouter {
  constructor(manager, baseRouter) {
    this.manager = manager
    this.baseRouter = baseRouter
    this.currentApp = null
    this.setupRouteGuards()
  }

  // 设置路由守卫
  setupRouteGuards() {
    this.baseRouter.beforeEach(async (to, from, next) => {
      try {
        await this.handleRouteChange(to, from)
        next()
      } catch (error) {
        console.error('Route change error:', error)
        next(false)
      }
    })
  }

  // 处理路由变化
  async handleRouteChange(to, from) {
    const targetApp = this.manager.matchRoute(to.path)
    
    // 如果目标应用与当前应用相同,不需要切换
    if (targetApp === this.currentApp) {
      return
    }

    // 卸载当前应用
    if (this.currentApp) {
      await this.manager.unmountApp(this.currentApp)
    }

    // 挂载目标应用
    if (targetApp) {
      await this.manager.mountApp(targetApp, {
        route: to,
        router: this.baseRouter
      })
      this.currentApp = targetApp
    } else {
      this.currentApp = null
    }
  }

  // 注册微前端路由
  registerMicroRoutes() {
    const apps = this.manager.getAllApps()
    
    apps.forEach(app => {
      app.routes.forEach(route => {
        this.baseRouter.addRoute({
          path: route,
          name: `micro-${app.name}-${route}`,
          component: {
            template: `<div id="micro-${app.name}"></div>`,
            async mounted() {
              // 组件挂载时加载微前端
              await this.$microManager.mountApp(app.name, {
                container: `#micro-${app.name}`
              })
            },
            async beforeDestroy() {
              // 组件销毁时卸载微前端
              await this.$microManager.unmountApp(app.name)
            }
          }
        })
      })
    })
  }

  // 预加载微前端
  async preloadApps(routes) {
    const preloadPromises = routes.map(async route => {
      const appName = this.manager.matchRoute(route)
      if (appName) {
        try {
          await this.manager.loadApp(appName)
          console.log(`Preloaded micro frontend: ${appName}`)
        } catch (error) {
          console.error(`Failed to preload ${appName}:`, error)
        }
      }
    })

    await Promise.allSettled(preloadPromises)
  }
}

module.exports = MicroFrontendRouter

9.4 本章小结

本章介绍了Vue SSR的高级特性与优化技巧,包括:

核心要点

  1. 服务端渲染缓存策略

    • 多级缓存架构设计
    • 智能缓存策略实现
    • 缓存性能分析与优化
  2. 流式渲染

    • 流式SSR实现原理
    • 渐进式渲染技术
    • 客户端流式激活
  3. 微前端集成

    • 微前端架构设计
    • 沙箱隔离机制
    • 路由集成方案

最佳实践

  1. 缓存优化

    • 根据访问模式调整缓存策略
    • 实施预测性缓存
    • 定期分析缓存性能
  2. 流式渲染

    • 优先渲染关键内容
    • 实施渐进式激活
    • 合理分配渲染优先级
  3. 微前端

    • 保持应用间的独立性
    • 合理共享依赖
    • 实施有效的通信机制

练习作业

  1. 实现智能缓存系统
  2. 开发流式渲染方案
  3. 集成微前端架构
  4. 性能测试与优化

下一章我们将学习Vue SSR的实战项目开发。