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.

      刪除

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。