WordPress: Сайт перестаёт грузиться при навигации после перемещения блока через output buffering
Использую output buffering в WordPress для перемещения блока term-description (SEO-оптимизация). Код корректно работает при первой загрузке страницы, но при переходе на другие страницы сайт перестаёт грузиться (белый экран или бесконечная загрузка).
Что делает код:
- Находит блок
<div class="term-description">
- Создает плейсхолдер с теми же стилями
- Переносит оригинальный блок после
<body>
(скрыто, для SEO) - Добавляет JS для синхронизации содержимого
Попробовал:
- Очистку кеша
- Отключение других плагинов
- Упрощение JS-часта
Вопрос: Почему буферизация ломает загрузку при навигации? Как это исправить?
add_action('template_redirect', function () {
if (is_admin() || wp_doing_ajax() || is_feed()) return;
ob_start(function ($html) {
if (preg_match('#(<div[^>]*class=["\'][^"\']*term-description[^"\']*["\'][^>]*>.*?</div>)#is', $html, $m)) {
$block = $m[1];
// Создаем DOM для копирования стилей
$dom = new DOMDocument();
@$dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
$xpath = new DOMXPath($dom);
// Находим оригинальный элемент
$original = $xpath->query("//div[contains(@class, 'term-description')]")->item(0);
if ($original) {
// Копируем все стили из оригинала
$styles = '';
if ($original->hasAttribute('style')) {
$styles = $original->getAttribute('style');
}
// Копируем классы
$classes = '';
if ($original->hasAttribute('class')) {
$classes = $original->getAttribute('class');
}
// Создаем плейсхолдер с теми же размерами и стилями
$placeholder = '<div id="term-description-placeholder" class="'.$classes.'" style="'.$styles.';visibility:hidden;height:auto!important;"></div>';
// Вставляем плейсхолдер
$html = str_replace($block, $placeholder, $html);
// Вставляем оригинальный блок после body (для SEO)
$html = preg_replace(
'#(<body[^>]*>)#i',
'$1' . "\n" . '<div class="seo-term-description" style="display:none!important;">' . $block . '</div>',
$html,
1
);
// Добавляем скрипт для синхронизации
$script = <<<JS
<script>
(function(){
function syncElements() {
var original = document.querySelector('.seo-term-description > div');
var placeholder = document.getElementById('term-description-placeholder');
if (!original || !placeholder) return;
// Копируем содержимое
placeholder.innerHTML = original.innerHTML;
// Показываем плейсхолдер
placeholder.style.visibility = 'visible';
// Обновляем размеры при изменениях
var observer = new MutationObserver(function() {
placeholder.innerHTML = original.innerHTML;
});
observer.observe(original, {
childList: true,
subtree: true,
characterData: true
});
}
function init() {
syncElements();
window.addEventListener('resize', syncElements);
window.addEventListener('scroll', syncElements, {passive: true});
// Для динамических изменений в блоках
setInterval(syncElements, 1000);
}
if (document.readyState === 'complete') {
init();
} else {
document.addEventListener('DOMContentLoaded', init);
}
})();
</script>
JS;
$html = str_replace('</body>', $script . '</body>', $html);
}
}
return $html;
});
});
Источник: Stack Overflow на русском