渲染视图时会自动“缓存”啥?

Posted

技术标签:

【中文标题】渲染视图时会自动“缓存”啥?【英文标题】:What is automatically "cached" when rendering a view?渲染视图时会自动“缓存”什么? 【发布时间】:2017-04-08 16:46:23 【问题描述】:

假设我们在一个视图中有这两个输出:

@post.user.first_name

current_user.posts.size

如果上面的输出会在一个视图中被多次调用,Rails 是否“足够聪明”,不会每次都访问数据库?

如果答案是肯定的 - 是否有任何值得了解的“一般规则”?

如果答案是否定的 - 将关联的对象存储在它自己的变量中是否是一个好习惯?

【问题讨论】:

【参考方案1】:

默认为 ActiveRecord caches queries for performance。如果您在控制台中执行 AC 查询几次,您会看到第二个查询由于 AC 缓存而执行得更快。所以我想这也适用于视图中的查询。

您可以使用 Rails Fragment Caching 功能手动缓存对象。

片段缓存允许将视图逻辑的片段包装在一个 缓存块并在下一个请求时从缓存存储中提供 进来。

还有Cache Stores供你使用。

Rails 为缓存数据提供了不同的存储方式(除了 SQL 和页面缓存)。

【讨论】:

【参考方案2】:

对视图的查询是在呈现视图的控制器操作中完成的。您会注意到您在控制器操作中定义了@post,但您可能看不到current_user 的定义。这通常是因为您使用的是设计 gem,而定义 current_user 方法的代码是 gem 的一部分。

渲染视图所需的一切都应在控制器中通过ActiveRecord 查询,并在应用程序的内存中查询,以准备渲染视图。因此多次调用 @post 或 current_user 应该无关紧要。

有时对象通过视图的关联被调用,例如。 @post.user.name 将不得不查询用户。这会起作用,但最好是模型-视图-控制器分离,以便将用户与控制器中的帖子一起预先加载。遵循 MVC 并确保您的查询发生在控制器中也将帮助您避免 N + 1 查询性能问题。见Rails Active Record Query Eager Load

使用帖子查询用户的示例。

@post = Post.find(post_params).includes(:user)

【讨论】:

感谢您的介绍。所以我的问题的答案可能是——不。 IE。 db 查询不会自动“缓存”,如果没有最佳实践(每个对象的实例变量和 .includes 的用法) - 那么我们将更频繁地访问数据库。跨度> 是的,ActiveRecord 查询被缓存以提高性能,如果控制器操作中的查询相同,请参阅 Martin Zinovsky 的回答。但是,如果没有最佳实践,并且您开始在模板中请求关联的对象,您将强制执行额外的查询并损害性能。

以上是关于渲染视图时会自动“缓存”啥?的主要内容,如果未能解决你的问题,请参考以下文章

部分视图和渲染部分视图有啥区别?

使用计算的 aurelia 搜索过滤在渲染到视图时会导致问题

具有图像视图并通过网络模型的单元格:重用时会发生啥?

渲染视图中的自动布局不会更新其框架

在 UIViewController 之间切换时会发生啥类型的内存问题?

ios - 表格单元格视图中的图像在运行时没有适当的大小,当我滚动时会自动改变大小和剪切边界