feat(pagespeed): implement YouTube Facade Pattern - Phase 2.4

PageSpeed Optimization to reduce TBT by ~2000ms:
- Add YoutubeFacade module following Clean Architecture
- Replace YouTube iframes with thumbnail + play button
- Load real iframe only on user click (lazy-load)
- Reduces initial page blocking time significantly

Files added:
- Public/YoutubeFacade/Infrastructure/Wordpress/YoutubeFacadeHooksRegistrar.php
- Public/YoutubeFacade/Infrastructure/Services/YoutubeFacadeContentFilter.php
- Public/YoutubeFacade/Infrastructure/Ui/YoutubeFacadeRenderer.php
- Public/YoutubeFacade/Infrastructure/Ui/Assets/Css/youtube-facade.css
- Public/YoutubeFacade/Infrastructure/Ui/Assets/Js/youtube-facade.js

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
FrankZamora
2025-11-27 13:28:20 -06:00
parent b0def25348
commit 133b364c78
6 changed files with 373 additions and 0 deletions

View File

@@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
namespace ROITheme\Public\YoutubeFacade\Infrastructure\Services;
use ROITheme\Public\YoutubeFacade\Infrastructure\Ui\YoutubeFacadeRenderer;
/**
* Filters post content to replace YouTube iframes with facades
*
* Detects YouTube iframes (including those wrapped in .video-wrapper)
* and replaces them with lightweight facade HTML.
*
* @package ROITheme\Public\YoutubeFacade
* @since 1.0.6
*/
final class YoutubeFacadeContentFilter
{
private YoutubeFacadeRenderer $renderer;
public function __construct(YoutubeFacadeRenderer $renderer)
{
$this->renderer = $renderer;
}
/**
* Filter content to replace YouTube iframes with facades
*
* @param string $content Post content
* @return string Filtered content
*/
public function filter(string $content): string
{
// Match YouTube iframes (with or without video-wrapper)
// Pattern handles both youtube.com/embed/ and youtube-nocookie.com/embed/
$pattern = '/<div class="video-wrapper">\s*<iframe[^>]*src="https?:\/\/(?:www\.)?(?:youtube\.com|youtube-nocookie\.com)\/embed\/([a-zA-Z0-9_-]+)[^"]*"[^>]*><\/iframe>\s*<\/div>/is';
$content = preg_replace_callback($pattern, function ($matches) {
$videoId = $matches[1];
return $this->renderer->render($videoId);
}, $content);
// Also match standalone iframes without wrapper
$patternStandalone = '/<iframe[^>]*src="https?:\/\/(?:www\.)?(?:youtube\.com|youtube-nocookie\.com)\/embed\/([a-zA-Z0-9_-]+)[^"]*"[^>]*><\/iframe>/is';
$content = preg_replace_callback($patternStandalone, function ($matches) {
$videoId = $matches[1];
return $this->renderer->render($videoId);
}, $content);
return $content;
}
}