简体   繁体   中英

typo3 fluid f:for is extreamly slow

In my Typo3 extension I us a <f:for to iterate trough a couple of items. Exactly 184 Items.

I generate a slider out of this.

Problem is that this iteration is extremly slow. Is there a way to fast it up. Backend is fast less than a sec. Only the frontend rendering needs to long time.

My full frontend Code looks like this:

<f:if condition="{videos -> f:count()} > 4">
    <f:then>
        <f:for each="{videos}" as="video" iteration="i">
            <f:if condition="{i.isFirst}">
                <f:then>
                    <div class="item active">
                </f:then>
                <f:else>
                    <div class="item">
                </f:else>
            </f:if>
            <div class="col-lg-3 thumbnailParent">
                <f:link.action controller="FrontendVideo" action="show" arguments="{video : video}">
                    <f:render partial="Video/ShowThumbnail" arguments="{video : video, userAuthorization : userAuthorization}"/>
                </f:link.action>
            </div>
            <!-- adding slider-class to one of all slides. condition: slide must have more than 4 videos for slide-effect -->
            <f:if condition="{i.isLast}">
                <f:then>
                    <script type="text/javascript">
                        addClassForSliding('{myCarouselID}');
                        function addClassForSliding(myCarouselID) {
                            $("#myCarousel"+myCarouselID).addClass("isCarousel");
                            if(!$("div.videoSlide").find("div").hasClass("thisIsTheOnlySliderWhichSlides")){
                                $("#myCarousel"+myCarouselID).addClass("thisIsTheOnlySliderWhichSlides");
                            }
                        }
                    </script>
                </f:then>
                <f:else></f:else>
            </f:if>
            </div>
        </f:for>
    </f:then>
    <f:else>
        <f:for each="{videos}" as="video" iteration="i">
            <div class="item active">
                <div class="col-lg-3">
                    <f:link.action controller="FrontendVideo" action="show" arguments="{video : video}">
                        <f:render partial="Video/ShowThumbnail" arguments="{video : video, userAuthorization : userAuthorization}"/>
                    </f:link.action>
                </div>
            </div>
        </f:for>
    </f:else>
</f:if>
  1. Make sure your caches are enabled - if they are not, don't judge the performance based on uncached renderings.
  2. Try to avoid the many conditions you use. And definitely don't leave the empty nodes like <f:else></f:else> .
  3. Move the stuff you do in the last iteration, outside of the loop (thus saving another condition and a lot of node construction).
  4. Avoid the iteration variable whenever possible. It adds additional processing and variable assignment to each iteration.
  5. I assume you use JS to activate the component. So use JS to set the active CSS class, thus avoiding 1) opening and closing tags incorrectly like you do, and 2) avoid another condition that only is true a single time, like the other one.
  6. Check your partial that you render. It may not be compilable. And every time you render it, the partial must be resolved. Note: in this type of use cases, a section almost always performs better than a partial. One tool I wrote which you can use, which also pre-compiles your templates and can fail if any template is not compatible: https://github.com/NamelessCoder/typo3-cms-fluid-precompiler
  7. Generally speaking: don't output <script> in Fluid unless you have an extremely good reason. Whenever possible, load scripts externally and store whichever values the script needs, in for example data- properties. Faster parsing, faster loop.
  8. Use actual profiling tools to precisely locate the bottleneck. Your code uses ViewHelpers and is also sensitive to configuration, eg the more setup you have for paths etc. the more processing needs to be done in f:render calls. Do not profile in development context!
  9. Do not profile on a Docker setup - unless you're running Linux. And even then, take results with some reservations: file system performance will never be equal.

Avoiding iteration and your conditions, and moving the last block outside the loop, should remove a good 80% of the cost (not counting what happens in your partial you render - it could be absolutely horrible in performance and we'd never know since you didn't paste that one).

Finally, when selecting whether to render a partial or a section there are a couple of things to consider. Most of these completely depend on your use case (as in: how do you need your templates to be structured - does it make more sense with a partial you can overlay than a section you cannot?) but it is possible to say something general about performance:

  • When you render a section, which exists in the same template, the rendering takes place with a single function call to switch to that section with a new set of template variables.
  • But when you render a partial, the template file for this partial first has to be resolved before rendering can take place.
  • The resolved template is not possible to compile since the same compiled template must be possible to render in multiple different contexts.
  • Thus, resolving of a partial template may only be cached once per context, which means that if this same template is rendered in multiple contexts multiple times on a page, performance may suffer a lot compared to using a section (which gets compiled to a plain function call).
  • The more template paths you have, the tougher this is on file resolving.

You always need to choose the right tool for the task - that's one of the things our job is as developers - so these points are pretty generic. Some uses cases simply have no difference in performance between sections and partials, some don't suffer noticeably from using iteration ; it all depends on your setup requirements and the data you are rendering. Profiling your templates certainly helps finding the right solution so I highly recommend doing that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM