分享 Rails 中使用 ETag 加速页面载入

huacnlee · December 17, 2012 · Last by zgm replied at March 15, 2013 · 9750 hits
Topic has been selected as the excellent topic by the admin.

最近尝试给 Ruby China 的某些页面加入了 ETag,效果很不错,总结了一下:

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

其实,我现在觉得直接上 xsl-stylesheet 才是正解

也减少了服务器的压力。

晚上回去试试,先收藏

用 Rails4 的 etagger 写起来会更自然一些:https://github.com/rails/etagger

#1 楼 @bhuztez 啥东东?和这个帖子有什么关系......

#5 楼 @hooopo 有关系啊,就直接返回 XML 啊。这样你 HTML 模板也是静态文件,直接在浏览器里缓存了。返回内容本来就短,要不要 ETag 无所谓,ETag 还耗 CPU 呢

#6 楼 @bhuztez 好吧 你说的和直接返回 JSON,然后在客户端渲染是一个意思吧 客户端渲染复杂性增加很多呢

#7 楼 @hooopo 不一样啊,你返回 JSON 就只能用 JavaScript 渲染。XSLT 是浏览器原生实现的...

#8 楼 @bhuztez 给个实际的例子看看啊

PS. 这么好的方案为啥大家都不用?

#9 楼 @hooopo 我打算试试看了,我也没想明白为啥不用,可能都没想到吧

http://en.wikipedia.org/wiki/XSLT

#10 楼 @bhuztez HTML 结构的生成不可能仅仅是一个 XML 这么简单把!如何整理结构,绑定 JS 事件。

#11 楼 @huacnlee 你没理解 XSLT

浏览器将收到的 XML 用 XSLT 模板转换成 HTML,再当 HTML 载入

#12 楼 @bhuztez 哦,我又仔细看了一下 Wikipedia 的例子,大概明白了

不过带出好几个新的问题了:

  1. 如果 HTML 结构是浏览器解析出来的,那蜘蛛就没法爬了
  2. 实际情况是 XSLT 的模板也没法直接 Cache 在本地的,不然模板有修改的时候,没法刷新
  3. #13 楼 @hooopo
  4. 前端的渲染速度是否好,还不确定,如果是以前那种 HTML 的,至少某些复杂慢的区域可以整个 HTML 做成 cache 来减少运算,XSLT 这样这些都不好处理了。

#14 楼 @huacnlee

如果 HTML 结构是浏览器解析出来的,那蜘蛛就没法爬了

直接返回给支持 HTML 啊,怎么也得有 fallback,在 Server 端进行 XSLT 的。第一次打开页面的时候,你总得返回个 HTML,万一浏览器不支持,就悲剧了。那个 HTML 里嵌个 JavaScript,检查一下浏览器是否支持 XSLT,支持就设个 cookie。

实际情况是 XSLT 的模板也没法直接 Cache 在本地的,不然模板有修改的时候,没法刷新

用那个 xsl 模板是在 xml 里的 xml-stylesheet 那儿的 href 里指定的

<?xml-stylesheet href="example2.xsl" type="text/xsl" ?>

#13 楼 @hooopo ,看起来不错,不过感觉又学了一套模板语言...

反正我早就会了......

前端的渲染速度是否好,还不确定

应该比用 JavaScript 渲染 JSON 好多了,毕竟是原生实现啊。另外是用客户端 CPU 换传输时间,是否合算那也只能看情况了。

#13 楼 @hooopo 关键是你能让 HTML 页面,Ajax 请求,API 调用都用同一个结果 ...

#16 楼 @bhuztez 有意思,快写个 demo 看看

@huacnlee 不知道是不是 Etag 的原因,原来对同一个 Topic 刷新会变动的 "小贴士", 现在一直显示同一个。并且更新过后的绿色 Alert 条,重复刷新也会一直显示 - -||

#18 楼 @wppurking 对的,就是因为你刷新的时候,没有变化,依然用的本地 cache 的内容,不过这里影响不大

这个不用设置 Nginx?默认开启支持 ETag?

#20 楼 @HungYuHei 不用的,这个是在 Rails 里面设置 ETag 信息

46%。。渲染页面居然需要这么久。。?

#22 楼 @jjym 还包括网络传输.... 304 响应就不会从服务器端再传输同样的内容到客户端,也节省了网络传输数据量的时间。

#19 楼 @huacnlee "小贴士"无伤大雅,更新回复以后刷新页面一直显示那个绿色的"回帖更新成功."就感觉有点怪怪的了。

#24 楼 @wppurking 这个好办,稍后修正一下

#23 楼 @wppurking 但是 Rails 默认使用Rack::Etag,还是 304,所以网络传输的时间还是可以忽略吧

不错的点子 最近在折腾性能这一块 俺明天也试试 下面给一个 我整理的一些主要是 server 端缓存的 给大家分享一下 https://gist.github.com/4265619 最后 @huacnlee 号外一下

<!--
      ____        __             ________    _
     / __ \__  __/ /_  __  __   / ____/ /_  (_)___  ____ _
    / /_/ / / / / __ \/ / / /  / /   / __ \/ / __ \/ __ `/
   / _, _/ /_/ / /_/ / /_/ /  / /___/ / / / / / / / /_/ /
  /_/ |_|\__,_/_.___/\__, /   \____/_/ /_/_/_/ /_/\__,_/
                    /____/
  ========================================================
                                          ruby-china.org

  App Environments:
  --------------------------------------------------------
  Ruby:  1.9.3-p327
  Rails: 3.2.9
-->

这个 怎么弄出来的呢

#27 楼 @jhjguxin 以前用 Sublime Text 2 的某个插件实现的,后面版本号是直接调用 Ruby 的方法出来的

@huacnlee 有名吗???

brew install figlet

类似效果,但不是斜体

 ____        _              ____ _     _             
|  _ \ _   _| |__  _   _   / ___| |__ (_)_ __   __ _ 
| |_) | | | | '_ \| | | | | |   | '_ \| | '_ \ / _` |
|  _ <| |_| | |_) | |_| | | |___| | | | | | | | (_| |
|_| \_\\__,_|_.__/ \__, |  \____|_| |_|_|_| |_|\__,_|
                   |___/                            

以前 china unix 的 blog 就是用 xsl 做模板的

我用上了,果然效果很棒。感谢分享

Unknow user #37 December 19, 2012

XSLT 在中国我知道最早是看射手播放器 http://blog.splayer.org/?tag=XSLT

现在在做的项目是把所有关于 current_user 判断的情况从 view 里面抽出来放到 客户端来修改。这样可以做到 cross user cache sharing,效果会提升很多。

关于 XSLT,有一个 CMS: http://getsymphony.com/

2 年前,HP 的一个项目名为 ESO 就用的是 xml + xsl,当时还是用 c++ 写的 ```

@knwang 关于 current_user 判断的情况从 view 里面抽出来放到 客户端来修改 能介绍下吗?

XSLT 就是 xml 版的 lisp, 最早我就在暴雪官网看到过用... 后来换掉不用了,太蛋疼了...

用 xml 解决一个问题,你就有了两个问题,然后再用 xslt, 你就有了ℵ2个问题

上,上 版的 csdn 论坛 XSLT + XML 的

@huacnlee etag 每次请求同一样,为什么返回的状态码还是 200 呢

#45 楼 @aoner curl 看看 etag 是不是相同的

#47 楼 @aoner curl 发出来看看. #46 楼 @huacnlee 多个服务器部署的 rails 怎么处理 etag? 对象在不同的 rails 进程中产生的 etag 不一样啊。

#48 楼 @zgm 不同的进程中 etag 应该也是相同的(据目前 Ruby China 的状态来看)

#48 楼 @zgm #49 楼 @huacnlee aoner@ubuntu:~$ curl -I 5433.com/cards/sdo-cjpp-jbzh HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Connection: keep-alive Status: 200 X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 3.0.19 ETag: "13085fdf57aadebcabc85c1363b25ab1" Cache-Control: max-age=0, private, must-revalidate X-UA-Compatible: IE=Edge,chrome=1 Set-Cookie: _mg_session=BAh7B0kiD3Nlc3Npb25faWQGOgZFVEkiJTIwN2VjZjg2MWQxMTZiYmVhYWMwOTYzNzM4MDdjNzI3BjsAVEkiEF9jc3JmX3Rva2VuBjsARkkiMWFqU0R5NnNQSUFzUFFSSE82ZE1tQWQxdmRicUdseXh3bDFma3d1b1FlTUk9BjsARg%3D%3D--c3cbb423419f7e97f91787ec08c450c7f8445892; path=/; HttpOnly X-Request-Id: eb53fd1e351b34fecc8d22f29f086431 X-Runtime: 0.025831 Date: Fri, 15 Mar 2013 11:00:36 GMT X-Rack-Cache: miss

curl -I 5433.com/cards/sdo-cjpp-jbzh -H 'if-none-modify: "13085fdf57aadebcabc85c1363b25ab1"'

You need to Sign in before reply, if you don't have an account, please Sign up first.