Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ReadonlyTagField loads all option items, without lazy loading, prior to returning selected ones #309

Open
2 tasks done
adunn49 opened this issue Sep 27, 2024 · 1 comment
Labels

Comments

@adunn49
Copy link

adunn49 commented Sep 27, 2024

Module version(s) affected

3.2.1

Description

Hey team,
I believe there is a performance issue when loading the TagField in read only mode (using TagField 3.2.1). The finding of this issue has come about through the combination of a number of other modules, namely a virtual elemental block (that now uses TagField), in conjunction with a workflow module that renders the TagField in read only mode. In a project this resulted in tens of thousands of blocks being returned in a query, causing very slow behaviour in the CMS.

How to reproduce

This issue can be seen with the following steps:

  • Adding a TagField to a page
  • Making the source of the TagField pages within the site
  • Adding a read only transformation to the added field.

So, in code, something like …

private static array $has_one = [
    'Tags' => TagField::class,
];

/**
 * @inheritDoc
 */
public function getCMSFields()
{
    $fields = parent::getCMSFields();

    $availablePages = SiteTree::get();

    $fields->addFieldToTab(
        'Root.Main',
        TagField::create('TagsID', 'Linked Page', $availablePages)
            ->setIsMultiple(false)
            ->setCanCreate(false)
            ->setShouldLazyLoad(true)
            ->setTitleField('Title')
            ->performReadonlyTransformation()
    );

    return $fields;
}

With these steps, and using debugging tools, although you won't experience the levels of performance degredation without a large number of items, you should be able to see that this loads all pages and performs a function on each to return an array of options (https://github.com/silverstripe/silverstripe-tagfield/blob/3/src/TagField.php#L310-L328).

Possible Solution

The issue, I believe, stems from the ReadOnlyTagField class (https://github.com/silverstripe/silverstripe-tagfield/blob/3/src/ReadonlyTagField.php#L30) where the getOptions method is called on the TagField class. Looking in the getOptions function it can be seen that without the $onlySelected attribute passed in, lazy loading is assumed false and this will load all items. It would seem that ReadOnlyTagField class only needs the selected fields so calling getOptions(true) might be a solution, but not sure it is as simple as that!?!

Additional Context

No response

Validations

  • Check that there isn't already an issue that reports the same bug
  • Double check that your reproduction steps work in a fresh installation of silverstripe/installer (with any code examples you've provided)
@GuySartorelli
Copy link
Member

Thanks for reporting this.
Your suggested solution sounds like a good one. Would you like to raise a PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants