Новое: Yoast выпускает оптимизацию производительности для крупных веб-сайтов.

SEO

Новое: Yoast выпускает оптимизацию производительности для крупных веб-сайтов.

<Изображение fetchpriority="высокий" ширина = "400" высота="210" декодирование = «асинхронный» loading="жаждущий" size="(максимальная ширина: 1012 пикселей) 100vw, 1012 пикселей" src="https://yoast.com/cdn-cgi/image/width=1012%2Cheight=531%2Cfit=cover%2Cf=auto%2Cquality=75%2Conerror=redirect/app/uploads/2026/06/release_general.jpg" srcset="https://yoast.com/cdn-cgi/image/width=400%2Cheight=210%2Cfit=cover%2Cf=auto%2Cquality=75%2Conerror=redirect/app/uploads/2026/06/release_general.jpg 400w, https://yoast.com/cdn-cgi/image/width=400%2Cheight=210%2Cdpr=2%2Cfit=cover%2Cf=auto%2Cquality=75%2Conerror=redirect/app/uploads/2026/06/release_general.jpg 800 Вт, https://yoast.com/cdn-cgi/image/width=600%2Cheight=315%2Cfit=cover%2Cf=auto%2Cquality=75%2Conerror=redirect/app/uploads/2026/06/release_general.jpg 600 Вт, https://yoast.com/cdn-cgi/image/width=600%2Cheight=315%2Cdpr=2%2Cfit=cover%2Cf=auto%2Cquality=75%2Conerror=redirect/app/uploads/2026/06/release_general.jpg 1200 Вт, https://yoast.com/cdn-cgi/image/width=800%2Cheight=420%2Cfit=cover%2Cf=auto%2Cquality=75%2Conerror=redirect/app/uploads/2026/06/release_general.jpg 800 Вт, https://yoast.com/cdn-cgi/image/width=800%2Cheight=420%2Cdpr=2%2Cfit=cover%2Cf=auto%2Cquality=75%2Conerror=redirect/app/uploads/2026/06/release_general.jpg 1600 Вт, https://yoast.com/cdn-cgi/image/width=1012%2Cheight=531%2Cfit=cover%2Cf=auto%2Cquality=75%2Conerror=redirect/app/uploads/2026/06/release_general.jpg 1012w, https://yoast.com/cdn-cgi/image/width=1012%2Cheight=531%2Cdpr=2%2Cfit=cover%2Cf=auto%2Cquality=75%2Conerror=redirect/app/uploads/2026/06/release_general.jpg 2024w" альт="" >

В нашей последней версии 27.8 мы ввели оптимизацию производительности, которая должна сократить время загрузки всех функций плагина, особенно заметно на больших сайтах с большим количеством сообщений и пользователей. 

Примечание. Этот пост содержит техническое содержание и подробности реализации.

<п>Предложение хорошо настроенного программного обеспечения с минимальными нагрузками на сервер и быстрым временем загрузки всегда находится в авангарде всего, что делают разработчики Yoast. Однако Yoast SEO установлен на миллионах веб-сайтов, поэтому настройки разные, и мы должны быть к этому готовы. Это означает, что мы должны постоянно проверять и оптимизировать производительность подключаемого модуля Windows. Известно, что мы постоянно делали это в прошлом, например, когда мы улучшали нашу систему баз данных. 

Версия 27.8 — результат одного из таких целевых обзоров. Мы сознательно выбрали функции, поведение которых обеспечивает наибольшую гибкость при масштабировании, и перепроектировали их, чтобы сделать их более компактными и быстрыми. От изменения запросов для ускорения страниц для сайтов с большим количеством пользователей и сокращения тяжелых административных операций для сайтов с большим количеством сообщений до сокращения обращений к базе данных для выполнения нескольких функций и общего применения передовых методов повышения производительности – это выпуск, цель которого улучшить взаимодействие пользователей и разработчиков с плагином Yoast SEO. 

Мы также хотели бы предоставить техническое описание улучшений в этом выпуске, уделив особое внимание мельчайшим деталям, потому что всегда приятно повысить осведомленность о передовых методах повышения производительности (не говоря уже о том, что всегда интересно поговорить о коде). 

Значительно сократить время загрузки корневого файла Sitemap на сайтах с большим количеством пользователей 

<п>Для контекста Yoast использует SEO для расчета значения «Последнее изменение» карты сайта автора. В выводе корневой карты сайта используются мета-данные всех пользователей, которым разрешено включение в карту сайта автора.  

Подсчет авторизованных пользователей традиционно производился путем проверки пользовательских функций. Это было сделано путем добавления функции ’ => [ ‘edit_posts’ ] Аргумент в вызове Used get_users(). В результате был запущен очень большой запрос с несколькими соединениями и без использования индексов базы данных.  

В частности, в результирующий запрос добавлено такое предложение:  

И ((((mt1.meta_key = ‘wp_capabilities’ И mt1.meta_value LIKE ‘%”edit\_posts”%’) ИЛИ (mt1.meta_key = ‘wp_capabilities’ И mt1.meta_value КАК ‘%”администратор”%’) ИЛИ (mt1.meta_key = ‘wp_capabilities’ И mt1.meta_value КАК ‘%”editor”%’) ИЛИ (mt1.meta_key = ‘wp_capabilities’ И mt1.meta_value НРАВИТСЯ ‘%”author”%’) ИЛИ (mt1.meta_key = ‘wp_capabilities’ И mt1.meta_value НРАВИТСЯ ‘%”участник”%’) ИЛИ (mt1.meta_key = ‘wp_capabilities’ И mt1.meta_value LIKE ‘%”wpseo\_manager”%’) ИЛИ (mt1.meta_key = ‘wp_capabilities’ И mt1.meta_value КАК ‘%”wpseo\_editor”%’))))

Поскольку LIKE ‘%…%’ не может использовать индекс B-дерева, MySQL должен полностью прочитать каждую соответствующую  wp_capabilities строку и семь сканирований подстроки, из которых выполняются  сериализованное PHP meta_value на строку. 

<п>Изменив этот расчет с использования проверки навыков на поиск пользователей с опубликованными сообщениями (с помощью аргумента  use ‘ has_published_posts ‘ => true), мы немедленно преобразуем результирующий запрос в запрос, который использует индексы и гораздо лучше работает на сайтах с большим количеством пользователей.  

На самом деле, в одном из наших тестов на сайте с примерно 2 миллионами пользователей время, необходимое для выполнения каждого запроса, составляло (примерно время, необходимое для получения корневой карты сайта). для рендеринга), перешел с более 300 секунд вниз на всего 25 миллисекунд! Это означает, что The change имеет потенциал для радикального улучшения времени загрузки корневых файлов Sitemap на похожих сайтах.  

Наконец, учитывая, что на сайте  ‘ has_published_posts ‘ => Если аргумент уже использовался на более позднем этапе создания карты сайта, само изменение практически не должно иметь негативного влияния на фактическую функциональность карты сайта. 

Уменьшить время загрузки карты сайта автора на сайтах с большим количеством пользователей 

<п>Чтобы Yoast SEO отображал и создавал карты сайта, необходимо рассчитать авторизованных пользователей. На веб-сайтах с большим количеством пользователей это может оказаться очень трудоемким процессом. Помимо вышеупомянутой оптимизации, мы заметили, что при подсчете подходящих пользователей Yoast SEO также добавил мета-запрос, чтобы проверить, превышает ли уровень пользователя каждого пользователя 0,60/p~62.

Оказалось, что это пережиток старых времен, поскольку фреймворк User_Level устарел с версии 3.0 WP Core. Хотя это не вызвало каких-либо проблем с функциональностью нашей карты сайта, к результирующему запросу было добавлено INNER JOIN без особой цели и на сайтах с очень большим количеством пользователей и пользовательскими таблицами, что снизило производительность. Итак, у нас есть  ненужное ПРИСОЕДИНИТЬСЯ: 

удалено ВНУТРЕННЕЕ СОЕДИНЕНИЕ wp_usermeta AS mt1 ON wp_users.ID = mt1.user_id  …  И ( mt1.meta_key = ‘wp_user_level’ И mt1.meta_value != ‘0’ )

Поскольку структура «user_level» уже давно устарела, мы сознательно решили прекратить ее поддержку, особенно потому, что это сделает нашу функциональность более плавной. На самом деле, мы довольны этой оптимизацией и ожидаем, что она вызовет минимальные нарушения именно из-за возраста этой настройки. 

Предотвращение ненужных дорогостоящих запросов к базе данных на страницах администратора 

<п>Чтобы своевременно информировать администраторов о том, что им необходимо выполнить необходимые действия для того, чтобы их данные были оптимально проиндексированы в нашем внутреннем хранилище, Yoast SEO используется для выполнения a запросов к базе данных ежедневно по мере того, как администраторы перемещаются по серверной части системы. Для больших веб-сайтов это Запрос к базе данных мог выполняться в течение нескольких секунд Отображение страниц администратора периодически замедлялось 

Подробнее, следующая функция:

Limited_Indexing_Action_Interface::get_limited_unindexed_count()

Это позволяет выполнять сложные запросы, подобные приведенным ниже, которые регулярно выполнялись на страницах администратора и замедляли рендеринг на крупных сайтах.  SELECT Count(P.id)  FROM   wp_posts AS P  ГДЕ  P.post_type IN ( ‘post’, ‘page’ )         И P.post_status НЕ В ( ‘автоматический черновик’)         И P.id НЕ ВХОДИТ (SELECT I.object_id             & nbsp;            FROM   wp_yoast_indexable LIKE I             & nbsp;            WHERE  I.object_type = ‘post’                                  И I.версия = 2) <п>Нам удалось перепроектировать логику кода, отвечающего за уведомление, информирующее администраторов об ожидающих действиях, так что эти большие запросы теперь выполняются только один раз, на данный момент это первый раз, когда было обнаружено что такое уведомление создается должен.  

Таким образом, мы эффективно кэшируем результаты

. Limited_Indexing_Action_Interface::get_limited_unindexed_count() <п>и полагаться на аннулирование кеша, которое существовало до наших изменений, но не использовалось должным образом. Это привело к потенциально очень большому запросу к базе данных: от ежедневного запуска (и каждые 15 минут на очень загруженных сайтах с большим количеством одновременных пользователей) до одного запуска на большинстве сайтов. 

Оптимизация дорогостоящих запросов к базе данных на страницах администратора  

В связи с упомянутым выше изменением предотвращения запросов нам не только удалось избежать выполнения вышеупомянутых больших запросов к базе данных более одного раза для каждого сайта, но нам также удалось оптимизировать сам запрос. Дополнительным преимуществом этого является то, что мы сделали инструмент SEO-оптимизации намного быстрее на сайтах с большим количеством сообщений. 

В частности, мы предполагали: 

И P.ID НЕ ВХОДИТ (      SELECT I.object_id FROM wp_yoast_indexable AS I      WHERE I.object_type = ‘post’  )

Кому:  

И НЕ СУЩЕСТВУЕТ (      ВЫБЕРИТЕ 1 ИЗ wp_yoast_indexable AS I      WHERE I.object_id = P.ID        AND I.object_type = ‘post’  )

Поскольку НЕ В (подзапрос) создается весь список идентификаторов объектов, в то время как второй запрос замыкает момент совпадения строки,  запрос становится значимым. Запускайте более быстрые веб-сайты. с несколькими тысячами постов. 

Уменьшить количество обращений к базе данных 

<п>Как правило, обращение к базе данных туда и обратно — дорогостоящая операция, которую следует по возможности сводить к минимуму. В ходе наших проверок мы обнаружили случаи, когда мы получали данные для нескольких публикаций в последовательных запросах SELECT, тогда как мы могли запустить один пакетный запрос SELECT для сбора данных для всех сообщений одновременно. 

Например, фрагмент кода выглядел так:

$indexables = [];  foreach ( $post_ids as $post_id ) {  $indexables[] = $this->repository->find_by_id_and_type( (int) $post_id, ‘post’ );  }

был переработан и выглядел примерно так: 

$ indexables = $this->repository->find_by_multiple_ids_and_type(  array_map( ‘intval’, $post_ids ),  ‘пост’,  ); <п>Это означало, что вместо выполнения 1000 запросов SELECT, которые возвращали максимум одну строку, для части из 1000 сообщений, мы теперь выполняем один запрос SELECT, который возвращал максимум  1000 строк. Конечно, мы позаботились о том, чтобы количество запрошенных сообщений каждый раз не превышало определенного порога, чтобы достичь ограничений на использование MySQL. избегать. 

В результате веб-сайты, например, B. 1000 публикаций 960 обращений к базе данных для конкретных операций, таких как сохранение части результатов SEO-оптимизации или части выходных данных функции агрегирования схемы. 

Улучшите производительность редактора сообщений, предотвратив ненужный повторный рендеринг 

Редактор WordPress повторно отображает боковые панели Yoast каждый раз, когда данные, которые они извлекают из хранилища, изменились. определяется равенством ссылок (JavaScript ===), а не сравнением значений. Селектор, возвращающий { items: [‘foo’] }  выглядит как человек, но если это каждый раз новый литерал объекта, React будет рассматривать его как новый и повторно отображать панель. А если мы умножим это на занятого редактора, отправляющего обновления статуса при каждом нажатии клавиши, мы получим панели, которые постоянно перерисовываются без причины. 

В версии 27.8 мы выявили несколько случаев, когда данные, которые фактически не были изменены, вызывали ненужные повторные рендеринги в редакторе сообщений, и исправили их, сделав интеграцию нашего редактора намного более надежной и производительной. 

<п>

Back To Top