我可能迟到了 2016 年的派对。Play 2 已经发布,JDK(更不用说硬件)大幅改进。我没有使用 Play 或 Spring Boot,因为我的平台不需要它们 - 只是从模板生成纯运行时文本/HTML。
首先,当谈到 Groovy 模板时,不止一个。我将原始的 Groovy SimpleTemplateEngine 用于从电子邮件到丰富网页的任何内容,无论现在大多数人是否喜欢具有非 HTML 构建器语法的“高级”MarkupTemplateEngine。我没有走那条路,因为 IDE(例如 UntelliJ)支持使用 JavaScript 的 JSPish HTML 文件 - 捕获未闭合的标签、大括号等。此外,您如何将 JavaScript 包含到基于大括号的“构建器”样式模板中?
无论您选择哪个,SimpleTemplateEngine 和 MarkupTemplateEngine 都会静态编译它们的模板,尽管 Groovy 文档只为后者提及它。为什么它不会为前者生成一个类?我没有将它们相互比较,但我希望 SimpleTemplateEngine 更快,因为它......嗯,更简单 - 不会将任何语法转换为带有 ifs 和循环的字符串连接。
而且确实非常快。我担心循环调用它。没有任何区别。没有开销,因为模板只编译一次。
我使用多个小模板负责生成单独的表单控件标记(HTML + JS)来生成复合表单,包含在更高级别的容器中,包含在另一个容器中,依此类推,直到形成整个页面。正如您已经猜到的那样,分解您的视图使其模块化、封装和“面向对象”——由许多相互构建的独立 MVC 组件组成。有点像老式的自定义 JSP 标记,仅在运行时评估并与 Spring Boot 等技术兼容,如果您无法抗拒诸如此类的时髦恢复增强功能的话。
一个包含 100 个字段的测试表单(所有复杂的“智能”控件都带有封装的状态管理和行为)第一次在 150 毫秒内呈现,然后在 10-14 毫秒内呈现。在我的内存不足的 4y.o 上的 IDE 调试器中。笔记本。我还验证了它是线程安全的,因为 Groovy 从未明确提及它。如果它像其他任何东西一样被编译成一个无状态的 Groovy 类,为什么不呢?调用 createTemplate() 一次,将模板存储在某处,然后在您的 servlet 或另一个并发上下文中使用它(调用 Template.make())。显然,在实际应用程序中我永远不会有 100 个字段的表单。任何这样做的人都需要重新考虑他/她的用户体验。
性能相当不错。我什至愿意接受一秒钟来呈现一个 100 字段的页面。想一想,您不需要 Web 应用程序中的终极纳米贸易或核导弹跟踪性能。如果这样做,请选择 Jamon:http://www.jamon.org/Overview.html,它会生成一个 Java 类,您通常会编写以连接字符串。我没有测试它,因为我不喜欢额外的编译步骤(由 Maven 自动执行,但仍然如此)。编译的 Groovy 字节码对我来说已经足够好了 - 与编译的、是的、强类型的 Java 相比。除非您正在做一些复杂的事情,否则差异将是微不足道的,您不应该在模板中(见下文)。按照这个线程中的建议,使用类型化的 Groovy 变量与 def,在 100 个模板的运行中只为我节省了几毫秒。
无论如何,模板不应该有太多的过程逻辑(内部变量、ifs 和循环)——这是控制器的责任,而不是视图的责任。也就是说,ifs 和循环对于模板引擎来说是必须的。如果他/她可以简单地调用 String.replace(),为什么还要使用 Handlebars/Mustache?
其余的模板引擎也无关紧要。没有任何字符串连接(例如 Velocity 或 Freemarker)或解释型的基于 JS 的技术(例如 Jade)会在性能方面击败最直接的 Jamon 方法。作为一名 Java 程序员,您想使用自己喜欢的语言/语法:直接(Jamon)或 90% 接近 Java,Groovy 是(作为以脚本为中心的简洁解释型 Java)。我不会评论 Scala - 偏好问题。除了所谓的“简洁”语法(与 Java 8+ 的相关性越来越低)之外,它是有代价的。并且只对复杂的循环很重要。你不想在一个模板中编写整个应用程序,就像我已经说过的那样。几个循环和最多十个 if 语句。
而且,就像大家提到的那样,直观的语法和易用性是关键。它们大大减少了错误的数量。一个好的(额外的)服务器要花费 1000 美元,而开发人员的工资——用于修复因边际性能优化的复杂性而产生的所有错误,要高出 100 倍。