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

[4.x]: Field Layout Designer Loads very slow compared to version 3. #11298

Closed
myleshyson opened this issue May 23, 2022 · 6 comments
Closed

[4.x]: Field Layout Designer Loads very slow compared to version 3. #11298

myleshyson opened this issue May 23, 2022 · 6 comments

Comments

@myleshyson
Copy link
Contributor

What happened?

Description

I noticed this originally when trying to update a neo field's settings. The settings page took about 4-5 minutes to load. I thought maybe it was a neo bug and opened an issue with them. However the more I dug into it the more I realized the bottleneck is coming from \craft\helpers\Cp::fieldLayoutDesignerHtml. In the update it looks like the logic for displaying field layouts was relegated all to php. I confirmed it's not necessarily a neo issue by trying to create a new Entry Type on on a section. Here's some screenshots of response times comparing Craft v3 to Craft v4 when loading the entry type settings page.

Craft 3:
Screen Shot 2022-05-23 at 11 59 20 AM

Craft 4:
Screen Shot 2022-05-23 at 3 14 03 PM

Now there are some things to note about our project. We're building a relatively large hospital system site with a lot of different types of content. As such, our field count is currently sitting at 365 and growing. I noticed that \craft\helpers\Cp::fieldLayoutDesignerHtml is doing some deep nested loops of available fields which maybe contributing to the response time difference here.

As a side note, those 31 warnings and errors on the craft 4 screenshot were coming from the EntryTitleField layout class namespace changing from craft\fieldlayoutelements\EntryTitleField to craft\fieldlayoutelements\entries\EntryTitleField and the "elements" column in the "fieldlayouttabs" table not updating its values with the new namespace. I added a migration to our project to do that but bringing it up just in case that's something that should be added as part of the core upgrade migrations as well. This problem still persists when that is fixed.

Any help or insight ya'll can give would be much appreciated! Also as a sidenote, the upgrade guide is phenomenal and this is the only issue I've run across so far.

Craft CMS version

4.0.3

PHP version

8.1.

Operating system and version

No response

Database type and version

mysql 8

Image driver and version

No response

Installed plugins and versions

  • Neo
  • Store Hours
  • Redactor
  • Link It
  • We have more but I was experiencing this with 0 plugins and with the ones listed here.
@maxstrebel
Copy link

Can confirm. Here's a NEO Field in Craft 4. A NEO field with more fields will not even load because it exhausts 1024M memory.

image

@brandonkelly
Copy link
Member

Thanks for pointing that out. Just made a change for the next release that should make it better.

If you’d like to get the change early, change your craftcms/cms requirement in composer.json to "dev-develop as 4.0.3" and run composer update.

@myleshyson
Copy link
Contributor Author

myleshyson commented May 24, 2022

I tested the fix and we're still getting the same response time. It caches the initialization of the UserCondition::class, but that class still generates all selectable conditions for every field.

My co-worker found if you cache the selectable conditions then response times go back to normal. Here's what he did.

// \craft\base\conditions\BaseCondition

private static $rules;

/**
     * @inheritdoc
     */
    public function getSelectableConditionRules(): array
    {
        $conditionsService = Craft::$app->getConditions();
        $hash = md5(serialize($this->getConditionRuleTypes()));

        if (!isset(self::$rules[$hash])) {
            self::$rules[$hash] = Collection::make($this->getConditionRuleTypes())
                ->keyBy(fn($type) => is_string($type) ? $type : Json::encode($type))
                ->map(fn($type) => $conditionsService->createConditionRule($type))
                ->filter(fn(ConditionRuleInterface $rule) => $this->isConditionRuleSelectable($rule))
                ->all();
        }
        return self::$rules[$hash];
    }

He drilled down and found that getSelectableConditions method is the main performance culprit. Your fix mixed with this brought the response time for creating a new entry type down to under a second again. Neo is still kinda slow but it at least loads in 8 seconds vs 600 seconds.

Is this or some form of this possible to add as part of the fix as well?

brandonkelly added a commit that referenced this issue May 24, 2022
@brandonkelly
Copy link
Member

Doh, yeah you’re right. Hashing shouldn’t be necessary, because the selectable condition rules are unlikely to change within a single request. Just made that change for the next release.

@myleshyson
Copy link
Contributor Author

Yep that did the trick. Thanks!

@brandonkelly
Copy link
Member

Craft 4.0.4 is out now with those perf improvements ✨

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

No branches or pull requests

3 participants