Ускоряем SeoFilter или почему хлебные крошки такие дорогие


Последнее время почти на каждом магазине встречаю компонент SeoFilter. Полагаю, что компонент пользуется спросом, т.к. позволяет очень точечно оптимизировать динамические страницы фильтра mSearch2. Вот и в этот раз ко мне обратился человек с задачей оптимизации скорости ИМ, на котором был установлен данный компонент.
Я уже однажды писал статью про оптимизацию фильтра каталога, реализованного на mSearch2, однако в этот раз дело было совершенно в другом…

Начав изучать выдачу DebugParser, я погрузился в лёгкое недоумение от того, что 3-7 секунд (в зависимости от страницы), проходило мимо логов. Не стану вдаваться в подробности и детальное описание отладки кода, скажу лишь, что мои изыскания привели меня к методу SeoFilter::findSeoLink.

Таблица класса sfUrlWord, которая несколько раз джоинится в запрос в данном методе, содержит более 600k строк. Не сказать, что это много, учитывая, что компонент генерирует огромное кол-во объектов в базе и постоянно выполняет туда запросы. К слову, товаров на сайте чуть более 2k, а полей в фильтре 11 штук (это вместе с ценовым слайдером).

Насколько я понял, данный метод выполняет запрос к базе и возвращает массив с данными страницы для формирования хлебных крошек. Делает он это несколько раз, в зависимости от того, сколько страниц в цепочке крошек. При чём отрабатывает он только при включённой настройке seofilter_crumbs_nested. Ни в документации к компоненту, ни на просторах Интернета я не нашёл ничего про эту настройку, а из описания я нифига не понял, поэтому до сих пор полагаю, что она отвечает за динамический вывод хлебных крошек при фильтрации товаров. Но отключив её и протестировав, работают ли динамические крошки, оказалось, что они работают. Хм, значит она нужна для чего-то ещё…

Увы, запрос я не оптимизировал, т.к. отключение данной настройки ничего не ломает на данном сайте. Однако, если это поможет, то я заметил, что дольше всего отрабатывает запрос с HAVING levels = 1, а быстрее всего HAVING levels = 3.

Вообще, я полагаю, что узкое место в запросе выглядит как-то так:
SELECT ..., COUNT(sfUrlWord0.id) as levels FROM ... HAVING levels = 1
Другими словами, стоит обратить внимание именно на то, как заменить этот кусок. Велика вероятность, что разбив запрос на пару и перетащив часть логики на сторону PHP, можно существенно ускорить этот метод.

Предлагаю обсудить, за что отвечает эта настройка и как можно ускорить данный метод на большом количестве SEO-страниц.
Павел Гвоздь
14 июня 2019, 09:30
modx.pro
1
681
+10
Поблагодарить автора Отправить деньги

Комментарии: 17

Yar
Yar
14 июня 2019, 11:09
+1
С интересом прочитал о выполненных работах, хотя компонентом не пользуюсь…
    Евгений Шеронов
    14 июня 2019, 14:14
    +2
    Привет!

    seofilter_crumbs_nested
    — эта настройка для виртуального вкладывания хлебных крошек)
    То есть не просто одну ссылку выведет — а все предыдущие к текущей вложенности.

    То есть так: Телефоны -> Красные телефоны -> Красные iPhone -> Красные iPhone 64gb (где реальная категория только телефоны).

    За исследование спасибо!
    Давно хочу взяться за серьёзную переработку, версию 2.0 так сказать.
    Возможно, эта статья поспособствует этому)

    P.s. если можно, то глянул бы что происходит на том сайте.
    Возможно, сразу выпущу обновление под такое количество.
      Павел Гвоздь
      15 июня 2019, 08:13
      0
      P.s. если можно, то глянул бы что происходит на том сайте.
      Сайт клиента, так что вряд ли.
        kudesia
        10 июля 2019, 14:58
        0
        Добрый день.
        Помогите, пожалуйста, найти где происходит подмена названия ссылки в хлебных крошках.
          Евгений Шеронов
          10 июля 2019, 18:43
          0
          Добрый день!
          Если настраивали по инструкции, то в вызов pdoCrumbs добавлен чанк Сео фильтра для текущей ссылки.

          Обновляется же всё так: при первой загрузке серверно формируются крошки, при фильтрации через ajax по классам.

          Если интересует именно замена названий ссылок — то первый вариант:
          Просто переименовать, а второй:
          у Seo страниц в компоненте есть ещё menutitle. Его можно заполнять и использовать в чанке. Возможно, он автоматически применится в крошках)
            kudesia
            10 июля 2019, 20:51
            0
            Используется компонент BreadCrumb
            [[!BreadCrumb? 
            			&showBreadCrumbAtHome=`0` 
            			&containerTpl=`@INLINE <ul class="breadcrumbs" itemprop="breadcrumb">[[+crumbs]]</ul>` 
            			&homeCrumbTpl=`@INLINE <li itemscope="itemscope" itemtype="http://data-vocabulary.org/Breadcrumb"><a href="[[+link]]" itemprop="url" rel="nofollow">Главная</a></li>` 
            			&linkCrumbTpl=`@INLINE <li itemscope="itemscope" itemtype="http://data-vocabulary.org/Breadcrumb"><a href="[[+link]]" itemprop="url" rel="dofollow">[[+menutitle]]</a></li>`
            			¤tCrumbTpl=`@INLINE <li itemscope="itemscope" itemtype="http://data-vocabulary.org/Breadcrumb"><span>[[!+sf.h1:default=`[[*menutitle:default=`[[*longtitle:default=`[[*pagetitle]]`]]`]]`]]</span></li>` 
            			]]
            Даже если я убираю из кода [[+menutitle]] — при выборе в фильтре пункта фильтрации, крошки все равно появляются.
              Евгений Шеронов
              10 июля 2019, 23:45
              0
              Ну тут точно не рекомендую использовать инлайн чанк для активной ссылки.

              И не заметил, чтобы здесь хоть как-то содержимое чанка крошек из SeoFilter использовалось.

              Рекомендую проверить всё что необходимо на pdoCrumbs — если там не будет работать так, как нужно — то это проблема и с ней жду обращения в тех поддержку на modstore с ссылками, доступами или скриншотами)
                adminixi
                11 июля 2019, 17:45
                0
                [[!+sf.h1:default=` .....
                вот из SeoFilter
                  Евгений Шеронов
                  11 июля 2019, 21:27
                  0
                  Это не из крошек Seo фильтра)
                  Для крошек есть другое стандартное решение.

                  Но если хотите чтобы текст по этому плейсхолдеру заменялся — не забудьте обернуть классом sf_h1.
        Александр Мельник
        13 июля 2019, 09:56
        0
        Спасибо Павел. Наша компания собирается использовать данный сеофильтр на двух крупных проектах и у меня возник возможно глупый, но мне кажется важный вопрос.
        Каким образом поисковые системы узнают о существовании таких вот отфильтрованных страниц?
        Наши сеошники к примеру пропишут в админпанели meta данные для отфильтрованной страницы, пользователь на сайте, нажав на соответствующие чекбоксы увидит результаты и заданные специалистами meta данные.
        Но поисковик как узнает о существовании такой страницы? Ведь поисковый бот не кликает по чекбоксам. Данные страницы попадают в сайтмап? Вряд-ли мне кажется. Не окажется так что весь сео фильтр работает исключительно на посетителя человека, но совершенно бесполезен для посетителя поискового бота?

        Почему возник этот вопрос. У нас много проектов на битриксе, где есть подобный компонент фильтрации, он позволяет задать для разных вариантов фильтрации задавать индивидуальные h1, title, description и кое-что еще. Мы долгое время заполняли эти данные, но когда я сел 2 месяца назад за написание ТЗ для двух новых проектов и узнал что на modx существует ваш компонент, то решили его использовать. И мне пришла мысль — проверить а знает ли вообще поисковик о таких страницах. Для всех проектов на битриксе я изучил данные из яндекс вебмастера (страницы в индексе) и оказалось, что яндекс не знает ни одной такой страницы…

        Спасибо.
          Павел Гвоздь
          13 июля 2019, 10:02
          +1
          и узнал что на modx существует ваш компонент
          Он не мой. @Евгений Шеронов

          Я сомневаюсь, что Яндекс узнает об этих страницах, только если через код Яндекс Метрики. Но вы можете вручную на страницах сайта указывать ссылки на эти страницы + можно поизвращаться и создать отдельный сайтмап из таблиц этого компонента.
            Александр Мельник
            13 июля 2019, 10:06
            0
            Я вас понял.
            Просто это строительные материалы, у них а каждого товара около 30 характеристик. Я так подозреваю, что даже внутри одной категории возникнет несколько миллионов вариантов отфильтрованных страниц, и вручную «скармливать» их яндексу или вписывать в свою карту сайта получиться вряд ли.
              Павел Гвоздь
              13 июля 2019, 10:10
              0
              Да + будут проблемы (большие) с производительностью, если использовать связку, описанную в данной статье (mSearch2 + SeoFilter), и дело не в том, что они в связке дают такой эффект, но и отдельно mSearch2 на большом кол-ве товаров и опций в фильтре будет тормозить.
              Александр Мельник
              13 июля 2019, 10:09
              0
              ааа, я чуток протупил. У него есть своя таблица, где хранится информация об этих урлах и можно автоматизировать процесс заполнения своего сайтмапа. Спасибо.
              Евгений Шеронов
              13 июля 2019, 10:23
              0
              Отвечу тогда тоже, раз меня упомянули)

              Роботы на самом деле щёлкают по чекбоксам, ну у Яндекса точно. Но для индексации другие методы.

              Карта сайта — для этого есть свой сниппет sfSitemap.
              Меню в категориях — сниппет sfMenu.
              Ссылки со страниц товаров через sfLink.

              От реальных страниц-ресурсов для работа такие страницы не отличаются.
                Александр Мельник
                13 июля 2019, 10:26
                0
                о как вы быстро, а я написал отдельную заметку. Если не сложно то продублируйте в ней, вдруг полезно будет другим. modx.pro/help/18580
                  Александр Мельник
                  13 июля 2019, 10:55
                  0
                  Я скопирую ваш ответ в отдельную заметку.
                  Роботы на самом деле щёлкают по чекбоксам, ну у Яндекса точно.
                  Прямо аж очень интересно, наверное мои знания в этом деле сильно устарели. Я считаю что боты поисковые не видят страницу как пользователи, они видят лишь код страницы, который возвращает сервер по этому урл. Как в коде можно кликнуть на чекбокс, ведь клик — это событие браузера.
                Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                17