转自http://huacnlee.com/blog/use-etag-in-your-rails-app-to-speed-up-loading/

什么是 ETag

网上关于 ETag 的解释有很多,我这里简单的说明一下我的理解:

ETag 是 HTTP 协议的标准参数,一般是这样的:”686897696a7c876b7e” 一段字符,它能通过一段字符来判断浏览器 cache 的内容是否和服务端返回的内容是否相同,从而来决定是否要重新从服务器下载东西 (HTTP 状态 200 - 重新下载 / 304 - 没有更新)。

ETag 使用场景举例

这个东西非常适合用于动态内容上面,以减少不必要的 HTML 下载,达到加速的目的。

比如下面这个场景的例子:

  1. 用户访问 /topics/11 页面,TopicsController#show 加载 @topic,并通过 View 生成内容返回
  2. 用户来回访问 10 次 /topics/11,可此页面内容无任何变化
  3. 过了1天以后,@topic 有了新的回复,用户再次访问的时候,内容变了

上面的场景用户一共访问了 12 次 /topics/11 这个页面,但只有第一次和最后一次才有实质性的内容需要下载的,可在没有 ETag 的情况下面,服务器执行和浏览器下载都是有 12 次,其中的 10 次是多余的。

如果加上 ETag 以后,将会是这样:

  1. 用户访问 /topics/11 页面,TopicsController#show 加载 @topic,并通过 View 生成内容返回,并给出目前内容的 ETag: 89vbsn28716
  2. 用户带着 ETag: 89vbsn28716 再次访问 /topics/11 ,服务器检查 ETag 与执行结果,发现无变化,返回 304,浏览器直接使用 Cache 的内容渲染页面
  3. 过了一天以后,@topic 有了新回复,用户再次带着 ETag: 89vbsn28716 /topics/11,服务器检查 ETag 发现不对了,生成新内容,并返回 200

这个过程中,服务端执行了 12 次页面,而下载 HTML 内容到本地却只有两次。

Rails 里面开启 ETag

Rails 的 ActionController 里面已经为我们提供了 fresh_when 和 stale? 这两个方法用于处理 ETag,可以点击连接稍微看一下说明。

我下面以 Ruby China 的 查看 Wiki 页面 为例子演示如何在 Rails 里面合理的使用 ETag

pages_controller.rb:

1
2
3
4
5
6
7
class PagesController < ApplicationController
  def show
    @page = Page.find_by_slug(params[:id])
    @comments = @page.comments.paginate(:page => params[:page], :per_page => 50)
    fresh_when(:etag => [@page, @comments])
  end
end

加上 fresh_when 方法以后,Rails 将会用 @page@comments 内容的组合的 MD5 hash 值作为 ETag 并与 HTTP Headers 里面的 ETag 进行比较来决定是否需要执行后面的 Views 渲染,并返回 200304

在浏览器上面显示将会是这样:

没有 ETag 的情况 (72 ms):

有 ETag 的情况 (40 ms):

OMG! 页面加载速度直接提升了 46%,并且 ETag 命中的情况下,Views 上面的一系列代码都不用执行了,节省了不少资源。

但是实际的场景,往往没有上面这个例子这么简单……

比如,页面上有 current_user 的状态,页脚的 HTML 代码是通过 Setting.footer_html 出来的,Head 里面还有 Setting.custom_heads 出来的代码。

以上这些东西都是需要影响页面更新的。

实际上我们只需要将 fresh_when 方法在 ApplicationController 里面覆盖一下,把页面上需要调用而影响结果的东西加入到 fresh_when:etag 参数里面就好了:

application_controller.rb:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def fresh_when(opts = {})
  opts[:etag] ||= []
  # 保证 etag 参数是 Array 类型
  opts[:etag] = [opts[:etag]] if !opts[:etag].is_a?(Array)
  # 加入页面上直接调用的信息用于组合 etag
  opts[:etag] << current_user
  # Config 的某些信息
  opts[:etag] << SiteConfig.app_name
  opts[:etag] << SiteConfig.custom_head_html
  opts[:etag] << SiteConfig.footer_html
  opts[:etag] << SiteConfig.google_analytics_key
  # 所有 etag 保持一天
  opts[:etag] << Date.current
  super(opts)
end

这样一来,每个用户的 ETag 都是不同的,当用户登出和登录以后,页面的内容将会呈现不同的 ETag,同时当你修改 SiteConfig 的某些内容是,ETag 也会随着改变,这样一来 ETag 的引入就不会影响到页面更新了。

实际上你可以大量的使用 fresh_when 方法在你的动态页面上面,来减少 Rails View 的执行与 HTML 下载,只要好好分析,将页面上需要的内容加入到 :etag 参数里面就好了。

比如:

1
2
3
4
5
6
7
def index
  @hot_topics = Topic.hot.limit(10)
  @hot_users = User.hot.limit(10)
  @hot_nodes = Node.hot.limit(10)
  @recent_topics = Topic.recent.limit(10)
  fresh_when(:etag => [@hot_topics,@hot_users,@hot_nodes,@recent_topics])
end

转载于:https://www.cnblogs.com/wangyuyu/p/3545978.html

在你的 Rails App 中开启 ETag 加速页面载入同时节省资源相关推荐

  1. 如何在CST仿真软件中开启GPU加速

    相信电磁领域的工作人员经常利用CST进行仿真运算,对于较大的模型和网格剖分,一般会在电脑里额外安装GPU加速卡.这里主要说明如下四个问题: 1.如何判断要购买哪种加速卡? 2.如何安装正确的驱动程序? ...

  2. Webview在RecyclerView中开启硬件加速闪屏问题解决

    博客转移到:http://www.wangchengmeng.club/ 在项目中遇到一个问题:把Webview作为header加在Recyclerview中,开启硬件加速后,锤子手机闪屏严重,其他手 ...

  3. app中加载h5页面白屏问题

    一.问题描述:通过原生检查日志在网络不好的情况下,由于vue打包后的第三方js包加载失败导致h5页面白屏. 二.解决方案: 1.减少第三方依赖:在package.json中把不需要的包删除. 2.组件 ...

  4. 学会这一招,轻松玩转 app 中混合应用自动化测试

    现在的 app 中越来越多的页面通过 H5 来做了,理由很简单,不需要升级 app 就能让用户使用新的功能.这就苦了我们测试工程师了,混合应用自动化不会玩.今天咱们来聊一聊 app 中混合应用自动化怎 ...

  5. 通过Appium获取Android app中webview

    因为要测试Android app中嵌入的web页面,所以需要从native切换到webview.网上查了好多帖子,都用到类似下面代码: //判断是否有 WEBVIEW Set<String> ...

  6. 如何创建 Ping app 中的 UIViewController 转换动画?

    原文:How To Make A UIViewController Transition Animation Like in the Ping App 作者:Luke Parham 译者:kmyhy ...

  7. uni 在app中引入h5页面(uni编写)

    关于在app中引入网页,使用的webview标签 相对于uniapp 官网给出的webview使用方法在这里https://uniapp.dcloud.io/component/web-view 但是 ...

  8. 安卓app中国际化任何资源的方法

    先说下国际化的问题.首先,一般认为所谓的国际化不包含逻辑的国际化,那么国际化涉及到的内容就是与广义上的用户UI相关的,包括用户能看到.听到.摸到的东西.当然,摸到东西,一般在软件层面就不探讨了.所以, ...

  9. linux chrome 硬件加速,在Chrome上开启硬件加速和预先渲染的方法技巧

    在 Chrome 上开启硬件加速的方法非常简单,Chrome 正式版和测试版都可以通过在about:flags中开启硬件加速以提升网页浏览体验并延长电池使用时间,如果你是那种动不动就开30个标签以上的 ...

最新文章

  1. c++ 公有继承的赋值兼容规则
  2. keil5建立多文件的时候为什么总是出错
  3. Sring AOP(简记)
  4. 【OpenCV】OpenCV函数精讲之 -- 命名空间
  5. 手把手教我班小姐姐学java之方法重写与方法重载
  6. java rsa 128_如何用java实现128位密钥的RSA算法
  7. No such file or directory
  8. Precision、Recall、F计算:举例
  9. 点云应用于电力行业助力输配电安全距离检测分析以及精细化巡检
  10. 简单适用的抽奖小程序
  11. silk lobe资源公众号_【好设计资源库】公众号素材获取方式说明
  12. itunes计算机无法启动,电脑怎么打开itunes
  13. 修复Java使用POI合并Excel单元格后,边框不显示的问题
  14. Go语言圣经 - 第11章 测试 - 11.1 go test 11.2 测试函数
  15. viz::viz3d报错_我可以在Excel中获得该Viz吗?
  16. java计算机毕业设计线上花店购物商城源码+lw文档+系统+数据库
  17. #define 用法解析
  18. 基于stm32的恒功率无线充电
  19. 安装 SIMATIC STEP7 Professional 一直停留在修改系统 估计剩余时间:2分钟
  20. cc双聚类 matlab,mtba 双聚类matlab工具箱,包含各种主要的 算法:cc、floc、opsm、bimax、b LAS等 256万源代码下载- www.pudn.com...

热门文章

  1. 收集全面WIN7共享设置
  2. 利用蒙特卡算法仿真二进制双极性基带通信系统
  3. asp.net 动态绑定html表格
  4. ISA Server实验环境搭建与企业×××配置
  5. java版电子商务spring cloud分布式微服务b2b2c社交电商-spring cloud gateway之filter篇
  6. 面试题-两个数值交换
  7. Apache Ignite(五):Ignite的集群部署
  8. nginx负载均衡的session共享问题的解决方法
  9. Xcode6中添加pch文件
  10. 在WAS中得到OracleConnection