WordPress企业官网开发:技术架构与前端工程化实践

207 阅读16分钟

WordPress企业官网开发:技术架构与前端工程化实践

引言

作为前端开发者,我们经常面临使用WordPress构建企业官网的挑战。虽然WordPress被视为内容管理系统,但从技术角度看,它实际上是一个基于PHP的全栈应用框架,需要深入的前端工程化思维来突破其传统限制。本文将从资深前端开发者视角深入探讨如何构建高性能、可维护且符合现代前端标准的WordPress企业官网。

一、现代前端开发流程与WordPress集成

1. 构建系统现代化

传统WordPress开发依赖简单的PHP模板和基础JS/CSS文件,而现代企业官网需要完整的前端工程化体系支持。我们可以通过引入Node.js生态系统中的构建工具,实现资源优化、代码分割与模块化开发。

技术实现:

// webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');

module.exports = {
  entry: {
    main: './src/js/main.js',
    admin: './src/js/admin.js'
  },
  output: {
    filename: 'js/[name].js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      },
      {
        test: /\.s[ac]ss$/i,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'postcss-loader',
          'sass-loader',
        ],
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: 'css/[name].css'
    }),
    new BrowserSyncPlugin({
      proxy: 'http://localhost:8888',
      files: ['**/*.php', 'dist/css/**/*.css', 'dist/js/**/*.js'],
      injectChanges: true
    })
  ]
};

2. 组件化开发与模板系统重构

WordPress传统的模板分层系统(如header.php、footer.php和循环结构)与现代组件化开发思想存在冲突,需要通过更精细化的架构重构来提升开发效率和代码可维护性。

技术方案:

// functions.php 中的组件加载系统
function load_component($name, $args = []) {
  // 组件缓存机制,减少重复解析和执行开销
  static $component_cache = [];

  $cache_key = $name . md5(serialize($args));

  if (isset($component_cache[$cache_key])) {
    echo $component_cache[$cache_key];
    return;
  }

  ob_start();
  include get_template_directory() . "/components/{$name}.php";
  $component_cache[$cache_key] = ob_get_clean();

  echo $component_cache[$cache_key];
}

// 将React等现代框架与WordPress集成
function enqueue_react_components() {
  wp_enqueue_script('react-components',
    get_template_directory_uri() . '/dist/js/components.js',
    array(), '1.0.0', true);

  // 向React传递后端数据,形成数据桥接
  wp_localize_script('react-components', 'wpData', array(
    'restUrl' => esc_url_raw(rest_url()),
    'nonce' => wp_create_nonce('wp_rest'),
    'currentUser' => get_current_user_id(),
    'siteSettings' => get_option('site_settings')
  ));
}
add_action('wp_enqueue_scripts', 'enqueue_react_components');

// 组件示例:复用的产品卡片组件
// components/product-card.php
function product_card_component($args) {
  $defaults = array(
    'product_id' => 0,
    'show_price' => true,
    'show_rating' => true,
    'layout' => 'grid'
  );
  $config = wp_parse_args($args, $defaults);
  extract($config);

  // 缓存产品数据
  $product_data = wp_cache_get('product_' . $product_id);
  if (false === $product_data) {
    $product_data = get_product_data($product_id);
    wp_cache_set('product_' . $product_id, $product_data, '', 3600);
  }

  // 渲染模板
  include get_template_directory() . "/views/{$layout}-product.php";
}

二、前端性能优化的技术实现

1. 关键渲染路径优化

WordPress主题默认加载大量不必要资源,导致性能瓶颈。针对关键渲染路径的优化关系到用户首屏体验和搜索引擎评分,需要从多方面入手。

技术实现:

// 实现资源预加载与优先级控制
function optimize_critical_path() {
  // 内联关键CSS,减少阻塞渲染的外部CSS请求
  $critical_css = file_get_contents(get_template_directory() . '/dist/css/critical.css');
  echo '<style>' . $critical_css . '</style>';

  // 使用preload策略非阻塞加载主CSS
  echo '<link rel="preload" href="' . get_template_directory_uri() . '/dist/css/main.css" as="style" onload="this.onload=null;this.rel=\'stylesheet\'">';
  echo '<noscript><link rel="stylesheet" href="' . get_template_directory_uri() . '/dist/css/main.css"></noscript>';

  // HTTP/2 服务器推送提示
  header('Link: <' . get_template_directory_uri() . '/dist/js/critical.js>; rel=preload; as=script', false);

  // 预连接第三方资源,减少DNS查询和TCP连接时间
  echo '<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>';
  echo '<link rel="preconnect" href="https://www.google-analytics.com">';

  // 优化JavaScript加载策略
  add_filter('script_loader_tag', function($tag, $handle, $src) {
    // 关键脚本使用async,非关键脚本使用defer
    if (in_array($handle, ['jquery', 'critical-scripts'])) {
      return str_replace(' src', ' async src', $tag);
    } elseif (strpos($handle, 'admin') === false) {
      return str_replace(' src', ' defer src', $tag);
    }
    return $tag;
  }, 10, 3);

  // 使用requestIdleCallback延迟加载非关键资源
  add_action('wp_footer', function() {
    ?>
    <script>
    window.addEventListener('load', function() {
      if ('requestIdleCallback' in window) {
        requestIdleCallback(function() {
          // 延迟加载分析脚本
          var script = document.createElement('script');
          script.src = '<?php echo get_template_directory_uri(); ?>/dist/js/analytics.js';
          document.body.appendChild(script);
        }, { timeout: 2000 });
      }
    });
    </script>
    <?php
  }, 99);
}
add_action('wp_head', 'optimize_critical_path', 1);

// 资源合并与按需加载
function conditional_asset_loading() {
  // 基于当前页面类型条件加载资源
  if (is_page('contact')) {
    wp_enqueue_script('form-validation',
      get_template_directory_uri() . '/dist/js/form-validation.js',
      array(), '1.0.0', true);
  } elseif (is_singular('product')) {
    wp_enqueue_script('product-gallery',
      get_template_directory_uri() . '/dist/js/product-gallery.js',
      array(), '1.0.0', true);
  }

  // 清理WordPress自动注入的不必要资源
  if (!is_admin() && !is_singular('post')) {
    wp_dequeue_style('wp-block-library');
    wp_dequeue_style('global-styles');
    wp_dequeue_style('classic-theme-styles');
    remove_action('wp_head', 'print_emoji_detection_script', 7);
    remove_action('wp_print_styles', 'print_emoji_styles');
    remove_action('wp_head', 'wp_generator');
    remove_action('wp_head', 'wlwmanifest_link');
    remove_action('wp_head', 'rsd_link');
  }

  // 根据页面复杂度动态调整资源加载
  add_filter('script_loader_src', 'versioned_resource', 10, 2);
  add_filter('style_loader_src', 'versioned_resource', 10, 2);
}
add_action('wp_enqueue_scripts', 'conditional_asset_loading', 100);

// 生成基于内容的版本号,实现有效的长期缓存策略
function versioned_resource($src, $handle) {
  if (strpos($src, 'ver=') && !is_admin()) {
    // 计算基于文件内容的哈希版本号
    $version = get_resource_version($src);
    $src = preg_replace('/ver=([^&]*)/', 'ver=' . $version, $src);
  }
  return $src;
}

function get_resource_version($src) {
  // 从URL中提取本地文件路径
  $url_parts = parse_url($src);
  $local_path = ABSPATH . str_replace(get_site_url(), '', $url_parts['path']);

  if (file_exists($local_path)) {
    return substr(md5_file($local_path), 0, 8);
  }

  return '1.0.0'; // 默认版本号
}

2. 图像处理与响应式优化

WordPress的传统图片处理系统难以满足现代前端性能需求,需要通过自定义代码实现更高级的图像优化技术,以提升加载速度和用户体验。

技术实现:

// 高级图像处理与优化
function advanced_image_processing() {
  // 启用WebP图像支持
  function webp_upload_mimes($existing_mimes) {
    $existing_mimes['webp'] = 'image/webp';
    return $existing_mimes;
  }
  add_filter('mime_types', 'webp_upload_mimes');

  // 自动转换上传图像为WebP/AVIF格式
  function create_next_gen_images($metadata, $attachment_id) {
    if (!isset($metadata['file'])) return $metadata;

    $upload_dir = wp_upload_dir();
    $file = $upload_dir['basedir'] . '/' . $metadata['file'];
    $pathinfo = pathinfo($file);

    if (!in_array(strtolower($pathinfo['extension']), ['jpg', 'jpeg', 'png'])) return $metadata;

    $webp_file = $pathinfo['dirname'] . '/' . $pathinfo['filename'] . '.webp';
    $avif_file = $pathinfo['dirname'] . '/' . $pathinfo['filename'] . '.avif';

    // WebP转换
    if (function_exists('imagewebp')) {
      switch (strtolower($pathinfo['extension'])) {
        case 'jpeg':
        case 'jpg':
          $image = imagecreatefromjpeg($file);
          break;
        case 'png':
          $image = imagecreatefrompng($file);
          break;
        default:
          return $metadata;
      }

      if ($image) {
        imagepalettetotruecolor($image);
        imagealphablending($image, true);
        imagesavealpha($image, true);
        imagewebp($image, $webp_file, 80);

        // 记录WebP版本在元数据中
        $metadata['sizes']['webp'] = [
          'file' => pathinfo($metadata['file'])['filename'] . '.webp',
          'width' => $metadata['width'],
          'height' => $metadata['height'],
          'mime-type' => 'image/webp',
        ];
      }
    }

    // AVIF转换 (PHP 8.1+支持)
    if (function_exists('imageavif')) {
      if ($image) {
        imageavif($image, $avif_file, 65);
        imagedestroy($image);

        // 记录AVIF版本在元数据中
        $metadata['sizes']['avif'] = [
          'file' => pathinfo($metadata['file'])['filename'] . '.avif',
          'width' => $metadata['width'],
          'height' => $metadata['height'],
          'mime-type' => 'image/avif',
        ];
      }
    } elseif ($image) {
      imagedestroy($image);
    }

    return $metadata;
  }
  add_filter('wp_generate_attachment_metadata', 'create_next_gen_images', 10, 2);

  // 增强图像HTML输出,支持现代格式和延迟加载
  function enhanced_image_markup($html, $attachment_id) {
    // 只处理img标签
    if (strpos($html, '<img') === false) return $html;

    // 获取附件信息
    $attachment = get_post($attachment_id);
    if (!$attachment) return $html;

    $image_meta = wp_get_attachment_metadata($attachment_id);
    if (!is_array($image_meta)) return $html;

    // 获取上传目录信息
    $upload_dir = wp_upload_dir();
    $file_path = pathinfo($image_meta['file']);
    $base_url = $upload_dir['baseurl'] . '/' . $file_path['dirname'] . '/' . $file_path['filename'];

    // 构建<picture>元素支持AVIF和WebP
    if ((isset($image_meta['sizes']['avif']) || file_exists($upload_dir['basedir'] . '/' . $file_path['dirname'] . '/' . $file_path['filename'] . '.avif')) ||
        (isset($image_meta['sizes']['webp']) || file_exists($upload_dir['basedir'] . '/' . $file_path['dirname'] . '/' . $file_path['filename'] . '.webp'))) {

      $alt = get_post_meta($attachment_id, '_wp_attachment_image_alt', true);
      $img_class = '';
      if (preg_match('/class="([^"]*)"/', $html, $matches)) {
        $img_class = $matches[1];
      }

      // 提取原始图像src
      preg_match('/src="([^"]*)"/', $html, $src_matches);
      $original_src = isset($src_matches[1]) ? $src_matches[1] : '';

      // 获取srcset
      $srcset = wp_get_attachment_image_srcset($attachment_id, 'full');
      $sizes = wp_get_attachment_image_sizes($attachment_id, 'full');
      if (!$sizes) $sizes = '(max-width: 768px) 100vw, '.min(1200, $image_meta['width']).'px';

      // 构建picture标签
      $picture = '<picture class="responsive-picture">';

      // AVIF源
      if (isset($image_meta['sizes']['avif']) || file_exists($upload_dir['basedir'] . '/' . $file_path['dirname'] . '/' . $file_path['filename'] . '.avif')) {
        $picture .= '<source type="image/avif" srcset="' . $base_url . '.avif" sizes="' . $sizes . '">';
      }

      // WebP源
      if (isset($image_meta['sizes']['webp']) || file_exists($upload_dir['basedir'] . '/' . $file_path['dirname'] . '/' . $file_path['filename'] . '.webp')) {
        $picture .= '<source type="image/webp" srcset="' . $base_url . '.webp" sizes="' . $sizes . '">';
      }

      // 原始图像(带srcset)
      $picture .= '<img src="' . $original_src . '" ';
      if (!empty($srcset)) {
        $picture .= 'srcset="' . $srcset . '" ';
      }
      $picture .= 'sizes="' . $sizes . '" ';
      $picture .= 'class="' . $img_class . '" ';
      $picture .= 'loading="lazy" ';
      $picture .= 'alt="' . esc_attr($alt) . '" ';
      $picture .= 'width="' . $image_meta['width'] . '" ';
      $picture .= 'height="' . $image_meta['height'] . '">';
      $picture .= '</picture>';

      return $picture;
    }

    // 如果不支持新格式,至少添加lazy loading和尺寸属性
    if (!strpos($html, 'loading=')) {
      $html = str_replace('<img ', '<img loading="lazy" ', $html);
    }
    if (!strpos($html, 'width=') && isset($image_meta['width'])) {
      $html = str_replace('<img ', '<img width="' . $image_meta['width'] . '" height="' . $image_meta['height'] . '" ', $html);
    }

    return $html;
  }
  add_filter('wp_get_attachment_image', 'enhanced_image_markup', 20, 2);

  // 为内容中的图像添加延迟加载
  function add_lazy_loading_to_content_images($content) {
    return preg_replace('/<img(.*?)>/', '<img$1 loading="lazy">', $content);
  }
  add_filter('the_content', 'add_lazy_loading_to_content_images', 99);

  // 添加预加载提示,优化LCP关键图像
  function preload_hero_image() {
    if (is_front_page()) {
      $hero_image_id = get_theme_mod('hero_image_id');
      if ($hero_image_id) {
        $hero_image_url = wp_get_attachment_image_url($hero_image_id, 'full');
        echo '<link rel="preload" as="image" href="' . $hero_image_url . '">';
      }
    }
  }
  add_action('wp_head', 'preload_hero_image', 5);
}
add_action('init', 'advanced_image_processing');

// 后台图像压缩质量控制
add_filter('jpeg_quality', function($quality) {
  return 82; // 调整JPEG压缩质量,平衡文件大小和视觉质量
});

// 添加WebP CDN支持
function add_webp_support_to_cdn($url) {
  if (strpos($_SERVER['HTTP_ACCEPT'], 'image/webp') !== false) {
    if (preg_match('/\.(jpe?g|png)$/i', $url)) {
      return $url . '.webp';
    }
  }
  return $url;
}
// 根据实际CDN情况启用
// add_filter('wp_get_attachment_url', 'add_webp_support_to_cdn', 100);

三、前端与WordPress后端API集成

1. REST API与前端框架集成

WordPress REST API提供了构建现代前端应用的基础,但在企业级应用中需要考虑安全性、性能和自定义扩展。

技术实现:

// React组件与WordPress REST API集成
import React, { useState, useEffect, useCallback, useMemo } from 'react';
import axios from 'axios';
import { useInView } from 'react-intersection-observer';
import { useQuery, useInfiniteQuery } from 'react-query';

// 创建API实例,统一处理认证和错误
const api = axios.create({
  baseURL: wpData.restUrl,
  headers: {
    'X-WP-Nonce': wpData.nonce,
    'Content-Type': 'application/json'
  }
});

// 通用错误处理器
api.interceptors.response.use(
  response => response,
  error => {
    const { status, data } = error.response || {};

    // 处理常见错误
    if (status === 401) {
      // 认证失败,刷新nonce或重定向到登录
      window.location.href = wpData.loginUrl;
    } else if (status === 403) {
      console.error('权限不足:', data?.message || '未授权访问');
    } else if (status === 429) {
      console.error('请求过于频繁,请稍后再试');
    }

    // 记录错误到监控系统
    logApiError(error);

    return Promise.reject(error);
  }
);

// 产品列表组件 - 使用React Query优化数据获取
const ProductListing = () => {
  const [filter, setFilter] = useState({
    category: '',
    sortBy: 'date',
    order: 'desc'
  });

  // 使用React Query提供的缓存和请求状态管理
  const {
    data,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    status
  } = useInfiniteQuery(
    ['products', filter],
    async ({ pageParam = 1 }) => {
      const response = await api.get('wp/v2/product', {
        params: {
          page: pageParam,
          per_page: 10,
          categories: filter.category,
          orderby: filter.sortBy,
          order: filter.order
        }
      });

      return {
        results: response.data,
        pagination: {
          total: parseInt(response.headers['x-wp-total'], 10),
          totalPages: parseInt(response.headers['x-wp-totalpages'], 10),
          currentPage: pageParam
        }
      };
    },
    {
      getNextPageParam: (lastPage, pages) => {
        if (lastPage.pagination.currentPage < lastPage.pagination.totalPages) {
          return lastPage.pagination.currentPage + 1;
        }
        return undefined;
      },
      staleTime: 60000, // 数据保鲜期1分钟
      refetchOnWindowFocus: false
    }
  );

  // 懒加载触发器
  const { ref, inView } = useInView({
    threshold: 0.5,
    triggerOnce: false
  });

  // 监听视图,触发加载更多
  useEffect(() => {
    if (inView && hasNextPage && !isFetchingNextPage) {
      fetchNextPage();
    }
  }, [inView, fetchNextPage, hasNextPage, isFetchingNextPage]);

  // 过滤选项变更处理
  const handleFilterChange = useCallback((newFilter) => {
    setFilter(prev => ({ ...prev, ...newFilter }));
  }, []);

  // 提取所有产品列表
  const products = useMemo(() => {
    if (!data) return [];
    return data.pages.flatMap(page => page.results);
  }, [data]);

  // 虚拟列表渲染 - 优化大量产品展示性能
  return (
    <div className="product-listing">
      <ProductFilter currentFilter={filter} onFilterChange={handleFilterChange} />

      {status === 'loading' ? (
        <div className="loading-spinner">初始加载中...</div>
      ) : status === 'error' ? (
        <div className="error-message">加载失败,请刷新重试</div>
      ) : (
        <>
          <div className="products-grid">
            {products.map(product => (
              <ProductCard key={product.id} product={product} />
            ))}
          </div>

          <div ref={ref} className="intersection-trigger">
            {isFetchingNextPage && <div className="loading-spinner">加载更多...</div>}
            {!hasNextPage && <div className="no-more-results">没有更多产品</div>}
          </div>
        </>
      )}
    </div>
  );
};

// 后端定义 - 自定义REST API端点与安全性增强
function register_custom_api_endpoints() {
  // 注册自定义端点
  register_rest_route('company/v1', '/featured-products', array(
    'methods' => 'GET',
    'callback' => 'get_featured_products',
    'permission_callback' => '__return_true',
    // 缓存控制
    'args' => array(
      'category' => array(
        'sanitize_callback' => 'sanitize_text_field'
      ),
      'limit' => array(
        'validate_callback' => function($param) {
          return is_numeric($param) && $param > 0 && $param <= 20;
        }
      )
    )
  ));

  // 产品搜索API - 带缓存支持
  register_rest_route('company/v1', '/product-search', array(
    'methods' => 'GET',
    'callback' => 'api_product_search',
    'permission_callback' => '__return_true',
    'args' => array(
      'term' => array(
        'required' => true,
        'sanitize_callback' => 'sanitize_text_field'
      )
    )
  ));

  // 联系表单提交端点 - 带CSRF和速率限制保护
  register_rest_route('company/v1', '/contact-form', array(
    'methods' => 'POST',
    'callback' => 'handle_contact_form',
    'permission_callback' => function() {
      // 验证nonce
      return wp_verify_nonce($_SERVER['HTTP_X_WP_NONCE'], 'wp_rest');
    },
    'args' => array(
      'name' => array(
        'required' => true,
        'sanitize_callback' => 'sanitize_text_field'
      ),
      'email' => array(
        'required' => true,
        'validate_callback' => function($param) {
          return is_email($param);
        },
        'sanitize_callback' => 'sanitize_email'
      ),
      'message' => array(
        'required' => true,
        'sanitize_callback' => 'sanitize_textarea_field'
      )
    )
  ));
}
add_action('rest_api_init', 'register_custom_api_endpoints');

// 联系表单处理函数 - 带速率限制
function handle_contact_form($request) {
  // 速率限制检查
  $ip_address = get_client_ip();
  $rate_key = 'contact_rate_' . md5($ip_address);
  $submission_count = get_transient($rate_key) ?: 0;

  if ($submission_count >= 5) {
    return new WP_Error(
      'rate_limit_exceeded',
      '提交过于频繁,请稍后再试',
      array('status' => 429)
    );
  }

  // 增加提交计数并设置过期时间
  set_transient($rate_key, $submission_count + 1, 3600); // 1小时期限

  // 处理表单数据
  $name = $request->get_param('name');
  $email = $request->get_param('email');
  $message = $request->get_param('message');

  // 保存到数据库或发送邮件
  $contact_id = save_contact_submission($name, $email, $message);

  if ($contact_id) {
    // 发送通知邮件
    wp_mail(
      get_option('admin_email'),
      '新的联系表单提交',
      "姓名: $name\n邮箱: $email\n\n$message"
    );

    return array(
      'success' => true,
      'message' => '表单提交成功',
      'id' => $contact_id
    );
  }

  return new WP_Error(
    'submission_failed',
    '表单提交失败,请稍后重试',
    array('status' => 500)
  );
}

// 获取客户端IP
function get_client_ip() {
  $ip_keys = array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR');

  foreach ($ip_keys as $key) {
    if (array_key_exists($key, $_SERVER) === true) {
      foreach (explode(',', $_SERVER[$key]) as $ip) {
        $ip = trim($ip);
        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) {
          return $ip;
        }
      }
    }
  }

  return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
}

// REST API性能优化
function optimize_api_performance() {
  // 对API响应进行缓存
  add_action('rest_pre_serve_request', function($served, $result, $request, $server) {
    // 只缓存GET请求和特定端点
    $route = $request->get_route();
    if ($request->get_method() === 'GET' && strpos($route, '/wp/v2/product') === 0 || strpos($route, '/company/v1/featured-products') === 0) {
      // 设置缓存头部
      $cache_control = 'public, max-age=60, s-maxage=300';
      header('Cache-Control: ' . $cache_control);
      header('X-WP-Cache: HIT');
    }
    return $served;
  }, 10, 4);

  // 优化API响应字段
  add_filter('rest_prepare_product', function($response, $post, $request) {
    $data = $response->get_data();

    // 移除不必要的大字段
    if (isset($data['content']) && !isset($request['_embed'])) {
      unset($data['content']);
    }

    // 添加自定义字段
    $data['product_price'] = get_post_meta($post->ID, 'product_price', true);
    $data['product_rating'] = calculate_product_rating($post->ID);

    return rest_ensure_response($data);
  }, 10, 3);
}
add_action('rest_api_init', 'optimize_api_performance');

2. GraphQL与WordPress集成

使用WPGraphQL插件可以构建更高效、类型安全的数据请求模式,相比REST API具有更灵活的查询能力和更高的性能。

技术实现:

// Apollo Client与WPGraphQL集成 - 前端代码
import { ApolloClient, InMemoryCache, HttpLink, ApolloLink, concat, gql } from '@apollo/client';
import { ApolloProvider, useQuery } from '@apollo/client';
import { onError } from '@apollo/client/link/error';
import { persistCache, LocalStorageWrapper } from 'apollo3-cache-persist';

// 创建错误处理链接
const errorLink = onError(({ graphQLErrors, networkError }) => {
  if (graphQLErrors) {
    graphQLErrors.forEach(({ message, locations, path, extensions }) => {
      console.error(
        `[GraphQL 错误]: 消息: ${message}, 位置: ${JSON.stringify(locations)}, 路径: ${path}`,
        extensions
      );

      // 处理特定错误类型
      if (extensions?.code === 'UNAUTHENTICATED') {
        // 重定向到登录页面
        window.location.href = wpData.loginUrl;
      }
    });
  }

  if (networkError) {
    console.error(`[网络错误]: ${networkError}`);
    // 显示网络错误通知
    showNetworkErrorNotification();
  }
});

// 认证中间件
const authMiddleware = new ApolloLink((operation, forward) => {
  operation.setContext({
    headers: {
      'X-WP-Nonce': wpData.nonce
    }
  });

  return forward(operation);
});

// Apollo Client配置
const setupApolloClient = async () => {
  // 主缓存实例
  const cache = new InMemoryCache({
    typePolicies: {
      Product: {
        // 自定义键字段,解决WordPress ID冲突
        keyFields: ['databaseId'],
        fields: {
          price: {
            // 统一价格格式
            read(price) {
              if (price) return parseFloat(price).toFixed(2);
              return null;
            }
          }
        }
      },
      Query: {
        fields: {
          products: {
            // 自定义合并函数,处理分页数据
            keyArgs: ['where'],
            merge(existing = { nodes: [] }, incoming, { args }) {
              // 首次加载或刷新
              if (args?.first && args?.after === undefined) {
                return incoming;
              }

              // 合并分页数据
              return {
                ...incoming,
                nodes: [...existing.nodes, ...incoming.nodes],
              };
            }
          }
        }
      }
    }
  });

  // 启用缓存持久化
  await persistCache({
    cache,
    storage: new LocalStorageWrapper(window.localStorage),
    key: 'company-website-cache',
    maxSize: 2097152, // 2MB限制
    debug: process.env.NODE_ENV === 'development'
  });

  // HTTP链接
  const httpLink = new HttpLink({
    uri: '/graphql'
  });

  // 创建Apollo客户端
  return new ApolloClient({
    link: concat(authMiddleware, concat(errorLink, httpLink)),
    cache,
    defaultOptions: {
      watchQuery: {
        fetchPolicy: 'cache-and-network',
        nextFetchPolicy: 'cache-first'
      }
    }
  });
};

// 包装React应用
const App = () => {
  const [client, setClient] = React.useState(null);

  React.useEffect(() => {
    setupApolloClient().then(setClient);
  }, []);

  if (!client) {
    return <div>加载中...</div>;
  }

  return (
    <ApolloProvider client={client}>
      <CompanyWebsite />
    </ApolloProvider>
  );
};

// 产品页面获取数据示例
const ProductPage = ({ slug }) => {
  // 使用Fragment共享可重用的字段集合
  const PRODUCT_FRAGMENT = gql`
    fragment ProductFields on Product {
      id
      databaseId
      title
      slug
      date
      featuredImage {
        node {
          sourceUrl
          srcSet
          altText
        }
      }
      productCategories {
        nodes {
          id
          name
          slug
        }
      }
      productMeta {
        price
        sku
        stockStatus
        attributes {
          name
          value
        }
      }
      seo {
        title
        metaDesc
        opengraphImage {
          sourceUrl
        }
      }
    }
  `;

  // 获取产品详情
  const PRODUCT_QUERY = gql`
    query GetProduct($slug: ID!) {
      product(id: $slug, idType: SLUG) {
        ...ProductFields
        content
        related: related(first: 4) {
          nodes {
            ...ProductFields
          }
        }
      }
    }
    ${PRODUCT_FRAGMENT}
  `;

  const { loading, error, data } = useQuery(PRODUCT_QUERY, {
    variables: { slug },
    // 禁用网络优先策略,优先使用缓存以加速体验
    fetchPolicy: "cache-and-network"
  });

  if (loading) return <ProductSkeleton />;
  if (error) return <ErrorDisplay error={error} />;
  if (!data?.product) return <NotFoundPage />;

  const { product } = data;

  return (
    <div className="product-detail">
      <Helmet>
        <title>{product.seo.title}</title>
        <meta name="description" content={product.seo.metaDesc} />
        <meta property="og:image" content={product.seo.opengraphImage?.sourceUrl} />
      </Helmet>

      <div className="product-layout">
        <ProductGallery product={product} />
        <ProductInfo product={product} />
      </div>

      <ProductContent content={product.content} />

      {product.related?.nodes.length > 0 && (
        <RelatedProducts products={product.related.nodes} />
      )}
    </div>
  );
};

// 后端WPGraphQL配置与优化
function optimize_wp_graphql() {
  // 注册自定义字段
  if (function_exists('register_graphql_field')) {
    // 添加自定义产品元数据
    register_graphql_field('Product', 'productMeta', [
      'type' => 'ProductMeta',
      'description' => '产品元数据',
      'resolve' => function($product) {
        return [
          'price' => get_post_meta($product->ID, 'product_price', true),
          'sku' => get_post_meta($product->ID, 'product_sku', true),
          'stockStatus' => get_post_meta($product->ID, 'stock_status', true),
          'attributes' => get_product_attributes($product->ID),
        ];
      }
    ]);

    // 注册产品相关查询
    register_graphql_field('Product', 'related', [
      'type' => ['list_of' => 'Product'],
      'description' => '相关产品',
      'args' => [
        'first' => [
          'type' => 'Int',
          'description' => '返回数量'
        ]
      ],
      'resolve' => function($product, $args) {
        $limit = isset($args['first']) ? absint($args['first']) : 4;

        // 获取相关产品(基于分类)
        $related_ids = get_related_products($product->ID, $limit);

        if (empty($related_ids)) {
          return [];
        }

        // 获取产品对象
        return array_map(function($id) {
          return get_post($id);
        }, $related_ids);
      }
    ]);
  }

  // 缓存GraphQL查询结果
  add_filter('graphql_pre_resolve_field', function($result, $source, $args, $context, $info, $type_name, $field_key, $field, $field_resolver) {
    // 只缓存特定类型的查询
    $cacheable_types = ['Product', 'Page', 'Post', 'MediaItem'];

    if (!in_array($type_name, $cacheable_types)) {
      return $result;
    }

    // 生成缓存键
    $cache_key = 'graphql_' . md5(json_encode([
      'type' => $type_name,
      'field' => $field_key,
      'args' => $args,
      'source_id' => isset($source->ID) ? $source->ID : null
    ]));

    // 尝试从缓存获取
    $cached = wp_cache_get($cache_key, 'graphql');

    if ($cached !== false) {
      return $cached;
    }

    // 执行原始解析器
    $result = $field_resolver($source, $args, $context, $info);

    // 缓存结果
    wp_cache_set($cache_key, $result, 'graphql', 300); // 5分钟缓存

    return $result;
  }, 10, 9);

  // 限制查询深度和复杂度,防止恶意查询
  add_filter('graphql_query_analyzer_config', function($config) {
    $config['max_query_depth'] = 10;  // 最大查询深度
    $config['max_query_complexity'] = 1000; // 最大查询复杂度
    return $config;
  });
}
add_action('graphql_init', 'optimize_wp_graphql');

四、高级主题开发与模块化设计

1. WordPress主题架构设计

采用现代前端架构思想重构WordPress主题,通过模块化、面向对象和设计模式提升代码可维护性。

技术实现:

// 现代化主题目录结构
/*
theme/
├── assets/                 # 前端资源源文件
│   ├── js/
│   │   ├── components/     # JS组件
│   │   ├── utils/          # 工具函数
│   │   └── main.js         # 主入口
│   └── scss/
│       ├── abstracts/      # 变量、混合宏等
│       ├── base/           # 基础样式
│       ├── components/     # 组件样式
│       ├── layouts/        # 布局样式
│       └── main.scss       # 主入口
├── dist/                   # 编译后的资源
│   ├── js/
│   ├── css/
│   └── images/
├── inc/                    # PHP功能模块
│   ├── Core/               # 核心功能
│   │   ├── Bootstrap.php   # 主题引导类
│   │   ├── Assets.php      # 资源管理
│   │   └── ThemeSetup.php  # 主题设置
│   ├── API/                # API集成
│   │   ├── RestAPI.php     # REST API扩展
│   │   └── GraphQL.php     # GraphQL扩展
│   ├── Admin/              # 管理界面功能
│   ├── Frontend/           # 前端功能
│   ├── Blocks/             # Gutenberg区块
│   ├── Customizer/         # 主题定制器
│   └── helpers.php         # 辅助函数
├── templates/              # 页面模板
│   ├── base.php            # 基础模板
│   ├── page.php            # 页面模板
│   └── single-product.php  # 产品页模板
├── template-parts/         # 模板部件
│   ├── components/         # 组件模板
│   └── blocks/             # 区块模板
├── vendor/                 # Composer依赖
├── functions.php           # 主题功能入口
├── index.php               # WordPress入口
├── style.css               # 主题信息
├── composer.json           # Composer配置
└── package.json            # NPM配置
*/

// functions.php - 采用PSR-4自动加载与IoC容器
<?php
/**
 * 主题初始化文件
 *
 * @package CompanyTheme
 */

// 避免直接访问
if (!defined('ABSPATH')) {
  exit;
}

// 设置常量
define('THEME_DIR', get_template_directory());
define('THEME_URI', get_template_directory_uri());
define('THEME_VERSION', wp_get_theme()->get('Version'));
define('THEME_DEV_MODE', true); // 开发模式标志

// 自动加载
require_once THEME_DIR . '/vendor/autoload.php';

// 辅助函数
require_once THEME_DIR . '/inc/helpers.php';

// 使用依赖注入容器
use CompanyTheme\Core\Bootstrap;
use Psr\Container\ContainerInterface;
use DI\ContainerBuilder;

// 创建容器
$containerBuilder = new ContainerBuilder();
$containerBuilder->useAutowiring(true);

// 设置依赖定义
$containerBuilder->addDefinitions([
  // 核心服务
  'theme.assets' => function(ContainerInterface $c) {
    return new \CompanyTheme\Core\Assets();
  },
  'theme.setup' => function(ContainerInterface $c) {
    return new \CompanyTheme\Core\ThemeSetup();
  },
  // API服务
  'api.rest' => function(ContainerInterface $c) {
    return new \CompanyTheme\API\RestAPI();
  },
  'api.graphql' => function(ContainerInterface $c) {
    return new \CompanyTheme\API\GraphQL();
  },
  // 前端服务
  'frontend.optimization' => function(ContainerInterface $c) {
    return new \CompanyTheme\Frontend\Optimization();
  }
]);

// 创建容器实例
$container = $containerBuilder->build();

// 启动主题
$bootstrap = new Bootstrap($container);
$bootstrap->init();

// inc/Core/Bootstrap.php - 主题引导
namespace CompanyTheme\Core;

use Psr\Container\ContainerInterface;

/**
 * 主题引导类
 *
 * 负责初始化所有主题组件和功能
 */
class Bootstrap {
  /**
   * 依赖注入容器
   *
   * @var ContainerInterface
   */
  private $container;

  /**
   * 构造函数
   *
   * @param ContainerInterface $container 依赖注入容器
   */
  public function __construct(ContainerInterface $container) {
    $this->container = $container;
  }

  /**
   * 初始化主题
   */
  public function init() {
    // 核心功能初始化
    $this->container->get('theme.setup')->register();
    $this->container->get('theme.assets')->register();

    // API功能初始化
    if (class_exists('WP_REST_Controller')) {
      $this->container->get('api.rest')->register();
    }

    if (function_exists('register_graphql_field')) {
      $this->container->get('api.graphql')->register();
    }

    // 前端优化初始化
    $this->container->get('frontend.optimization')->register();

    // 加载Gutenberg区块
    $this->loadBlocks();

    // 自定义钩子
    do_action('company_theme_initialized', $this->container);
  }

  /**
   * 加载Gutenberg区块
   */
  private function loadBlocks() {
    $blocks_dir = THEME_DIR . '/inc/Blocks';

    if (is_dir($blocks_dir)) {
      $blocks = glob($blocks_dir . '/*.php');

      foreach ($blocks as $block) {
        require_once $block;

        // 自动注册区块类
        $block_name = basename($block, '.php');
        $class_name = 'CompanyTheme\\Blocks\\' . $block_name;

        if (class_exists($class_name) && method_exists($class_name, 'register')) {
          call_user_func([$class_name, 'register']);
        }
      }
    }
  }
}

// inc/Core/Assets.php - 资源管理
namespace CompanyTheme\Core;

/**
 * 资源管理类
 *
 * 负责所有JS/CSS资源的优化加载
 */
class Assets {
  /**
   * 注册所有钩子
   */
  public function register() {
    add_action('wp_enqueue_scripts', [$this, 'enqueueStyles']);
    add_action('wp_enqueue_scripts', [$this, 'enqueueScripts']);
    add_action('admin_enqueue_scripts', [$this, 'enqueueAdminAssets']);
    add_filter('script_loader_tag', [$this, 'addScriptAttributes'], 10, 3);
  }

  /**
   * 注册和加载样式
   */
  public function enqueueStyles() {
    // 内联关键CSS
    $this->inlineCriticalCss();

    // 主题样式
    wp_enqueue_style(
      'company-theme-main',
      THEME_URI . '/dist/css/main.css',
      [],
      $this->getAssetVersion('/dist/css/main.css')
    );

    // 条件加载特定页面样式
    if (is_front_page()) {
      wp_enqueue_style(
        'company-theme-home',
        THEME_URI . '/dist/css/home.css',
        ['company-theme-main'],
        $this->getAssetVersion('/dist/css/home.css')
      );
    }
  }

  /**
   * 注册和加载脚本
   */
  public function enqueueScripts() {
    // 主脚本文件
    wp_enqueue_script(
      'company-theme-main',
      THEME_URI . '/dist/js/main.js',
      [],
      $this->getAssetVersion('/dist/js/main.js'),
      true
    );

    // 本地化脚本
    wp_localize_script('company-theme-main', 'companyTheme', [
      'ajaxUrl' => admin_url('admin-ajax.php'),
      'restUrl' => esc_url_raw(rest_url()),
      'nonce' => wp_create_nonce('wp_rest'),
      'currentUser' => get_current_user_id(),
      'siteUrl' => get_site_url()
    ]);

    // 条件加载
    if (is_singular('product')) {
      wp_enqueue_script(
        'company-theme-product',
        THEME_URI . '/dist/js/product.js',
        ['company-theme-main'],
        $this->getAssetVersion('/dist/js/product.js'),
        true
      );
    }

    // 去除不必要的依赖
    if (!is_admin() && !is_user_logged_in()) {
      wp_deregister_script('jquery');
      wp_register_script('jquery', THEME_URI . '/dist/js/vendor/jquery.slim.min.js', [], '3.5.1', true);
    }
  }

  /**
   * 添加脚本属性(async/defer)
   */
  public function addScriptAttributes($tag, $handle, $src) {
    // 允许延迟加载的脚本
    $defer_scripts = ['company-theme-main'];

    if (in_array($handle, $defer_scripts)) {
      return str_replace(' src', ' defer src', $tag);
    }

    return $tag;
  }

  /**
   * 内联关键CSS
   */
  private function inlineCriticalCss() {
    $critical_css_path = THEME_DIR . '/dist/css/critical.css';

    if (file_exists($critical_css_path)) {
      $critical_css = file_get_contents($critical_css_path);
      echo '<style id="critical-css">' . $critical_css . '</style>';
    }
  }

  /**
   * 获取基于文件内容的版本号
   */
  private function getAssetVersion($file_path) {
    if (THEME_DEV_MODE) {
      return time(); // 开发模式下使用时间戳防止缓存
    }

    $full_path = THEME_DIR . $file_path;

    if (file_exists($full_path)) {
      return substr(md5_file($full_path), 0, 8);
    }

    return THEME_VERSION;
  }

  /**
   * 注册管理界面资源
   */
  public function enqueueAdminAssets($hook) {
    // 管理员界面资源...
  }
}

2. Gutenberg区块开发与性能优化

为内容编辑器开发自定义区块,同时确保前端性能,提升内容编辑体验和页面加载速度。

技术实现:

// src/blocks/featured-product/index.js - Gutenberg区块开发
import { registerBlockType } from '@wordpress/blocks';
import { InspectorControls, RichText, MediaUpload, useBlockProps } from '@wordpress/block-editor';
import { Panel, PanelBody, SelectControl, RangeControl, ToggleControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import ServerSideRender from '@wordpress/server-side-render';
import apiFetch from '@wordpress/api-fetch';
import { useState, useEffect } from '@wordpress/element';

// 区块定义
registerBlockType('company/featured-product', {
  apiVersion: 2,
  title: __('特色产品', 'company'),
  description: __('展示特色产品,支持自定义布局和外观。', 'company'),
  category: 'company-blocks',
  icon: 'star-filled',
  supports: {
    align: ['wide', 'full'],
    html: false,
    color: {
      background: true,
      text: true,
      gradients: true
    },
    spacing: {
      margin: true,
      padding: true
    }
  },

  // 定义属性模式
  attributes: {
    title: {
      type: 'string',
      source: 'html',
      selector: '.product-title'
    },
    description: {
      type: 'string',
      source: 'html',
      selector: '.product-description'
    },
    mediaId: {
      type: 'number',
      default: 0
    },
    mediaUrl: {
      type: 'string',
      default: ''
    },
    productId: {
      type: 'number',
      default: 0
    },
    layout: {
      type: 'string',
      default: 'standard' // standard, compact, featured
    },
    showPrice: {
      type: 'boolean',
      default: true
    },
    showRating: {
      type: 'boolean',
      default: true
    },
    callToAction: {
      type: 'string',
      default: __('了解更多', 'company')
    },
    columns: {
      type: 'number',
      default: 3
    },
    aspectRatio: {
      type: 'string',
      default: '4:3' // 16:9, 4:3, 1:1
    }
  },

  // 编辑器界面
  edit: ({ attributes, setAttributes }) => {
    const blockProps = useBlockProps({
      className: `featured-product-block layout-${attributes.layout}`
    });

    const [availableProducts, setAvailableProducts] = useState([]);
    const [isLoading, setIsLoading] = useState(false);

    // 加载可用产品
    useEffect(() => {
      setIsLoading(true);

      apiFetch({ path: '/wp/v2/product?per_page=50' })
        .then(products => {
          const options = products.map(product => ({
            value: product.id,
            label: product.title.rendered
          }));

          setAvailableProducts([
            { value: 0, label: __('选择产品...', 'company') },
            ...options
          ]);
          setIsLoading(false);
        })
        .catch(error => {
          console.error('加载产品失败:', error);
          setIsLoading(false);
        });
    }, []);

    // 产品选择变更处理
    const handleProductChange = (productId) => {
      setAttributes({ productId: parseInt(productId, 10) });

      // 如果选择了有效产品,加载产品详情
      if (productId > 0) {
        apiFetch({ path: `/wp/v2/product/${productId}` })
          .then(product => {
            setAttributes({
              title: product.title.rendered || '',
              description: product.excerpt.rendered || '',
              mediaId: product.featured_media || 0
            });

            // 如果有特色图片,获取图片URL
            if (product.featured_media) {
              apiFetch({ path: `/wp/v2/media/${product.featured_media}` })
                .then(media => {
                  setAttributes({ mediaUrl: media.source_url });
                });
            }
          });
      }
    };

    return (
      <>
        <InspectorControls>
          <Panel>
            <PanelBody title={__('产品设置', 'company')}>
              <SelectControl
                label={__('选择产品', 'company')}
                value={attributes.productId}
                options={availableProducts}
                onChange={handleProductChange}
                disabled={isLoading}
                help={isLoading ? __('加载中...', 'company') : ''}
              />

              <SelectControl
                label={__('布局样式', 'company')}
                value={attributes.layout}
                options={[
                  { value: 'standard', label: __('标准', 'company') },
                  { value: 'compact', label: __('紧凑', 'company') },
                  { value: 'featured', label: __('特色', 'company') }
                ]}
                onChange={(layout) => setAttributes({ layout })}
              />

              <RangeControl
                label={__('列数', 'company')}
                value={attributes.columns}
                onChange={(columns) => setAttributes({ columns })}
                min={1}
                max={4}
              />

              <SelectControl
                label={__('宽高比', 'company')}
                value={attributes.aspectRatio}
                options={[
                  { value: '16:9', label: '16:9' },
                  { value: '4:3', label: '4:3' },
                  { value: '1:1', label: '1:1' }
                ]}
                onChange={(aspectRatio) => setAttributes({ aspectRatio })}
              />

              <ToggleControl
                label={__('显示价格', 'company')}
                checked={attributes.showPrice}
                onChange={(showPrice) => setAttributes({ showPrice })}
              />

              <ToggleControl
                label={__('显示评分', 'company')}
                checked={attributes.showRating}
                onChange={(showRating) => setAttributes({ showRating })}
              />
            </PanelBody>

            <PanelBody title={__('按钮设置', 'company')}>
              <RichText
                tagName="span"
                value={attributes.callToAction}
                onChange={(callToAction) => setAttributes({ callToAction })}
                placeholder={__('按钮文字...', 'company')}
              />
            </PanelBody>
          </Panel>
        </InspectorControls>

        <div {...blockProps}>
          {attributes.productId === 0 ? (
            <div className="product-placeholder">
              <p>{__('请在右侧面板中选择一个产品。', 'company')}</p>
            </div>
          ) : (
            <ServerSideRender
              block="company/featured-product"
              attributes={attributes}
              EmptyResponsePlaceholder={() => (
                <div className="loading-placeholder">
                  {__('加载产品中...', 'company')}
                </div>
              )}
            />
          )}
        </div>
      </>
    );
  },

  // 保存方法 - 使用动态渲染
  save: () => null
});

// inc/Blocks/FeaturedProduct.php - 区块后端渲染
<?php
namespace CompanyTheme\Blocks;

/**
 * 特色产品区块
 */
class FeaturedProduct {
  /**
   * 区块名称
   */
  const BLOCK_NAME = 'company/featured-product';

  /**
   * 注册区块
   */
  public static function register() {
    // 注册脚本和样式
    add_action('init', [self::class, 'registerAssets']);

    // 注册区块类型
    register_block_type(self::BLOCK_NAME, [
      'editor_script' => 'company-blocks',
      'editor_style' => 'company-blocks-editor',
      'style' => 'company-blocks-style',
      'render_callback' => [self::class, 'renderBlock'],
      'attributes' => [
        'title' => [
          'type' => 'string',
          'default' => ''
        ],
        'description' => [
          'type' => 'string',
          'default' => ''
        ],
        'mediaId' => [
          'type' => 'number',
          'default' => 0
        ],
        'mediaUrl' => [
          'type' => 'string',
          'default' => ''
        ],
        'productId' => [
          'type' => 'number',
          'default' => 0
        ],
        'layout' => [
          'type' => 'string',
          'default' => 'standard'
        ],
        'showPrice' => [
          'type' => 'boolean',
          'default' => true
        ],
        'showRating' => [
          'type' => 'boolean',
          'default' => true
        ],
        'callToAction' => [
          'type' => 'string',
          'default' => '了解更多'
        ],
        'columns' => [
          'type' => 'number',
          'default' => 3
        ],
        'aspectRatio' => [
          'type' => 'string',
          'default' => '4:3'
        ],
        'className' => [
          'type' => 'string',
          'default' => ''
        ],
        'align' => [
          'type' => 'string',
          'default' => ''
        ],
        'backgroundColor' => [
          'type' => 'string',
          'default' => ''
        ],
        'textColor' => [
          'type' => 'string',
          'default' => ''
        ]
      ]
    ]);
  }

  /**
   * 注册区块资源
   */
  public static function registerAssets() {
    // 注册区块脚本
    wp_register_script(
      'company-blocks',
      THEME_URI . '/dist/js/blocks.js',
      ['wp-blocks', 'wp-element', 'wp-editor', 'wp-components', 'wp-i18n', 'wp-api-fetch'],
      THEME_VERSION,
      true
    );

    // 注册编辑器样式
    wp_register_style(
      'company-blocks-editor',
      THEME_URI . '/dist/css/blocks-editor.css',
      ['wp-edit-blocks'],
      THEME_VERSION
    );

    // 注册前端样式
    wp_register_style(
      'company-blocks-style',
      THEME_URI . '/dist/css/blocks.css',
      [],
      THEME_VERSION
    );

    // 本地化脚本
    if (function_exists('wp_set_script_translations')) {
      wp_set_script_translations('company-blocks', 'company', THEME_DIR . '/languages');
    }
  }

  /**
   * 渲染区块
   */
  public static function renderBlock($attributes, $content) {
    // 提取属性
    $title = $attributes['title'] ?? '';
    $description = $attributes['description'] ?? '';
    $product_id = $attributes['productId'] ?? 0;
    $layout = $attributes['layout'] ?? 'standard';
    $show_price = $attributes['showPrice'] ?? true;
    $show_rating = $attributes['showRating'] ?? true;
    $call_to_action = $attributes['callToAction'] ?? '了解更多';
    $columns = $attributes['columns'] ?? 3;
    $aspect_ratio = $attributes['aspectRatio'] ?? '4:3';
    $class_name = $attributes['className'] ?? '';
    $align = $attributes['align'] ?? '';
    $bg_color = $attributes['backgroundColor'] ?? '';
    $text_color = $attributes['textColor'] ?? '';

    // 如果没有选择产品,返回空
    if (empty($product_id)) {
      return '';
    }

    // 获取产品数据 - 添加缓存
    $cache_key = 'featured_product_' . $product_id;
    $product = wp_cache_get($cache_key);

    if (false === $product) {
      $product = get_post($product_id);

      if (!$product || $product->post_type !== 'product') {
        return '';
      }

      // 缓存产品数据5分钟
      wp_cache_set($cache_key, $product, '', 300);
    }

    // 获取产品元数据
    $price = get_post_meta($product_id, 'product_price', true);
    $rating = get_post_meta($product_id, 'product_rating', true);

    // 获取产品图片
    $image_id = get_post_thumbnail_id($product_id);
    $image_data = [];

    if ($image_id) {
      $image_src = wp_get_attachment_image_src($image_id, 'large');
      $image_srcset = wp_get_attachment_image_srcset($image_id, 'large');
      $image_alt = get_post_meta($image_id, '_wp_attachment_image_alt', true);

      if ($image_src) {
        $image_data = [
          'url' => $image_src[0],
          'width' => $image_src[1],
          'height' => $image_src[2],
          'srcset' => $image_srcset,
          'alt' => $image_alt ?: $title
        ];
      }
    }

    // 构建CSS类
    $classes = ['featured-product', "layout-{$layout}", "aspect-{$aspect_ratio}"];

    if ($class_name) {
      $classes[] = $class_name;
    }

    if ($align) {
      $classes[] = "align{$align}";
    }

    if ($columns > 1) {
      $classes[] = "cols-{$columns}";
    }

    // 内联样式
    $styles = [];

    if ($bg_color) {
      $styles[] = "background-color:{$bg_color}";
    }

    if ($text_color) {
      $styles[] = "color:{$text_color}";
    }

    $style_attr = !empty($styles) ? ' style="' . esc_attr(implode(';', $styles)) . '"' : '';

    // 开始构建输出
    $output = sprintf(
      '<div class="%s"%s>',
      esc_attr(implode(' ', $classes)),
      $style_attr
    );

    // 产品图片
    if (!empty($image_data)) {
      $output .= '<div class="product-image-wrapper">';
      $output .= sprintf(
        '<img src="%s" width="%d" height="%d" srcset="%s" alt="%s" loading="lazy" class="product-image" />',
        esc_url($image_data['url']),
        esc_attr($image_data['width']),
        esc_attr($image_data['height']),
        esc_attr($image_data['srcset']),
        esc_attr($image_data['alt'])
      );
      $output .= '</div>';
    }

    // 产品内容
    $output .= '<div class="product-content">';

    // 产品标题
    if ($title) {
      $output .= sprintf('<h3 class="product-title">%s</h3>', $title);
    }

    // 价格和评分
    if ($show_price && $price || $show_rating && $rating) {
      $output .= '<div class="product-meta">';

      if ($show_price && $price) {
        $output .= sprintf('<span class="product-price">%s</span>', esc_html($price));
      }

      if ($show_rating && $rating) {
        $stars = self::generateStarRating($rating);
        $output .= sprintf('<span class="product-rating">%s</span>', $stars);
      }

      $output .= '</div>';
    }

    // 产品描述
    if ($description) {
      $output .= sprintf('<div class="product-description">%s</div>', $description);
    }

    // 行动按钮
    $output .= sprintf(
      '<a href="%s" class="product-cta">%s</a>',
      esc_url(get_permalink($product_id)),
      esc_html($call_to_action)
    );

    $output .= '</div>'; // .product-content
    $output .= '</div>'; // .featured-product

    // 预加载关键图片资源
    add_action('wp_footer', function() use ($image_data) {
      if (!empty($image_data['url'])) {
        echo '<link rel="preload" href="' . esc_url($image_data['url']) . '" as="image">';
      }
    }, 20);

    return $output;
  }

  /**
   * 生成星级评分HTML
   */
  private static function generateStarRating($rating) {
    $rating = floatval($rating);
    $full_stars = floor($rating);
    $half_star = ($rating - $full_stars) >= 0.5;
    $empty_stars = 5 - $full_stars - ($half_star ? 1 : 0);

    $output = '<div class="star-rating" role="img" aria-label="' . sprintf(__('评分: %s / 5', 'company'), $rating) . '">';

    // 实星
    for ($i = 0; $i < $full_stars; $i++) {
      $output .= '<span class="star star-full">★</span>';
    }

    // 半星
    if ($half_star) {
      $output .= '<span class="star star-half">★</span>';
    }

    // 空星
    for ($i = 0; $i < $empty_stars; $i++) {
      $output .= '<span class="star star-empty">☆</span>';
    }

    $output .= '</div>';

    return $output;
  }
}

五、WordPress作为Headless CMS的技术架构

1. Headless WordPress与前端分离

将WordPress作为纯数据源,前端使用现代框架重构,实现真正的前后端分离架构,提升性能和开发效率。

技术实现:

// Next.js前端与Headless WordPress集成
// 文件: /frontend/src/pages/[...slug].js

import { useRouter } from 'next/router';
import Head from 'next/head';
import Error from 'next/error';
import { GetStaticProps, GetStaticPaths } from 'next';
import { gql } from '@apollo/client';
import { initializeApollo, addApolloState } from '../lib/apollo-client';
import { ParsedUrlQuery } from 'querystring';
import Layout from '../components/Layout';
import PageSkeleton from '../components/PageSkeleton';
import PageComponents from '../components/PageComponents';
import { PAGE_COMPONENTS_FRAGMENT } from '../fragments/pageComponents';
import { SEO_FRAGMENT } from '../fragments/seo';
import { buildImageSizes } from '../utils/images';
import { useTranslation } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';

// 定义完整页面查询
const GET_PAGE_BY_URI = gql`
  query GetPageByUri($uri: String!) {
    nodeByUri(uri: $uri) {
      ... on Page {
        id
        databaseId
        title
        content
        slug
        uri
        template {
          templateName
        }
        featuredImage {
          node {
            sourceUrl(size: LARGE)
            srcSet(size: LARGE)
            altText
            mediaDetails {
              height
              width
            }
          }
        }
        seo {
          ...SeoFragment
        }
        pageComponents {
          ...PageComponentsFragment
        }
      }
      ... on Post {
        id
        databaseId
        title
        content
        slug
        date
        author {
          node {
            name
            slug
            avatar {
              url
            }
          }
        }
        categories {
          nodes {
            id
            name
            slug
          }
        }
        tags {
          nodes {
            id
            name
            slug
          }
        }
        featuredImage {
          node {
            sourceUrl(size: LARGE)
            srcSet(size: LARGE)
            altText
            mediaDetails {
              height
              width
            }
          }
        }
        seo {
          ...SeoFragment
        }
      }
      ... on Product {
        id
        databaseId
        title
        content
        slug
        date
        productMeta {
          price
          sku
          rating
        }
        categories: productCategories {
          nodes {
            id
            name
            slug
          }
        }
        featuredImage {
          node {
            sourceUrl(size: LARGE)
            srcSet(size: LARGE)
            altText
            mediaDetails {
              height
              width
            }
          }
        }
        galleryImages {
          nodes {
            id
            sourceUrl(size: LARGE)
            srcSet(size: LARGE)
            altText
            mediaDetails {
              height
              width
            }
          }
        }
        relatedProducts {
          nodes {
            id
            title
            slug
            featuredImage {
              node {
                sourceUrl(size: MEDIUM)
              }
            }
            productMeta {
              price
            }
          }
        }
        seo {
          ...SeoFragment
        }
      }
    }
    generalSettings {
      title
      description
    }
    mainMenu: menuItems(where: {location: PRIMARY}) {
      nodes {
        id
        databaseId
        title
        url
        path
        parentId
        cssClasses
        menu {
          node {
            name
          }
        }
      }
    }
    footerMenu: menuItems(where: {location: FOOTER}) {
      nodes {
        id
        databaseId
        title
        url
        path
        parentId
        cssClasses
      }
    }
  }
  ${SEO_FRAGMENT}
  ${PAGE_COMPONENTS_FRAGMENT}
`;

// 获取所有页面路径
const GET_ALL_URIS = gql`
  query GetAllUris {
    contentNodes(first: 1000, where: {
      contentTypes: [PAGE, POST, PRODUCT]
    }) {
      nodes {
        uri
        ... on NodeWithTemplate {
          template {
            templateName
          }
        }
      }
    }
  }
`;

// 页面组件
export default function DynamicPage({ page, notFound, preview }) {
  const router = useRouter();
  const { t } = useTranslation('common');

  // 处理路由加载状态
  if (router.isFallback) {
    return <PageSkeleton />;
  }

  // 处理404页面
  if (notFound) {
    return <Error statusCode={404} />;
  }

  // 提取页面内容和元数据
  const { nodeByUri: node, generalSettings, mainMenu, footerMenu } = page;

  // 如果没有内容返回404
  if (!node) {
    return <Error statusCode={404} />;
  }

  // 确定页面类型
  const isPost = !!node?.date && !node?.productMeta;
  const isProduct = !!node?.productMeta;
  const isPage = !isPost && !isProduct;

  // 确定显示模板
  const templateName = node?.template?.templateName || 'Default';
  const contentType = isPage ? 'page' : (isPost ? 'post' : 'product');

  // 构建页面通用数据
  const pageData = {
    id: node.id,
    databaseId: node.databaseId,
    title: node.title,
    content: node.content,
    slug: node.slug,
    uri: node.uri,
    type: contentType,
    template: templateName,
    seo: node.seo,
    featuredImage: node.featuredImage?.node || null,
    // 页面类型特有数据
    ...(isPage && {
      pageComponents: node.pageComponents || null
    }),
    ...(isPost && {
      date: node.date,
      author: node.author?.node || null,
      categories: node.categories?.nodes || [],
      tags: node.tags?.nodes || []
    }),
    ...(isProduct && {
      productMeta: node.productMeta || null,
      categories: node.categories?.nodes || [],
      galleryImages: node.galleryImages?.nodes || [],
      relatedProducts: node.relatedProducts?.nodes || []
    })
  };

  // 页面SEO优化
  const seo = node.seo || {};
  const title = seo.title || node.title;
  const description = seo.metaDesc || generalSettings.description;
  const siteTitle = generalSettings.title;
  const fullTitle = `${title} | ${siteTitle}`;

  return (
    <Layout
      mainMenu={mainMenu.nodes}
      footerMenu={footerMenu.nodes}
      pageType={contentType}
      isPreview={preview}
    >
      <Head>
        <title>{fullTitle}</title>
        <meta name="description" content={description} />
        {seo.canonical && <link rel="canonical" href={seo.canonical} />}
        {seo.opengraphTitle && (
          <meta property="og:title" content={seo.opengraphTitle} />
        )}
        {seo.opengraphDescription && (
          <meta property="og:description" content={seo.opengraphDescription} />
        )}
        {seo.opengraphImage?.sourceUrl && (
          <meta property="og:image" content={seo.opengraphImage.sourceUrl} />
        )}
        {seo.twitterTitle && (
          <meta name="twitter:title" content={seo.twitterTitle} />
        )}
        {seo.twitterDescription && (
          <meta name="twitter:description" content={seo.twitterDescription} />
        )}
        {seo.twitterImage?.sourceUrl && (
          <meta name="twitter:image" content={seo.twitterImage.sourceUrl} />
        )}
        <meta name="twitter:card" content="summary_large_image" />
      </Head>

      {isPage && node.pageComponents ? (
        // 使用ACF灵活内容字段的模块化渲染
        <PageComponents
          components={node.pageComponents}
          pageData={pageData}
          preview={preview}
        />
      ) : (
        // 默认内容模板
        <div className="container mx-auto py-12">
          <article className="prose prose-lg mx-auto">
            <h1 className="text-4xl font-bold">{node.title}</h1>

            {node.featuredImage?.node && (
              <figure className="my-8">
                <img
                  src={node.featuredImage.node.sourceUrl}
                  srcSet={node.featuredImage.node.srcSet}
                  alt={node.featuredImage.node.altText || node.title}
                  sizes={buildImageSizes('(min-width: 1280px) 1100px, (min-width: 768px) 90vw, 95vw')}
                  className="w-full h-auto rounded-lg"
                  width={node.featuredImage.node.mediaDetails?.width}
                  height={node.featuredImage.node.mediaDetails?.height}
                />
              </figure>
            )}

            {/* 帖子元数据 */}
            {isPost && (
              <div className="flex items-center text-gray-500 mb-8">
                {node.author?.node && (
                  <div className="flex items-center mr-6">
                    {node.author.node.avatar?.url && (
                      <img
                        src={node.author.node.avatar.url}
                        alt={node.author.node.name}
                        className="w-10 h-10 rounded-full mr-3"
                      />
                    )}
                    <span>{node.author.node.name}</span>
                  </div>
                )}
                <time dateTime={node.date}>
                  {new Date(node.date).toLocaleDateString()}
                </time>
              </div>
            )}

            {/* 产品元数据 */}
            {isProduct && (
              <div className="border-t border-b border-gray-200 py-6 mb-8">
                {node.productMeta?.price && (
                  <div className="text-3xl font-bold text-blue-600 mb-4">
                    {node.productMeta.price}
                  </div>
                )}
                {node.productMeta?.sku && (
                  <div className="text-sm text-gray-500 mb-4">
                    {t('product.sku')}: {node.productMeta.sku}
                  </div>
                )}
                <button className="bg-blue-600 text-white px-8 py-3 rounded-lg hover:bg-blue-700">
                  {t('product.addToCart')}
                </button>
              </div>
            )}

            {/* 内容主体 */}
            <div
              className="content"
              dangerouslySetInnerHTML={{ __html: node.content }}
            />

            {/* 产品图库 */}
            {isProduct && node.galleryImages?.nodes.length > 0 && (
              <div className="mt-12">
                <h2 className="text-2xl font-bold mb-6">{t('product.gallery')}</h2>
                <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
                  {node.galleryImages.nodes.map(image => (
                    <img
                      key={image.id}
                      src={image.sourceUrl}
                      alt={image.altText || ''}
                      className="rounded-lg cursor-pointer"
                      onClick={() => openLightbox(image)}
                    />
                  ))}
                </div>
              </div>
            )}

            {/* 相关产品 */}
            {isProduct && node.relatedProducts?.nodes.length > 0 && (
              <div className="mt-16">
                <h2 className="text-2xl font-bold mb-6">{t('product.related')}</h2>
                <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
                  {node.relatedProducts.nodes.map(product => (
                    <a
                      key={product.id}
                      href={`/product/${product.slug}`}
                      className="block group"
                    >
                      {product.featuredImage?.node && (
                        <img
                          src={product.featuredImage.node.sourceUrl}
                          alt={product.title}
                          className="w-full h-56 object-cover rounded-lg"
                        />
                      )}
                      <h3 className="mt-3 text-lg font-medium group-hover:text-blue-600">
                        {product.title}
                      </h3>
                      {product.productMeta?.price && (
                        <p className="mt-1 text-blue-600">{product.productMeta.price}</p>
                      )}
                    </a>
                  ))}
                </div>
              </div>
            )}
          </article>
        </div>
      )}
    </Layout>
  );
}

// 获取路径参数
interface Params extends ParsedUrlQuery {
  slug: string[];
}

// 静态路径生成
export const getStaticPaths: GetStaticPaths = async ({ locales }) => {
  // 初始化Apollo客户端
  const apolloClient = initializeApollo();

  // 获取所有内容URI
  const { data } = await apolloClient.query({
    query: GET_ALL_URIS
  });

  // 生成所有可能的路径
  const paths = [];

  // 处理每个本地化
  if (locales) {
    for (const locale of locales) {
      data.contentNodes.nodes.forEach(node => {
        // 处理首页特例
        if (node.uri === '/') {
          paths.push({
            params: { slug: [''] },
            locale
          });
          return;
        }

        // 跳过非公开路径
        if (!node.uri || node.uri === '/') return;

        // 添加标准路径
        const slug = node.uri.split('/').filter(Boolean);
        paths.push({
          params: { slug },
          locale
        });
      });
    }
  } else {
    // 没有本地化时的处理
    data.contentNodes.nodes.forEach(node => {
      if (node.uri === '/') {
        paths.push({ params: { slug: [''] } });
        return;
      }

      if (!node.uri || node.uri === '/') return;

      const slug = node.uri.split('/').filter(Boolean);
      paths.push({ params: { slug } });
    });
  }

  return {
    paths,
    // 增量静态生成 - 未预渲染的路径将在运行时生成
    fallback: 'blocking'
  };
};

// 静态页面生成
export const getStaticProps: GetStaticProps = async ({ params, locale, preview = false }) => {
  const apolloClient = initializeApollo();

  // 获取slug数组并构建URI
  const { slug = [] } = params as Params;
  const uri = slug.join('/');
  const path = uri ? `/${uri}/` : '/';

  try {
    // 执行GraphQL查询
    const { data } = await apolloClient.query({
      query: GET_PAGE_BY_URI,
      variables: { uri: path }
    });

    // 页面不存在,返回404
    if (!data.nodeByUri) {
      return {
        notFound: true,
        revalidate: 60 // 1分钟后重新验证
      };
    }

    // 返回页面数据
    return addApolloState(apolloClient, {
      props: {
        page: data,
        notFound: false,
        preview: !!preview,
        // 添加本地化支持
        ...(locale && { ...(await serverSideTranslations(locale, ['common'])) })
      },
      // 启用增量静态重新生成 - 每隔一段时间重新生成页面
      revalidate: data.nodeByUri.template?.templateName === 'Homepage' ? 60 : 300 // 首页1分钟,其他页面5分钟
    });
  } catch (error) {
    console.error('Page generation error:', error);

    // 错误处理 - 返回404
    return {
      notFound: true,
      revalidate: 60 // 1分钟后重新验证
    };
  }
};

// 后端配置:/wp-content/themes/headless-theme/functions.php
<?php
/**
 * Headless主题基础功能,提供API支持
 */

// 安全检查
if (!defined('ABSPATH')) exit;

// 禁用前端主题加载,仅保留API功能
add_action('template_redirect', function() {
  if (!is_admin() &&
      !rest_doing_request() &&
      !graphql_is_request() &&
      !(defined('WP_CLI') && WP_CLI)
  ) {
    // 检查是否有预览请求
    $is_preview = isset($_GET['preview']) && $_GET['preview'] === 'true';
    $preview_id = isset($_GET['p']) ? $_GET['p'] : false;

    if ($is_preview && $preview_id && current_user_can('edit_post', $preview_id)) {
      // 允许预览请求,重定向到前端预览页
      $frontend_url = get_option('headless_frontend_url');
      $post_type = get_post_type($preview_id);
      $preview_url = "{$frontend_url}/api/preview?id={$preview_id}&type={$post_type}";
      wp_redirect($preview_url);
      exit;
    }

    // 非预览请求重定向到前端
    $frontend_url = get_option('headless_frontend_url');
    $requested_uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
    wp_redirect($frontend_url . $requested_uri);
    exit;
  }
});

// 增强REST API和GraphQL
require_once __DIR__ . '/inc/api-extensions.php';
require_once __DIR__ . '/inc/graphql-extensions.php';
require_once __DIR__ . '/inc/preview-control.php';
require_once __DIR__ . '/inc/media-optimization.php';

// Headless CMS设置页面
add_action('admin_menu', function() {
  add_options_page(
    'Headless CMS设置',
    'Headless CMS',
    'manage_options',
    'headless-cms-settings',
    'headless_cms_settings_page'
  );
});

// 设置页面回调
function headless_cms_settings_page() {
  // 保存设置
  if (isset($_POST['headless_frontend_url'])) {
    check_admin_referer('headless_cms_settings');
    update_option('headless_frontend_url', esc_url_raw($_POST['headless_frontend_url']));
    echo '<div class="notice notice-success"><p>设置已保存</p></div>';
  }

  $frontend_url = get_option('headless_frontend_url', '');

  ?>
  <div class="wrap">
    <h1>Headless CMS设置</h1>
    <form method="post" action="">
      <?php wp_nonce_field('headless_cms_settings'); ?>
      <table class="form-table">
        <tr>
          <th scope="row">前端URL</th>
          <td>
            <input type="url" name="headless_frontend_url" value="<?php echo esc_attr($frontend_url); ?>" class="regular-text" required />
            <p class="description">您的Next.js前端URL(不含结尾斜杠),例如 https://www.example.com</p>
          </td>
        </tr>
      </table>
      <p class="submit">
        <input type="submit" name="submit" id="submit" class="button button-primary" value="保存设置">
      </p>
    </form>
    <hr>
    <h2>Headless模式状态</h2>
    <table class="widefat">
      <tr>
        <th>WordPress REST API</th>
        <td><?php echo rest_get_url_prefix() ? '✅ 已启用' : '❌ 未启用'; ?></td>
      </tr>
      <tr>
        <th>WPGraphQL</th>
        <td><?php echo class_exists('WPGraphQL') ? '✅ 已启用' : '❌ 未安装'; ?></td>
      </tr>
      <tr>
        <th>前端URL配置</th>
        <td><?php echo $frontend_url ? '✅ 已配置: ' . esc_html($frontend_url) : '❌ 未配置'; ?></td>
      </tr>
      <tr>
        <th>CORS配置</th>
        <td><?php echo has_filter('cors_allow_origin') ? '✅ 已配置' : '⚠️ 请检查跨域配置'; ?></td>
      </tr>
    </table>
  </div>
  <?php
}

// 自定义预览API接口
add_action('rest_api_init', function() {
  register_rest_route('headless/v1', '/preview', [
    'methods' => 'GET',
    'callback' => 'headless_preview_api',
    'permission_callback' => function() {
      return current_user_can('edit_posts');
    }
  ]);
});

// 预览API处理
function headless_preview_api($request) {
  $post_id = $request->get_param('id');
  $post_type = get_post_type($post_id);

  if (!$post_id || !$post_type) {
    return new WP_Error('invalid_post', '无效的文章ID', ['status' => 404]);
  }

  $post = get_post($post_id);
  if (!$post) {
    return new WP_Error('post_not_found', '找不到文章', ['status' => 404]);
  }

  // 生成预览数据
  $controller = new WP_REST_Posts_Controller($post_type);
  $data = $controller->prepare_item_for_response($post, $request);

  // 添加预览URL
  $frontend_url = get_option('headless_frontend_url');
  $preview_url = "{$frontend_url}/api/preview?id={$post_id}&type={$post_type}";
  $data->data['preview_url'] = $preview_url;

  return $data;
}

2. 性能监控与优化系统

构建完整的前端性能监控与持续优化体系,追踪关键性能指标并进行自动化优化。

技术实现:

// 前端性能监测系统 - 监测Web Vitals和业务指标
// src/lib/performance-monitoring.js
import { onLCP, onFID, onCLS, onINP, onTTFB } from 'web-vitals';

class PerformanceMonitor {
  constructor(options = {}) {
    this.options = {
      sampleRate: 0.1, // 采样率默认10%
      endpoint: '/api/analytics/performance',
      includeCrashReports: true,
      resourceTiming: false,
      ...options
    };

    this.metrics = {};
    this.initialized = false;
    this.userId = this.getUserId();
  }

  /**
   * 初始化性能监控
   */
  init() {
    if (this.initialized) return;
    this.initialized = true;

    // 确保只采样部分用户
    if (Math.random() > this.options.sampleRate) {
      return;
    }

    // 注册核心Web Vitals监测
    this.registerWebVitals();

    // 捕获错误与拒绝的Promise
    if (this.options.includeCrashReports) {
      this.setupErrorCapture();
    }

    // 资源加载性能监控
    if (this.options.resourceTiming) {
      this.setupResourceTiming();
    }

    // 监控首次绘制与首次内容绘制
    this.observePaintMetrics();

    // 用户交互监控
    this.setupInteractionMonitoring();

    // 页面完全加载后收集指标
    window.addEventListener('load', () => {
      // 使用requestIdleCallback延迟收集数据,避免影响主交互线程
      if (window.requestIdleCallback) {
        window.requestIdleCallback(() => this.gatherAndSendMetrics(), { timeout: 3000 });
      } else {
        setTimeout(() => this.gatherAndSendMetrics(), 1000);
      }
    });

    // 页面离开前尝试发送最终数据
    document.addEventListener('visibilitychange', () => {
      if (document.visibilityState === 'hidden') {
        // 使用beacon API确保数据在页面关闭时发送
        this.sendMetricsBeacon();
      }
    });
  }

  /**
   * 为用户生成唯一标识符
   */
  getUserId() {
    let userId = localStorage.getItem('pm_user_id');
    if (!userId) {
      userId = crypto.randomUUID ? crypto.randomUUID() : `user_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
      localStorage.setItem('pm_user_id', userId);
    }
    return userId;
  }

  /**
   * 注册Web Vitals核心指标监测
   */
  registerWebVitals() {
    // LCP (Largest Contentful Paint) - 最大内容渲染
    onLCP(metric => {
      this.metrics.lcp = metric.value;

      // 如果LCP超过阈值,立即发送报告
      if (metric.value > 2500) {
        this.sendMetric('lcp', metric);
      }
    });

    // FID (First Input Delay) - 首次输入延迟
    onFID(metric => {
      this.metrics.fid = metric.value;
    });

    // CLS (Cumulative Layout Shift) - 累积布局偏移
    onCLS(metric => {
      this.metrics.cls = metric.value;
    });

    // INP (Interaction to Next Paint) - 交互到下一次绘制
    onINP(metric => {
      this.metrics.inp = metric.value;
    });

    // TTFB (Time to First Byte) - 首字节时间
    onTTFB(metric => {
      this.metrics.ttfb = metric.value;
    });
  }

  /**
   * 设置错误捕获
   */
  setupErrorCapture() {
    // 存储错误信息
    window.jsErrors = [];

    // 全局错误事件
    window.addEventListener('error', event => {
      const error = {
        type: 'error',
        message: event.message,
        source: event.filename,
        lineno: event.lineno,
        colno: event.colno,
        stack: event.error?.stack,
        timestamp: new Date().toISOString()
      };

      window.jsErrors.push(error);

      // 严重错误立即上报
      if (event.error instanceof TypeError || event.error instanceof ReferenceError) {
        this.sendMetric('error', error);
      }
    }, true);

    // 未捕获的Promise拒绝
    window.addEventListener('unhandledrejection', event => {
      const error = {
        type: 'promise_rejection',
        message: typeof event.reason === 'string' ? event.reason : event.reason?.message,
        stack: event.reason?.stack,
        timestamp: new Date().toISOString()
      };

      window.jsErrors.push(error);
    }, true);
  }

  /**
   * 设置资源加载性能监测
   */
  setupResourceTiming() {
    const observer = new PerformanceObserver(list => {
      const entries = list.getEntries();

      // 收集关键资源加载信息
      entries.forEach(entry => {
        // 只监控关键资源类型
        const criticalResourceTypes = ['script', 'css', 'fetch', 'xmlhttprequest', 'img'];
        if (criticalResourceTypes.includes(entry.initiatorType)) {
          // 大于500ms的资源加载时间记录为慢资源
          if (entry.duration > 500) {
            if (!this.metrics.slowResources) {
              this.metrics.slowResources = [];
            }

            this.metrics.slowResources.push({
              name: entry.name,
              duration: entry.duration,
              size: entry.transferSize,
              type: entry.initiatorType
            });
          }
        }
      });
    });

    observer.observe({ entryTypes: ['resource'] });
  }

  /**
   * 监控绘制指标
   */
  observePaintMetrics() {
    const observer = new PerformanceObserver(list => {
      const entries = list.getEntries();

      entries.forEach(entry => {
        if (entry.name === 'first-paint') {
          this.metrics.fp = entry.startTime;
        }
        if (entry.name === 'first-contentful-paint') {
          this.metrics.fcp = entry.startTime;
        }
      });
    });

    observer.observe({ entryTypes: ['paint'] });
  }

  /**
   * 监控用户交互
   */
  setupInteractionMonitoring() {
    // 追踪用户点击到响应的时间
    const clicks = [];

    window.addEventListener('click', event => {
      clicks.push({
        target: event.target.tagName,
        timeStamp: event.timeStamp,
        time: performance.now()
      });
    }, { passive: true });

    // 监听渲染时机来测量响应时间
    const observer = new PerformanceObserver(list => {
      // 如果有最近的点击,计算响应时间
      const entry = list.getEntries()[0];
      const lastClick = clicks[clicks.length - 1];

      if (lastClick && (entry.startTime - lastClick.time < 100)) {
        const responseTime = entry.startTime - lastClick.time;

        // 记录慢响应
        if (responseTime > 100) {
          if (!this.metrics.slowInteractions) {
            this.metrics.slowInteractions = [];
          }
          this.metrics.slowInteractions.push({
            target: lastClick.target,
            responseTime
          });
        }
      }
    });

    observer.observe({ entryTypes: ['render'] });
  }

  /**
   * 收集并发送所有指标
   */
  gatherAndSendMetrics() {
    // 添加更多导航和资源计时指标
    const navTiming = performance.getEntriesByType('navigation')[0];

    if (navTiming) {
      // DNS解析时间
      this.metrics.dns = navTiming.domainLookupEnd - navTiming.domainLookupStart;

      // TCP连接时间
      this.metrics.tcp = navTiming.connectEnd - navTiming.connectStart;

      // 请求响应时间
      this.metrics.request = navTiming.responseStart - navTiming.requestStart;

      // 响应下载时间
      this.metrics.response = navTiming.responseEnd - navTiming.responseStart;

      // DOM处理时间
      this.metrics.dom = navTiming.domComplete - navTiming.domInteractive;

      // 总加载时间
      this.metrics.load = navTiming.loadEventEnd - navTiming.startTime;
    }

    // 内存使用情况
    if (performance.memory) {
      this.metrics.memory = {
        jsHeapSizeLimit: performance.memory.jsHeapSizeLimit,
        totalJSHeapSize: performance.memory.totalJSHeapSize,
        usedJSHeapSize: performance.memory.usedJSHeapSize
      };
    }

    // 添加上下文信息
    this.metrics.context = {
      url: window.location.href,
      path: window.location.pathname,
      referrer: document.referrer,
      userAgent: navigator.userAgent,
      deviceType: this.getDeviceType(),
      connection: this.getConnectionInfo(),
      screenSize: `${window.innerWidth}x${window.innerHeight}`,
      userId: this.userId,
      timestamp: new Date().toISOString()
    };

    // 发送收集到的指标
    this.sendMetrics();
  }

  /**
   * 获取设备类型
   */
  getDeviceType() {
    const ua = navigator.userAgent;
    if (/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(ua)) {
      return 'tablet';
    }
    if (/Mobile|Android|iP(hone|od)|IEMobile|BlackBerry|Kindle|Silk-Accelerated/i.test(ua)) {
      return 'mobile';
    }
    return 'desktop';
  }

  /**
   * 获取网络连接信息
   */
  getConnectionInfo() {
    if (!navigator.connection) {
      return null;
    }

    const { effectiveType, downlink, rtt, saveData } = navigator.connection;
    return { effectiveType, downlink, rtt, saveData };
  }

  /**
   * 发送单个指标数据
   */
  sendMetric(name, data) {
    // 限制数据发送频率
    if (this._throttleCheck(name)) return;

    fetch(this.options.endpoint, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        metric: name,
        data,
        context: {
          url: window.location.href,
          userId: this.userId,
          timestamp: new Date().toISOString()
        }
      }),
      // 不阻塞主线程
      keepalive: true
    }).catch(err => console.debug('Failed to send metric:', err));
  }

  /**
   * 限流检查
   */
  _throttleCheck(name) {
    const key = `pm_throttle_${name}`;
    const now = Date.now();
    const lastSent = parseInt(sessionStorage.getItem(key) || 0);

    // 每5秒最多发送一次同类型指标
    if (now - lastSent < 5000) {
      return true;
    }

    sessionStorage.setItem(key, now.toString());
    return false;
  }

  /**
   * 发送所有指标数据
   */
  sendMetrics() {
    // 避免发送空数据
    if (Object.keys(this.metrics).length === 0) return;

    fetch(this.options.endpoint, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        metrics: this.metrics,
      }),
      // 不阻塞主线程
      keepalive: true
    }).catch(err => console.debug('Failed to send metrics:', err));
  }

  /**
   * 使用Beacon API发送数据
   */
  sendMetricsBeacon() {
    if (!navigator.sendBeacon) return this.sendMetrics();

    const blob = new Blob([JSON.stringify({ metrics: this.metrics })], {
      type: 'application/json'
    });

    navigator.sendBeacon(this.options.endpoint, blob);
  }
}

// 导出单例实例
const performanceMonitor = new PerformanceMonitor({
  sampleRate: 0.2, // 提高采样率到20%
  endpoint: '/api/analytics/performance',
  includeCrashReports: true,
  resourceTiming: true
});

export default performanceMonitor;

// 后端性能数据收集与分析API
// pages/api/analytics/performance.js
import { MongoClient } from 'mongodb';
import { v4 as uuidv4 } from 'uuid';

// 数据库连接
let cachedDb = null;

/**
 * 连接MongoDB
 */
async function connectToDatabase() {
  if (cachedDb) {
    return cachedDb;
  }

  const client = await MongoClient.connect(process.env.MONGODB_URI);
  const db = client.db(process.env.MONGODB_DB);

  cachedDb = db;
  return db;
}

/**
 * 性能数据处理API
 */
export default async function handler(req, res) {
  // 只允许POST请求
  if (req.method !== 'POST') {
    return res.status(405).json({ error: 'Method not allowed' });
  }

  // 验证请求来源
  const origin = req.headers.origin || '';
  const allowedOrigins = process.env.ALLOWED_ORIGINS?.split(',') || [];

  if (process.env.NODE_ENV === 'production' && !allowedOrigins.includes(origin)) {
    return res.status(403).json({ error: 'Forbidden' });
  }

  try {
    const metrics = req.body.metrics || req.body;

    if (!metrics) {
      return res.status(400).json({ error: 'No metrics data provided' });
    }

    // 添加服务端时间戳和ID
    metrics.serverTimestamp = new Date();
    metrics.id = uuidv4();

    // 连接数据库
    const db = await connectToDatabase();
    const collection = db.collection('performance_metrics');

    // 存储数据
    await collection.insertOne(metrics);

    // 处理严重性能问题的警报
    await checkForAlerts(metrics, db);

    return res.status(200).json({ success: true });
  } catch (error) {
    console.error('Error saving performance metrics:', error);
    return res.status(500).json({ error: 'Internal server error' });
  }
}

/**
 * 检查性能指标警报条件
 */
async function checkForAlerts(metrics, db) {
  // 核心Web Vitals警报
  const alerts = [];

  // LCP警报 - 超过2.5秒为中等问题,超过4秒为严重问题
  if (metrics.lcp > 4000) {
    alerts.push({
      type: 'LCP',
      level: 'critical',
      value: metrics.lcp,
      url: metrics.context?.url,
      userId: metrics.context?.userId,
      timestamp: new Date()
    });
  } else if (metrics.lcp > 2500) {
    alerts.push({
      type: 'LCP',
      level: 'warning',
      value: metrics.lcp,
      url: metrics.context?.url,
      userId: metrics.context?.userId,
      timestamp: new Date()
    });
  }

  // CLS警报 - 超过0.1为中等问题,超过0.25为严重问题
  if (metrics.cls > 0.25) {
    alerts.push({
      type: 'CLS',
      level: 'critical',
      value: metrics.cls,
      url: metrics.context?.url,
      userId: metrics.context?.userId,
      timestamp: new Date()
    });
  } else if (metrics.cls > 0.1) {
    alerts.push({
      type: 'CLS',
      level: 'warning',
      value: metrics.cls,
      url: metrics.context?.url,
      userId: metrics.context?.userId,
      timestamp: new Date()
    });
  }

  // FID警报 - 超过100ms为中等问题,超过300ms为严重问题
  if (metrics.fid > 300) {
    alerts.push({
      type: 'FID',
      level: 'critical',
      value: metrics.fid,
      url: metrics.context?.url,
      userId: metrics.context?.userId,
      timestamp: new Date()
    });
  } else if (metrics.fid > 100) {
    alerts.push({
      type: 'FID',
      level: 'warning',
      value: metrics.fid,
      url: metrics.context?.url,
      userId: metrics.context?.userId,
      timestamp: new Date()
    });
  }

  // INP警报 - 超过200ms为中等问题,超过500ms为严重问题
  if (metrics.inp > 500) {
    alerts.push({
      type: 'INP',
      level: 'critical',
      value: metrics.inp,
      url: metrics.context?.url,
      userId: metrics.context?.userId,
      timestamp: new Date()
    });
  } else if (metrics.inp > 200) {
    alerts.push({
      type: 'INP',
      level: 'warning',
      value: metrics.inp,
      url: metrics.context?.url,
      userId: metrics.context?.userId,
      timestamp: new Date()
    });
  }

  // 如果有警报,保存到数据库
  if (alerts.length > 0) {
    const alertsCollection = db.collection('performance_alerts');
    await alertsCollection.insertMany(alerts);

    // 如果有严重警报,触发通知
    const criticalAlerts = alerts.filter(alert => alert.level === 'critical');
    if (criticalAlerts.length > 0) {
      await sendAlertNotification(criticalAlerts);
    }
  }
}

/**
 * 发送警报通知
 */
async function sendAlertNotification(alerts) {
  // 实际项目中可以集成Slack、邮件等通知服务
  console.error('Critical performance alerts:', alerts);

  // 为了简化示例,这里我们只记录了警报
  // TODO: 集成实际的通知机制,例如:
  // await fetch(process.env.SLACK_WEBHOOK, {
  //   method: 'POST',
  //   body: JSON.stringify({
  //     text: `🚨 Critical Performance Issues Detected:\n${alerts.map(a =>
  //       `${a.type}: ${a.value} on ${a.url}`
  //     ).join('\n')}`
  //   })
  // });
}

结语

现代WordPress企业官网开发已经远超传统的主题开发范畴,通过技术深度探索,我们可以看到WordPress已不仅仅是一个内容管理系统,而是一个可以与现代前端工程化深度结合的全栈开发平台。

在本文中,我们从前端工程化角度,详细剖析了企业级WordPress官网的技术架构和实现细节。通过构建系统现代化、模块化开发范式、关键渲染路径优化、高级图像处理、API集成、Headless CMS模式等多个角度,展示了如何突破WordPress传统限制,打造高性能、可维护的企业数字门户。

值得强调的是,企业官网不应仅仅满足于基本的展示需求,更应当关注用户体验的可度量指标、长期可维护性和系统扩展性。现代化的WordPress开发需要前端工程师跳出传统思维模式,将前沿的前端工程实践与WordPress的内容管理优势相结合,才能真正发挥这一平台的价值。

对于前端开发者而言,掌握深层次的WordPress架构设计与性能优化技术,不仅能提升项目质量,也能在纷繁复杂的企业需求中游刃有余。而对于企业而言,基于这些最佳实践构建的官网不仅能提供优质的用户体验,也能为后续的业务扩展和技术迭代奠定坚实基础。

无论是作为传统CMS还是转向Headless架构,WordPress的技术生态依然充满活力,持续深入学习和实践,才能在当今竞争激烈的数字化时代中,为企业打造出真正具有竞争力的官网产品。