博客園博客程序中.aspx和.ascx文件總共加起來有3000多個(博客模板中有大量的.ascx文件)。如果使用動態(tài)編譯,每次只要更新bin文件夾中的任何一個dll文件,動態(tài)編譯至少需要5分鐘(訪問量越高,所需的編譯時間越長),而在動態(tài)編譯期間網(wǎng)站訪問速度極慢,幾乎就是無法正常訪問。這樣,每次更新程序成為了一種痛苦,只能安排在深夜或一大早。
面對這樣的情況,只能選擇預(yù)編譯。
預(yù)編譯的原理是什么?
請閱讀Artech寫的深入剖析ASP.NET的編譯原理之二:預(yù)編譯(Precompilation)。
如何進(jìn)行預(yù)編譯?
用aspnet_compiler命令,命令示例:
aspnet_compiler -v \ -p G:\SourceWebSite G:\TargetWebsite -fixednames
參數(shù)說明:
-v \ 要編譯的虛擬路徑,這里表示根路徑。
-p G:\SourceWebSite 要編譯的源Web項目所在文件夾。
G:\TargetWebsite 編譯目標(biāo)文件夾。
-fixednames 每個.aspx與.ascx文件都編譯生成單獨(dú)的dll文件,并使用固定文件名。
編譯情況分析
1. 源文件夾中的所有.aspx, .ascx及App_Code中的.cs文件都會被編譯。
2. 編譯中遇到任何一個錯誤,會立即停止編譯,并清空目標(biāo)文件夾中已生成的文件;解決了引起編譯錯誤的問題后,只能從頭重新進(jìn)行編譯。出現(xiàn)編譯警告,只提示,不影響正常編譯。
3. 編譯完成后,aspnet_compiler會將.aspx, .ascx, .cs之外的所有文件原封不動地復(fù)制至目標(biāo)文件。(如果編譯只是為了更新網(wǎng)站程序,這個操作顯得多余。aspnet_compiler沒有提供取消這個操作的參數(shù))
4. 3000多個.aspx,.ascx文件,使用-fixednames編譯,耗時30分鐘左右;不使用-fixednames編譯,只要6分鐘。-fixednames編譯本來是為了更新方便(每次編譯生成的文件名相同,更新生產(chǎn)環(huán)境中的dll時直接覆蓋就行),沒想到這么慢。不用-fixednames編譯,每次更新時,要先刪除原來的文件,再復(fù)制。在生產(chǎn)環(huán)境中,這個操作會短暫影響網(wǎng)站的正常訪問。
為什么不用“可更新的預(yù)編譯(Updatable Pre-compilation)”
Updatable Pre-compilation只編譯App_Code中的文件以及.aspx,.ascx的code behind文件,我們的Web項目類型是Web Application,code behind已經(jīng)編譯了,App_Code中也沒有代碼,相當(dāng)于已經(jīng)處于這種編譯狀態(tài),但還是需要至少5分鐘的動態(tài)編譯時間。
這種編譯方式只是減少了編譯.cs文件的工作量,但每個.aspx,.ascx文件還是要動態(tài)編譯,不能避免動態(tài)編譯的性能問題。
Updatable Pre-compilation適用于App_Code中有大量代碼(更新其中的文件會引起該文件夾中的所有文件重新編譯),又不想用Non-updatable Pre-compilation的情況。
結(jié)論
面對這么多的.aspx,.ascx文件,只能選擇預(yù)編譯。-fixednames編譯實(shí)在太慢,只能放棄。更新時只能先刪除,再更新。雖然有些不足,但總比動態(tài)編譯好。
當(dāng)然,真正的解決之道是干掉模板中的那些.ascx文件。ASP.NET MVC會是救星嗎?