Normally I'm not working that much with craft and twig syntax, so first of all sorry if I'm not that much into that topic (normaly html,css,js,jquery). There is one site which need so much time to load. There is much data to load but that can't be the reason that the server needs about 25s to respond. Do you have any performance tips?

Live Example: http://www.christlicher-gesundheitskongress.de/program.html

Probably this snippet is responsible for the long load time.

{% set z = 0 %}
            {% for program_block in craft.categories.group('program_block') %}
            <div class="program-block" data-index="{{z}}" id="{{z}}">
                <div class="block-header">
                    <h3>{{ program_block.title }}</h3>
                    <h5><span>{{ program_block.program_date | date ('l, d. F') }} von </span>{{ program_block.time_start | date('H:i')  }} - {{ program_block.time_end | date('H:i')  }}</h5>
                <div class="block-body double">
                    {# {% cache %} #}
                    {% for program in craft.entries.section('program_point').order('program_number') %}
                        {% if program.block.first().title == program_block.title %}
                            <div class="seminar-box">
                                {% if program.type == "seminar" %}<a href="{{ program.url }}">{% endif %}
                                <h4><span> {# {% if program.type != "seminar" %}#{% endif %} #} {{ program.program_number }}</span>{{ program.title }}</h4>
                                {% if program.short_description|length %}
                                    <p>{{ program.short_description }}</p>
                                {% endif %}
                                {% if program.type == "seminar" %}</a>{% endif %}
                                {% if program.program_referents|length %}
                                    {% set i = 1 %}
                                    {% for referent in program.program_referents %}
                                        <!-- <a href="{{ referent.url }}" class="referent-link">--> {{ referent.referent_name }}<!--</a>--> {% if i != program.program_referents|length %}// {% endif %}
                                    {% set i = i+1 %}
                                    {% endfor %}
                                {% endif %}
                        {% endif %}
                    {% endfor %}
                    {# {% endcache %} #}
                    <div class="seminar-box fill_up"></div>
                    <div class="seminar-box fill_up"></div>
                    <div class="seminar-box fill_up"></div>
                    <div class="seminar-box fill_up"></div>
                    <div class="seminar-box fill_up"></div>
                    <div class="seminar-box fill_up"></div>
                    <div class="seminar-box fill_up"></div>
            {% set z = z+1 %}
            {% endfor %}

2 Answers 2


Let me try to turn this into a more valuable StackExchange for others who will find it, since the original poster apparently got help and solved his problem without participating here. We can see so on the linked site, which is now running as expected for Craft, quite rapidly.

What I'd like to do is suggest a less awkward way to approach his task. We can do that much more nicely due to Craft's actual abilities, and then there will be no need for index counters, full table scans of data, and so forth as in the original code. The site will then also be more efficient, offering something to the original question, while also having some convenient extra features.

The data involved is naturally hierarchic - Seminar 'plenums' with sessions within them. The sessions are run by speakers, whose information pages are linked. Speakers might be in more than one session, and it's possible that sessions would also be repeated in other plenums, so both should be independent data sets. By using Matrix variables, we can make it very easy to organize plenums, and provide per-plenum information such as times.

Thus in Craft terms, we should have a Channel of plenums, a Channel of sessions, and a Channel of speakers. To give the ordering flexibility, own times etc., and ease of relations, the plenums channel should have a Matrix variable for sessions scheduling. The sessions channel can even more easily use an Entries variable to hold details of the speakers for each session. Otherwise, the channels will contain simple Craft types for each of their data fields.

Such a design will replace the originally posted code with something like the following, which is much more simple and direct:

{% foreach plenum in plenums %}
  ...print plenum fields information
  {% foreach session in plenum.sessions %}
    ...print general session fields information
    ...print plenum-session-specific information, such as location and times
    <a href="{{speaker.link}}">{{ speaker.speaker_name }}</a> 
     {% if not loop.last %}// {% endif %}
  {% endfor %}
{% endfor %}

Note that highly efficient database queries will eliminate table scans and index variables, with the Craft-Twig loop variable supporting clean formatting of single or multiple speakers.

The Craft control panel will let us just pull around sessions within plenums to reorder them, while entering any changed times or places very easily. Simple variations on this design would allow us as easily to change speakers when necessary for instances of a session, for example.

Since the sessions are only related to plenums, they can appear in multiple plenums just by adding them to the Matrix variable for each. Not much extra work would allow the Matrix variables to hold or over-ride date-times, locations, or even alternate speakers, etc., adding flexibility.

The original poster's site presentation design was appreciated as quite nice for its type, and this picture should show that Craft makes an appropriate data and code design for it just as nice and clean.

  • 1
    Completely replaced this answer, as explained. The original troubleshooting tips, besides talking to the hosting provider, are below, attached to RitterKnight's answer which they reference. One item to consider: there were no Matrix elements in the original db/code, as far as I could see. Sep 7, 2015 at 23:46

You have a lot of matrix blocks; I'm guessing that's why your output is slow. It looks like your initial query doesn't depend on any other input, so you could probably cache the whole thing. I would put cache tags before and after your whole snippet, before the first for loop near the top.

Looks like you commented out your cache tags, probably because they won't work where you have them. Cache tags can't go inside a for loop.

The way Craft's caching tag works is it takes the output of whatever is between the cache tags and sends it to database. The next time Craft fetches your template, it looks to see if that output is already in the cache; If it is, it reaches for the cache.

  • Actually, I like what you suggest here. At the least, putting the cache tags around this entire code block will allow to see if it is making things slow. The second browser refresh from the site afterwards would be fast in that case. I don't seem to see why the code itself should be slow, even though there are some questionable loops of full data, selected by string matches instead of proper keys, but that should be investigated after proving the slowness originates here. I am also thinking of server memory perhaps, but actually this is so far a mysterious case, and no one communicating yet.. Sep 2, 2015 at 9:15
  • And here's one more tip to the original poster, for understanding such problems. Read Brad Bell's answer here, and use devMode set true in general.php with the browser console as suggested to see your SQL queries and times directly. Brad is one of the top CraftCMS developers, and a very excellent resource at all times. craftcms.stackexchange.com/questions/6645/… Sep 2, 2015 at 9:29
  • Brad is a founder of Craft, of course, besides his very evident expertise as care -- just couldn't get words together yesterday to say all ;) Sep 3, 2015 at 22:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.