You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Scripts.Render添加defer属性、为Styles.Render配置preload属性

脚本添加defer属性的正确实现

你之前使用的Scripts.RenderFormat仅在<compilation debug="false">(发布模式、Bundle开启打包)时生效,调试模式下Bundle会拆分输出原始文件,模板不会生效,以下是兼容所有模式的方案:

方案1:全局所有脚本自动加defer

在App_Start/BundleConfig.cs中自定义Bundle类型:

public class DeferScriptBundle : ScriptBundle
{
    public DeferScriptBundle(string virtualPath) : base(virtualPath) { }
    public DeferScriptBundle(string virtualPath, string cdnPath) : base(virtualPath, cdnPath) { }

    public override IHtmlString Render(string[] paths)
    {
        return new HtmlString(base.Render(paths).ToHtmlString().Replace(">", " defer>"));
    }
}

注册Bundle时替换原有ScriptBundle:

bundles.Add(new DeferScriptBundle("~/bundles/jquery").Include("~/Scripts/jquery-{version}.js"));

视图中直接调用即可自动带defer属性:

@Scripts.Render("~/bundles/jquery")

方案2:单个脚本按需加defer

不需要修改全局配置,直接在视图中写:

@{
    var scriptBundle = BundleTable.Bundles.GetBundleFor("~/bundles/jquery");
    var context = new HttpContextWrapper(HttpContext.Current);
    foreach (var file in scriptBundle.EnumerateFiles(context, false))
    {
        <script src="@Url.Content(file.IncludedVirtualPath)" defer></script>
    }
}

样式配置preload的正确实现

preload需要同时输出预加载标签和样式生效标签,还要兼容禁用JS的场景:

方案1:全局所有样式自动加preload

在App_Start/BundleConfig.cs中自定义Bundle类型:

public class PreloadStyleBundle : StyleBundle
{
    public PreloadStyleBundle(string virtualPath) : base(virtualPath) { }
    public PreloadStyleBundle(string virtualPath, string cdnPath) : base(virtualPath, cdnPath) { }

    public override IHtmlString Render(string[] paths)
    {
        var originalStyle = base.Render(paths).ToHtmlString();
        var preloadStyle = originalStyle.Replace("rel=\"stylesheet\"", "rel=\"preload\" as=\"style\" onload=\"this.rel='stylesheet'\"");
        var noscriptFallback = $"<noscript>{originalStyle}</noscript>";
        return new HtmlString(preloadStyle + Environment.NewLine + noscriptFallback);
    }
}

注册Bundle时替换原有StyleBundle:

bundles.Add(new PreloadStyleBundle("~/Content/css").Include("~/Content/site.css"));

视图中直接调用即可自动生成preload配置:

@Styles.Render("~/Content/css")

方案2:单个样式按需加preload

直接在视图中写:

@{
    var styleBundle = BundleTable.Bundles.GetBundleFor("~/Content/css");
    var context = new HttpContextWrapper(HttpContext.Current);
    foreach (var file in styleBundle.EnumerateFiles(context, false))
    {
        var href = Url.Content(file.IncludedVirtualPath);
        <link rel="preload" as="style" href="@href" onload="this.rel='stylesheet'">
        <noscript><link rel="stylesheet" href="@href"></noscript>
    }
}

内容的提问来源于stack exchange,提问作者Prem Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 01:36:01