你能预缓存ASP.NET Bundles吗?

15
每次我部署一个MVC web应用程序,我的服务器都必须重新缓存所有js和css捆绑包。
因此,在部署后,第一次查看需要几秒钟才能呈现。
有什么方法可以预缓存捆绑包吗?毕竟,这些文件在编译时是静态的。

4
如果我理解打包是如何工作的,它会在应用程序域中缓存到内存中。在编译时,显然没有应用程序域,因此没有地方可以将文件缓存到。你确定打包是导致速度慢的原因吗?我无法想象读取一堆静态文件并在运行时将它们转储到内存中需要超过几分之一秒钟的时间。但一般情况下重新启动应用程序而不进行打包确实需要几秒钟的时间。 - Joe Enos
@JoeEnos 是的,这正是我所想并在网上找到的。我只是想听听第二个意见。谢谢。 - Mark Rucker
不同的解决方案,我想尽可能地摆脱所有预热成本,所以我让我的app_start在后台向我的“RouteTable”中的每个路由发送网络请求。 - Chris Marisic
1个回答

12

解决方案

为了解决问题,我们用能够持久化缓存的方式替代了默认内存缓存。

我们通过继承ScriptBundle并重写CacheLookup()UpdateCache()方法来实现这一点。

/// <summary>
/// override cache functionality in ScriptBundle to use 
/// persistent cache instead of HttpContext.Current.Cache
/// </summary>
public class ScriptBundleUsingPersistentCaching : ScriptBundle
{
    public ScriptBundleUsingPersistentCaching(string virtualPath)
        : base(virtualPath)
    { }

    public ScriptBundleUsingPersistentCaching(string virtualPath, string cdnPath)
        : base(virtualPath, cdnPath)
    { }

    public override BundleResponse CacheLookup(BundleContext context)
    {
        //custom cache read
    }

    public override void UpdateCache(BundleContext context, BundleResponse response)
    {
        //custom cache save
    }
}

问题

值得一提的另一个问题与我们持久缓存工具有关。为了进行缓存,我们必须拥有一个可序列化对象。不幸的是,BundleResponse 没有标记为 Serializable

我们的解决方案是创建一个小型实用程序类,将BundleResponse分解为其值类型。这样做后,我们就可以序列化实用程序类。然后,在从缓存中检索时,我们会重建 BundleResponse


3
可能与此相关,但您提到的BundleResponse的http://msdn.microsoft.com/en-us/magazine/cc188950.aspx讨论了如何使用序列化代理来绕过该限制,这里是一个示例https://dev59.com/v2Ys5IYBdhLWcg3wE_ze#16121346。 - Chris Marisic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接