首页 > 解决方案 > 我应该在每个 http 请求上调用 template.ParseFiles(...) 还是只从主函数调用一次?

问题描述

我正在使用使用包的 go 编程语言进行一些网络开发html/template。在代码的某个点,我需要调用该函数template.ParseFiles(...),以便我可以从这些文件创建一个模板,然后使用temp.Execute(w,data). 我想知道是否最好在每个请求上创建模板或在主中创建一次并声明一个全局变量。

现在我对我的句柄函数的每个请求都这样做,就像大多数教程一样。但是,我不知道我是否通过在每个请求上执行它而不是将它们作为全局变量来浪费资源。

这是它在每个请求上的样子

func ViewStats(w http.ResponseWriter, r *http.Request) {
    //Get stuff from db and put them in data
    //...
    //return data to user
    tmp, err := template.ParseFiles("views/guest-layout.html",
        "views/stats.html")

    if err != nil {
        fmt.Println(err)
    } else {
        tmp.Execute(w,data)
    }
}

我想知道这是否更好:

var temp1 template.Template

func main() {
    temp1, err = template.ParseFiles("file1","file2") 
    //...
}

标签: performancegogo-templates

解决方案


像往常一样:这取决于。

但首先有一些细微差别:

  1. 你永远不应该在你的main()函数中进行模板解析(或任何其他有趣的事情)。相反,您的main()函数应该调用启动程序中有趣事物链的方法(或单个方法)。

  2. Go 没有全局变量,因此首先将解析的模板存储在全局变量中实际上并不是一个选项。Go 最接近全局变量的是包变量。您可以将解析后的模板存储在包中的包变量中main,但这也是一种不好的形式,因为您的main包(除了微小的、琐碎的程序)应该只是一个入口点,否则几乎是空的。

但是现在,进入您问题的核心:

您应该按请求解析模板,还是按运行解析模板?

这取决于。

如果您有经常更改的模板(即在开发过程中,当您不断编辑 HTML 文件时),最好每个请求一次。

但这比只解析一次效率要低得多,因此在生产中,您可能希望仅在启动时解析一次模板。然后,您可以将模板存储在包变量中,或者更好的是,存储在运行时初始化的结构中。但我把它留给你。

但最好的方法实际上是在这两种方法之间进行一些折衷。最好在启动时加载模板,并偶尔重新加载它们,或者自动(例如,每 5 分钟一次),或者监视文件系统,并在模板的磁盘表示发生变化时重新加载它们。

如何做到这一点留给读者作为练习。


推荐阅读