我应该在每个http请求上调用template.ParseFiles(...)还是仅从主函数调用一次?

时间:2019-04-02 01:39:48

标签: performance go go-templates

我正在使用包html/template使用go编程语言进行一些Web开发。在代码的某个点上,我需要调用函数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") 
    //...
}

1 个答案:

答案 0 :(得分:1)

与往常一样:这取决于。

但首先要有一些细微差别:

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

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

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

您应该按请求还是按运行来分析模板?

这取决于情况。

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

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

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

如何做这件事留给读者练习。