<p>Avoid calling <code>block.entry</code> multiple time per block since you only need to do that database query once. Alternatively you can use function memoization to cache the entry like this:</p>

<pre><code>class FruitGrid_BlockModel extends BaseModel
{
    private $_entry;

    protected function defineAttributes()
    {
        return array(
            'row' =&gt; array(AttributeType::Number),
            'col' =&gt; array(AttributeType::Number),
            'sizex' =&gt; array(AttributeType::Number),
            'sizey' =&gt; array(AttributeType::Number),
            'entryid' =&gt; array(AttributeType::Number),
            'rules' =&gt; array(AttributeType::Mixed),
        );
    }

    public function getRuleClasses()
    {
        //...
    }

    public function getEntry()
    {
        if(!$this-&gt;_entry){
            $criteria = craft()-&gt;elements-&gt;getCriteria(ElementType::Entry);
            $criteria-&gt;id = $this-&gt;entryid;
            $this-&gt;_entry = $criteria-&gt;first();
        }

        return $this-&gt;_entry;

    }
}
</code></pre>

<p>This will only get the entry from the database once.</p>

<p>Also recommend renaming the <code>rules</code> attribute on the model to something like <code>blockRules</code>.</p>

<p>When you loop over the rules to create the ruleClasses string you may be looping over every rule created by the AttributeType declarations in your <code>defineAttributes</code> method.</p>

CC BY-SA 3.0
2015-09-09T10:14:10.047Z
Ah I see, removing ```{{ block.ruleClasses }}``` improved things a drop, but I was accessing ```{{ block.entry.customField }}``` loads of times, storing / caching the entry and accessing it via this var helped loads. So does it get the entry each time i hit block.entry??
Sam Hibberd
CC BY-SA 3.0
2015-09-09T10:15:43.820Z
ah yes, you are doing a db call every time you do `block.entry`. You could cache it in the plugin function or just assign it once per block in the template like so: {% set blockEntry = block.entry %}. This would have been causing the huge slowdown more than my answer.
Luke Holder
CC BY-SA 3.0
2015-09-09T11:30:40.830Z
Yes, this was the issue, although your suggestion certainly helped speed things up. What do you mean by cache in the function? Set a var that is checked before grabbing the entry and set only if it has not be retrieved?
Sam Hibberd
CC BY-SA 3.0
2015-09-09T11:31:50.617Z
Sorry Luke, just saw you answer! Exactly as expected, thanks!!!
Sam Hibberd
CC BY-SA 3.0
2015-09-09T09:15:20.273Z
2015-09-09T10:24:50.947Z
2015-09-09T10:24:50.947Z
Luke Holder
<p>I'm getting a big performance hit on front end requests (+15 seconds) when using a model to store / use data from one of my custom fieldtypes, cp requests for the same data appear unaffected.</p>

<p>The prepValue function:</p>

<pre><code>public function prepValue($value)
{
    if( is_array($value) )
    {
        return FruitGrid_BlockModel::populateModels($value);
    }

    return $value;
}
</code></pre>

<p>And the model which is getting populated:</p>

<pre><code>class FruitGrid_BlockModel extends BaseModel
{
    protected function defineAttributes()
    {
        return array(
            'row' =&gt; array(AttributeType::Number),
            'col' =&gt; array(AttributeType::Number),
            'sizex' =&gt; array(AttributeType::Number),
            'sizey' =&gt; array(AttributeType::Number),
            'entryid' =&gt; array(AttributeType::Number),
            'rules' =&gt; array(AttributeType::Mixed),
        );
    }

    public function getRuleClasses()
    {
        $string = '';
        if(is_array($this-&gt;rules))
        {
            foreach ($this-&gt;rules as $rule =&gt; $value)
            {
                switch ($rule)
                {
                    case 'fixedHeight':
                        $string .= ' height-'.$value;
                        break;
                    case 'desktopRuleOne':
                        $string .= ' desktop-'.$value;
                        break;
                    case 'tabletRuleOne':
                        $string .= ' tablet-'.$value;
                        break;
                    case 'mobileRuleOne':
                        $string .= ' mobile-'.$value;
                        break;
                }
            }
        }
        return trim($string);
    }

    public function getEntry()
    {
        $criteria = craft()-&gt;elements-&gt;getCriteria(ElementType::Entry);
        $criteria-&gt;id = $this-&gt;entryid;
        return $criteria-&gt;first();
    }
}
</code></pre>

<p>And pretty standard usage on the front end:</p>

<pre><code>{% if entry.customFieldHandle|length %}

    {% for block in entry.customFieldHandle %}

        &lt;h1&gt;{{ block.entry.title }}&lt;/h2&gt;
        &lt;p&gt;{{ block.entry.text }}&lt;/p&gt;

        ...

    {% endfor %}

{% endif %}
</code></pre>

<plugin-development><fieldtypes><performance>
Craft model and populateModels() performance issue?
# Craft model and populateModels() performance issue?

(Asked by: username_0 on 2015-09-09)

I'm getting a big performance hit on front end requests (+15 seconds) when using a model to store / use data from one of my custom fieldtypes, cp requests for the same data appear unaffected.
The prepValue function:
public function prepValue($value)
{
    if( is_array($value) )
    {
        return FruitGrid_BlockModel::populateModels($value);
    }

    return $value;
}

And the model which is getting populated:
class FruitGrid_BlockModel extends BaseModel
{
    protected function defineAttributes()
    {
        return array(
            'row' => array(AttributeType::Number),
            'col' => array(AttributeType::Number),
            'sizex' => array(AttributeType::Number),
            'sizey' => array(AttributeType::Number),
            'entryid' => array(AttributeType::Number),
            'rules' => array(AttributeType::Mixed),
        );
    }

    public function getRuleClasses()
    {
        $string = '';
        if(is_array($this->rules))
        {
            foreach ($this->rules as $rule => $value)
            {
                switch ($rule)
                {
                    case 'fixedHeight':
                        $string .= ' height-'.$value;
                        break;
                    case 'desktopRuleOne':
                        $string .= ' desktop-'.$value;
                        break;
                    case 'tabletRuleOne':
                        $string .= ' tablet-'.$value;
                        break;
                    case 'mobileRuleOne':
                        $string .= ' mobile-'.$value;
                        break;
                }
            }
        }
        return trim($string);
    }

    public function getEntry()
    {
        $criteria = craft()->elements->getCriteria(ElementType::Entry);
        $criteria->id = $this->entryid;
        return $criteria->first();
    }
}

And pretty standard usage on the front end:
{% if entry.customFieldHandle|length %}

    {% for block in entry.customFieldHandle %}

        {{ block.entry.title }}
        {{ block.entry.text }}

        ...

    {% endfor %}

{% endif %}

**Tags:** plugin-development, fieldtypes, performance

---

## 1 answers

### Answer by username_1 on 2015-09-09. Score: 2 | Accepted answer

Avoid calling block.entry multiple time per block since you only need to do that database query once. Alternatively you can use function memoization to cache the entry like this:
class FruitGrid_BlockModel extends BaseModel
{
    private $_entry;

    protected function defineAttributes()
    {
        return array(
            'row' => array(AttributeType::Number),
            'col' => array(AttributeType::Number),
            'sizex' => array(AttributeType::Number),
            'sizey' => array(AttributeType::Number),
            'entryid' => array(AttributeType::Number),
            'rules' => array(AttributeType::Mixed),
        );
    }

    public function getRuleClasses()
    {
        //...
    }

    public function getEntry()
    {
        if(!$this->_entry){
            $criteria = craft()->elements->getCriteria(ElementType::Entry);
            $criteria->id = $this->entryid;
            $this->_entry = $criteria->first();
        }

        return $this->_entry;

    }
}

This will only get the entry from the database once.
Also recommend renaming the rules attribute on the model to something like blockRules.
When you loop over the rules to create the ruleClasses string you may be looping over every rule created by the AttributeType declarations in your defineAttributes method.

> **Comments:**
> **username_0**: Ah I see, removing ```{{ block.ruleClasses }}``` improved things a drop, but I was accessing ```{{ block.entry.customField }}``` loads of times, storing / caching the entry and accessing it via this var helped loads. So does it get the entry each time i hit block.entry??  
> **username_1**: ah yes, you are doing a db call every time you do `block.entry`. You could cache it in the plugin function or just assign it once per block in the template like so: {% set blockEntry = block.entry %}. This would have been causing the huge slowdown more than my answer.  
> **username_0**: Yes, this was the issue, although your suggestion certainly helped speed things up. What do you mean by cache in the function? Set a var that is checked before grabbing the entry and set only if it has not be retrieved?  
> **username_0**: Sorry Luke, just saw you answer! Exactly as expected, thanks!!!  

---

