【问题标题】:typo3 fluid f:for is extreamly slowTyp3 流体 f:for 非常慢
【发布时间】:2018-07-03 10:28:36
【问题描述】:

在我的 Typo3 扩展中,我使用 <f:for 来迭代几个项目。正好 184 项。

我由此生成了一个滑块。

问题是这个迭代非常慢。有没有办法快点。后端速度不到一秒。只有前端渲染需要很长时间。

我的完整前端代码如下所示:

<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>

【问题讨论】:

  • 您检查过缩略图的图像尺寸吗?
  • 我正在一个测试系统上运行,此时所有缩略图的大小为 1kb。
  • 加载东西需要多少时间?
  • 我删除了&lt;f:render partial="Video/ShowThumbnail" arguments="{video : video, userAuthorization : userAuthorization}"/&gt; 并直接在里面设置了这个部分的代码。所以目前我需要 12 秒……有什么进一步的提示来固定它吗?
  • 将代码从部分移动到模板对性能的影响非常非常小。要测试实际影响,您必须删除对 f:render 的调用。我怀疑你会发现这个部分是你面临的大部分沉重成本的原因——Fluid 代码本身没有一个天生就性能不佳。您没有包括部分内容,因此我无法判断该部分。

标签: html typo3 fluid


【解决方案1】:
  1. 确保您的缓存已启用 - 如果未启用,请不要根据未缓存的渲染来判断性能。
  2. 尽量避免您使用的许多条件。并且绝对不要留下像&lt;f:else&gt;&lt;/f:else&gt; 这样的空节点。
  3. 将您在最后一次迭代中所做的事情移到循环之外(从而节省另一个条件和大量节点构造)。
  4. 尽可能避免使用iteration 变量。它为每次迭代添加了额外的处理和变量分配。
  5. 我假设您使用 JS 来激活组件。所以使用 JS 设置 active CSS 类,从而避免 1) 像您一样错误地打开和关闭标签,以及 2) 避免像其他条件一样仅一次为真的另一个条件。
  6. 检查您渲染的部分。它可能无法编译。并且每次渲染它时,必须解决部分问题。注意:在这种类型的用例中,一个部分几乎总是比一个部分执行得更好。我写的一个你可以使用的工具,它也预编译你的模板,如果任何模板不兼容,它可能会失败:https://github.com/NamelessCoder/typo3-cms-fluid-precompiler
  7. 一般来说:除非你有非常好的理由,否则不要在 Fluid 中输出&lt;script&gt;。只要有可能,在外部加载脚本并存储脚本需要的任何值,例如data- 属性。更快的解析,更快的循环。
  8. 使用实际的分析工具来精确定位瓶颈。您的代码使用 ViewHelpers 并且对配置也很敏感,例如您对路径等的设置越多,在f:render 调用中需要完成的处理就越多。不要在开发环境中分析!
  9. 不要在 Docker 设置上配置文件 - 除非您运行的是 Linux。即便如此,也要保留一些结果:文件系统性能永远不会相等。

避免iteration 和您的条件,并将最后一个块移到循环之外,应该会减少 80% 的成本(不计算在您渲染的部分中发生的情况 - 这在性能上可能绝对是可怕的,我们我永远不知道,因为你没有粘贴那个)。

最后,在选择是渲染部分还是部分时,需要考虑几件事情。其中大部分完全取决于您的用例(例如:您需要如何构建模板 - 可以覆盖的部分是否比您不能覆盖的部分更有意义?)但可以说一些一般性的内容性能:

  • 当您渲染存在于同一模板中的部分时,会通过一个函数调用来进行渲染,以使用一组新的模板变量切换到该部分。
  • 但是当您渲染一个局部时,这个局部的模板文件必须首先解析,然后才能进行渲染。
  • 无法编译已解析的模板,因为必须可以在多个不同的上下文中呈现相同的已编译模板。
  • 1234563到一个普通的函数调用)。
  • 您拥有的模板路径越多,文件解析就越困难。

您始终需要为任务选择正确的工具——这是我们作为开发人员的工作之一——所以这些要点非常笼统。有些用例在部分和部分之间的性能上根本没有区别,有些用例不会因使用iteration 而受到明显影响;这一切都取决于您的设置要求和您正在渲染的数据。分析您的模板肯定有助于找到正确的解决方案,因此我强烈建议您这样做。

【讨论】:

  • 3.) 是指哪一部分。有没有办法在没有迭代的情况下做到这一点{i.isFirst}
  • 我删除了f:render 并从上面代码中的部分移动了所有代码。现在它快得多。从 30 秒减少到 12 秒 ...
  • 在我的第三点中,我的意思是您目前将所有内容都放在循环中。尽可能多地移到循环之外,这样您就不必每次迭代都对其进行评估。如果你做对了,你将不需要你当前拥有的任何条件,并且你将不再需要迭代变量。请注意,您还可以在f:for 上使用key 将键/索引分配给变量,这可以检查您是否在零索引数组的第一项上,但不允许您检查“isLast ”。 TL;DR:将事物移到循环之外,那么您根本不会遇到这个问题;)
  • 好吧,比它更多的重构。 ^^ 它不是我的代码只是想要它更快;)
  • @wirap 谢谢,很高兴你发现它有用。我添加了一个指向预编译器实用程序的链接,该实用程序具有可选的“在任何不可编译的模板上失败”开关。我更详细地解释了为什么一个部分可以比一个部分更快,以及为什么您有时需要使用部分而不是部分。
猜你喜欢
  • 2021-05-06
  • 1970-01-01
  • 2016-11-18
  • 1970-01-01
  • 2023-02-26
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多