我想确切地找出两者之间的区别:
- “不要合并”和“不要合并。为每个页面和控件创建一个单独的程序集。”
- “将所有输出合并到一个程序集”和“将所有页面和控制输出合并到一个程序集”
- 同样,这些听起来像是同一件事(当您没有
App_Code
文件夹时)。
而且我想找出为什么“允许预编译的站点可更新”在检查时似乎没有做任何事情(即我认为它会将页面预编译为他们自己的程序集/程序集,同时还发出原始的可编辑文件.*.aspx
.ascx
.master
因此,今天我坐下来创建了一个电子表格,并使用 ASP.NET WebForms *.csproj 应用程序运行了每个不同的发布配置文件预编译设置 - 我还想看看最慢与最快的输出是什么。
背景:
- 我的 ASP.NET 项目面向 .NET Framework 4.7.2
- 它不是一个“网站项目”。
- 原始 C#
*.cs
文件不会发布到生产网络服务器。
- 它是一个使用
*.aspx
、*.ascx
、*.master
和*.ashx
的WebForms 项目Global.asax
。它不是使用 Razor*.cshtml
或 WebForms *.aspx
视图引擎的 MVC 项目)。
- 它不使用
App_Code
文件夹(因此“视为库组件”选项无效)。
发现:
重要说明:
- 这些发现仅适用于使用“传统”ASP.NET Web 窗体 Web 应用程序项目的情况。这些不适用于 ASP.NET 网站项目(没有
*.csproj
文件)、ASP.NET MVC(非核心)项目或 ASP.NET Core 项目。
- 我使用术语“页面文件”作为
*.aspx
、*.ascx
、*.master
、*.asmx
和*.ashx
files 的简写,但不是 Global.asax
.
- 我使用术语“正常构建”来指代在 Visual Studio 中执行“构建 > 重建项目”,您可以在其中看到
%projectdir%\bin
目录中的输出。这与执行 Publish Build 相比(它将首先执行正常构建,然后将输出复制到另一个目录以运行 Publish MSBuild 步骤)
以下是我对每个选项的结果的发现:
“发布期间预编译”(在发布设置窗口中)
- 如果您没有
App_Code
文件夹并且想要发布可编辑的*.aspx
/ *.ascx
/`*.master 文件,则没有性能理由来选中此框。
- 这是因为当检查此功能时,“允许预编译的站点可更新”是未选中的,则只会预先编译您的
Global.asax
文件(而不是您的文件Global.asax.cs
)。
- 即您的
*.aspx
,*.ascx
和*.master
文件*.ashx
不会被预编译为程序集,它们仍然需要在 Web 服务器上按需编译。
- 但它仍会预编译它们以检查
<% @
您的*.aspx
、*.ascx
、和文件*.master
中的编译器错误和断行。*.asax
*.ashx
“允许预编译站点可更新”
- 当这个检查你的
*.aspx
,*.ascx
和*.master
文件*.ashx
不会被预编译成程序集,它们仍然需要在 web 服务器上按需编译。
- 我最初认为它将这些文件预编译为程序集(DLL)并另外发布原始
*.aspx
文件以在服务器上进行编辑,并且只有在它们被更改时才重新编译它们 - 但我错了。
发出调试信息
- 这
*.pdb
将为预编译过程生成的每个新程序集生成文件。当您的应用程序正常构建时,它不会影响任何*.pdb
已经存在的文件。
- 我认为这应该始终启用 - PDB 文件对于快速调查运行时问题至关重要,它们不会对最终发布大小增加太多。
不要合并
不要合并。为每个页面和控件创建一个单独的程序集。
- 这与上面相同,除了每个程序集不是以 10 个页面文件(或类)为一组,而是每个程序集 1个页面文件。
- 当未选中“允许预编译的站点可更新”时,这也是最慢的发布版本之一。
- 这种方法的唯一优点是如果您想单独替换
*.dll
服务器上预编译的每个页面 - 但我认为这不是一个好主意,因为它经常会中断 - 最好一次替换所有文件。仅当您使用 56K 连接并且一次只能上传少于 100KB 时才这样做——这很愚蠢。
将所有输出合并到一个程序集中
- 确实将所有页面文件 和
Global.asax
( App_global.asax.dll
) 编译/合并为单个 DLL 文件。
视为库组件
- 此选项对我的项目的影响为零,无论是选中还是未选中(因为我的项目没有
App_Code
文件夹)。
将每个单独的文件夹输出合并到自己的程序集中
- 这会为项目中包含页面文件的每个文件系统目录生成中间 DLL ,然后将它们合并到每个文件夹的单个 DLL 中。
- 此选项导致发布构建时间第二长。
- 我想不出您今天需要使用此功能的充分理由 - 除非您的项目中有数千个页面文件分布在数十个文件夹中并且想要进行手动增量更新。(即这不是您在 CI/CD 过程中使用的选项)。
将所有页面和控制输出合并到一个程序集中
- 如果你有一个
App_Code
文件夹:
- 然后
App_Code
(和其他“特殊文件夹”,如App_GlobalResources
, App_WebReferences
)的内容将从您的页面文件程序集预编译到这个单独的程序集。这将不包括Global.asax
(编译为App_global.asax.dll
)。
- 如果您没有
App_Code
文件夹,则此选项会产生与“将所有输出合并到单个程序集”非常相似的输出,但最终输出将预编译Global.asax
为其自己的程序集 ( App_global.asax.dll
)。
- 此选项导致所有选项的发布构建时间最长 - 在我的情况下,实际收益为零。
- 因此,如果您没有
App_Code
文件夹,则没有理由选择此选项。
重述:
当检查“允许预编译的站点可以更新”并检查“不要合并”时:
*.aspx
*.ascx
*.ashx
*.asmx
*.master
* Compiled only for error-checking.
* Not compiled to an assembly DLL in the `bin\` folder.
Global.asax
* Compiled to `App_global.asax.dll`
App_Code
* Compiled to `App_Code.dll`
当未选中“允许预编译站点可更新”并选中“不合并”时:
*.aspx
*.ascx
*.ashx
*.asmx
*.master
* Compiled to `App_Web_abcdefghij.dll` in groups of 10-per-DLL
Global.asax
* Compiled to `App_global.asax.dll`
App_Code
* Compiled to `App_Code.dll`
当未选中“允许预编译站点可更新”并且选中“将每个单独的文件夹输出合并到其自己的程序集”时:
*.aspx
*.ascx
*.ashx
*.asmx
*.master
* Each file compiled to its own `App_Web_OriginalFileName.abcdefghij.dll` file.
Global.asax
* Compiled to `App_global.asax.dll`
App_Code
* Compiled to `App_Code.dll`
当未选中“允许预编译站点可更新”并且选中“将所有输出合并到单个程序集(名为 'Everything')”时:
*.aspx
*.ascx
*.ashx
*.asmx
*.master
* Compiled and merged into the single Everything.dll
Global.asax
* Compiled and merged into the single Everything.dll
App_Code
* Compiled and merged into the single Everything.dll
当未选中“允许预编译站点可更新”并且选中“将每个单独的文件夹输出合并到其自己的程序集”时:
*.aspx
*.ascx
*.ashx
*.asmx
*.master
* Compiled into an assembly for each folder.
Global.asax
* Compiled to `App_global.asax.dll` (separate from the assembly for the *.aspx files in the root directory)
App_Code
* Compiled and merged into `App_Code.dll`
选中“将所有页面和控件输出合并到单个程序集(名为 'PagesAndControls')”时:
*.aspx
*.ascx
*.ashx
*.asmx
*.master
* Compiled into PagesAndControls.dll
Global.asax
* Compiled to `App_global.asax.dll` (separate from PagesAndControls.dll)
App_Code
* Compiled and merged into `App_Code.dll`
结论:
如果您在部署后不需要编辑*.aspx
/ *.ascx
,/*.master
文件,并且您没有App_Code
文件夹,请选择以下设置以获得最佳效果:
[ ] Allow precompiled site to be updatable
[X] Emit debug information
[X] Merge all outputs to a single assembly
[ ] Treat as library component
方法:
- 所有构建都使用 Release。
- 使用了“文件夹”发布配置文件。
- 目标是同一磁盘卷(PCI-Express Optane 驱动器)上的文件夹。
- 每次运行后都会清除该文件夹。
- 每次测试运行之间的唯一变化是更改
git
在每次构建和发布之前确认源文件和项目文件的零更改。
- 我运行了一个 shell 脚本,它在每次运行之间完全清除
bin
和obj
目录,因此 Web 应用程序项目在运行之间完全重建,而不仅仅是 Publish)。
- 我使用了一个秒表程序,它记录了我单击“发布”按钮的确切时间,但是当我看到“发布”操作完成时,它被键盘按下手动停止。
结果:
(我的电子表格的屏幕截图)