網頁

2013年12月1日 星期日

Partial View 與放在 App_Code 目錄裡的 Razor@helper

對於最近遇到的情況做了一些觀察與思考,因為之前沒有這麼作過與想過,所以看到有人這麼做的時候,當下的衝擊與震驚是相當大,然後周遭的人都被我這問題搞得有點煩,所以這幾天一直反覆思考著,因為對於比較深入的內容無法做仔細的研究與探討,所以只有將看到的相關內容與觀察的結果以文字方式做個紀錄。

 


看到有人把一堆原本應該是放在 Partial View 的 Html 與 JS 內容改用 Razor@helper 的方式建立然後放到 App_Code 目錄下,這麼做的人一直強調說因為在 App_Code 會編譯在 DLL 之中,所以會執行比較快。

這樣說是有問題的,不論是放在 App_Code 的程式檔案或是 Views 目錄下的 View 檔案都是會經過編譯的,也都會在 DLL  裡,有比較快嗎?其實都差不多,要快的話,改用 Html.RenderPartial 會快一些,但影響是很微小的。       

另外一點 *.cshtml 放在 App_Code 目錄下,而並非在 ~/Views 目錄裡,所以一些方法(例如 Url Helper)將無法使用,必須要用另外的方式做解決(應該說編譯後的類別是繼承於不同的父類別,所以就有這樣的差異)。      

還有一點就是不管是一般的 View 檔案還是在 App_Code 目錄裡的 Razor@helper,如果在裡頭寫太多程式邏輯,然後沒有將專案的 MvcBuildViews 設定為 true (預設為 false),那麼將無法在設計期、編譯期發現到錯誤,需要在執行之後才會發現到錯誤。       

也許有人會覺得將原本 PartialView 的內容改用 Razor@helper 的方式在編寫 View 的時候會比較快,但如果因為這種快而犧牲維護性以及效能就有可能因小失大。我會建議用 Razor@helper 是需要對顯示的內容做動態調整的時候,例如頁面上的某區塊因為條件值的不同而有不一樣的呈現時,這時用 Razor@helper 就很方便,但如果是一般單純的靜態頁面或是需要做 Model 資料 Binding 的內容,這時後會建議使用 Partial View。

 

對 Partial View 以及 Razor@helper 做了一個小測試,結果不出我所料,使用 Partial View 所 render 的速度跟使用 Razor@helper 的結果差不多,如果真的要說哪個比較快的話,Razor@helper 的速度比較快一點,View 也是會做編譯的,而 App_Code 裡的 Razor@helper 會編譯為靜態方法,輸出為 HelperResult 類別的結果,是在一個繼承於 System.Web.WebPages.HelperPage 的類別中,類別的名稱會使用 Razor@helper 所放置的 cshtml 檔案名稱。

而在 Views 目錄裡的 View 與 Partial View 檔案則是會一個 cshtml 建立一個 WebViewPage<T> 的類別,WebViewPage 類別裡有 AjaxHelper, HtmlHelper, UrlHelper 的屬性,可以處理我們編輯 View 所要使用到的操作,而 Razor@helper 則沒有,因為並非是 WebViewPage 的類別,所以當要使用 HtmlHelper 就要另外加入 using 使用,而 UrlHelper 就別想要在 Razoe@helper 裡去使用,但可以在後端程式裡建立靜態方法做處理,不過因為是需要另外動手去做,所以就不是那麼方便。

雖然前面有說兩種方式的 Render 速度上是差不多的,不過 Razor@Helper 在處理上會比較快一些,但是受限於許多的限制,所以大多數有關介紹 Razor@helper 的文章都是用 Html Element 的變化來做說明,很少人會將 Partial View 的內容放置在 App_Code 裡的 Razor@helper。

放在 App_Code 裡的 Razor@helper 是因為要作為全域使用,這樣在網站裡的所有 View 都可以取用,適合重複使用性高且範圍小的內容,反之如果將 Partial View 的內容用在 Razor@Helper 裡面,雖然可以用,也可以正常執行,但是容易造成有許多方法無法使用的情況。

另外 View 的內容有許多的內容被放在 Razor@Helper 裡,那麼將會造成維護上的困難,尤其是當這些切切成許多塊的部份內容包含有 Javascript 的時候,然後這許多的 Razor@Helper 又都放在同一個 *.cshtml 檔案裡,怎麼維護與管理就會是個問題。

在開發上有很多的方式在執行的結果是沒有問題的,但這不表示這麼做是合適的,要仔細考慮往後的維護性,甚至是當這個專案從你手上交給其他人做維護時,要考慮後續接手維護的人是否能夠明白與了解你的作法。

很多作法在你發現可以用一些取巧的方式來完成而沾沾自喜的時候,你要再三思考這樣的作法為何別人不這麼用,為何一些大型開放原始碼的專案或是其他專案裡也不這麼用的原因。

 

這一整篇文章看來像是嘮叨碎念,但或許你也可以思考一下,這兩種作法的差別,以及什麼時候與什麼樣的情況下適合使用那一種方法。

 

以上

2 則留言:

  1. Razor Views Pre-Compile 會不會比較快呢?

    回覆刪除
    回覆
    1. 我想速度並不是我考慮的問題,而是在於是否合適,例如驗證碼,如果在一個網站裡會有許多地方要用到,那我就會切出來做成一個 PartialView 而不是放在 App_Code 下的 Razor@Helper.

      刪除