如何在 FreeMarker 模板中调试低效的 JCR 查询?

Posted

技术标签:

【中文标题】如何在 FreeMarker 模板中调试低效的 JCR 查询?【英文标题】:How do I debug an inefficient JCR query in FreeMarker template? 【发布时间】:2020-04-27 07:42:35 【问题描述】:

我有一个 Magnolia FreeMarker 模板,它重复执行(每页加载 1,400 多次)一个简单但不必要的按 ID JCR 查询选择。例如:

select BUNDLE_DATA FROM BUNDLE WHERE NODE_ID = ? 

由于 FreeMarker 代码的复杂性,我无法判断是哪一行导致了重复查询。

如何在 Magnolia 中调试 JCR 查询,以便确定导致重复查询的 FreeMarker 代码?

【问题讨论】:

【参考方案1】:

进入数据库级别太深了。上面的查询是 JCR 请求获取节点的所有属性 w/ ID 等于NODE_ID,但正如您所说,它在告诉您在哪里/什么操作导致它方面毫无意义。

可能来自:

ctx.getJCRSession('some_workspace').getNode('some_path')

到:

node.getNode('some_subpath')

到:

searchfn.searchPages('...')

甚至:

cmsfn.children(node)

可能还有更多。

更复杂的是,只有当本地(内存中)jcr 缓存不包含您的模板请求的项目时,您才会在 DB 上看到查询,因此您甚至不会在 DB 中捕获所有内容请求水平可靠。

有一点是肯定的,请求 1k+ 个节点进行单个模板渲染在大多数情况下表明您做错了(除非您确实想要渲染某种类型的摘要或概览超过数千个节点)。

最简单的方法是先停止思考模板中的逻辑。如果它包含多个组件,则尝试将其固定到给定组件以限制搜索空间,例如通过逐个删除组件并观察更改。

如果归结为正在执行一些 JCR 查询,您可以直接在以下位置配置调试级别日志记录:

info.magnolia.templating.functions.SearchTemplatingFunctions

这是假设您使用searchfn 从模板中进行搜索。对于其他用例,调试会有点困难,因为普通的 JCR Node API 也用于获取所有其他内容(例如与配置相关的内容),而不仅仅是在页面上呈现的内容。

可能的情况是它是模板中的单个命令或循环导致它,因此模板不同部分的定时执行也可以为您提供线索并帮助缩小问题范围。如果您共享模板本身,我们可能(但不能保证)在其中发现一些内容并为您提供更准确的指标。

【讨论】:

以上是关于如何在 FreeMarker 模板中调试低效的 JCR 查询?的主要内容,如果未能解决你的问题,请参考以下文章

Freemarker 模板错误

如何在 freemarker 模板中显示验证错误

如何在freemarker模板中按索引获取列表项?

如何在 Maven 中使用模板代码生成器(例如 freemarker)?

在 Freemarker 模板中,如何获取数据模型类的名称?

spring 如何在freemarker模板中获取请求上下文