Smile-SA/elasticsuite

Slow loading of search results page with filters enabled

taurus-media opened this issue · 1 comments

When ElasticSuite is enabled and there are many filterable attributes configured, search page loads very slowly. The same issue also affects non-cached category pages with layered navigation enabled.

Preconditions

Magento Version : CE 2.4.6-p5
ElasticSuite Version : 2.11.6
Environment : Production

Steps to reproduce

  1. Configure ~30 attributes to be filterable on search results page
  2. Try using Magento search
  3. Go to search results page

Expected result

  1. Search results page loads fast enough

Actual result

  1. It takes around 15-20 seconds to load (server response time)

Additional Info

After enabling Magento profiler and debugging the issue, it turned out that this is related to changes in the following file:
\Smile\ElasticsuiteCatalog\Model\ResourceModel\Product\Fulltext\Collection

The problem is that the following line is added in multiple places:
$this->_isFiltersRendered = false;

Filters should be collected only once per page load. But since _isFiltersRendered gets reseted for every filter, module makes a request to Elasticsearch for every single filterable attribute. Such a request takes around 0.5 seconds. So if there are 30 filterable attributes, it will take 30*0.5=15 seconds to render the filters section only.

Temporary Fix

A quick fix is to add a flag Collection::filtersRendered as a class member:
private $filtersRendered = false;

And then set it to true once the filters are rendered:

protected function _renderFilters()
{
    if ($this->filtersRendered) {
        return $this;
    }

    $this->_filters = [];
    
    parent::_renderFilters();

    $this->filtersRendered = true;

    return $this;
}

Hello @taurus-media,

The multiple locations (and legacy, mind you) where $this->_isFiltersRendered = false; is applied make total sense, it's basically when the collection / request "parameters" are changed: pageSize, curPage, search query, search filters.

On the other hand, while I see where you're coming from with a possible "multiple getFacetedData = multiple _renderFilters = multiple _renderFiltersBefore = multiple search query execution".
But that something that we have never noticed.
We'll have a look into it.

Regards,