Rails 3:提高Ajax应用速度

  • Rails 3:提高Ajax应用速度

  • http://developer.51cto.com  2011-05-18 09:45  Stefan Siebel  51CTO  我要评论(0)
  • 我建立了一个列表网站,ListKungFo,其中大量使用了Ajax,目前为止网站运行非常良好。而过去两周里,我一直在寻找一些能够进一步提高UI性能的方法,现在写出来和大家分享。

【51CTO.com 5月18日外电头条】而过去两周里,我一直在寻找一些能够进一步提高UI性能的方法,得到的成果主要是返回正确的HTTP状态代码,优化浏览器的缓存功能。

51CTO推荐专题:Ruby On Rails开发教程

具体地说,会返回两种状态代码:

◆ 返回200-“Ok”,这告知浏览器服务器能够成功的对请求进行响应。响应包含了从服务器返回的HTTP载荷中的数据。

◆ 返回304-“Not modified”,表示未修改,这告知浏览器所发出请求中的数据并没有改变,因此可以从缓存中装载数据。这种情况下,响应不包含HTTP载荷。

既然“Not modified”消息包含的数据要少得多(没有内容,只有头),这样你就最好返回到浏览器这里,当然你需要先确保浏览器的缓存中已经存在数据了。

在我的应用中,我发现服务器返回的200-响应比304-响应要多得多。这造成了两方面的问题:

◆ 不得不传输比所需的更多的数据

◆ UI不得不处理更多数据

这两方面出现的问题都会让应用的速度变慢。虽然只是慢了一点,但在UI端还是足够让人察觉到了。幸运的是你只需要对Rails应用做几个小修改,就能获得应有的效果。

1在GET方法中使用stale?语句

  1. def show  
  2.   @list_item = @list.list_items.find( params[ :id ] )  
  3.   if stale?( :etag => @list_item, :last_modified => @list_item.updated_at.utc, :public => true )  
  4.     respond_with( @list_item )  
  5.   end  
  6. end  

stale?语句会通过响应发送回一个etag与一个last_modified日期。如果下一个请求是相同的URL,那么浏览器会把这个etag和last_modified日期发送给服务器。然后stale?方法会对这两个参数进行分析,如果内容相同,则返回304,如果出现参数值不同,那么说明有新的内容,这样返回200。

Rails 3新特性:提高Ajax应用速度

想知道更详细的stale?方法的用法,可以查阅Rails的API文档,以及阅读Rails的手册。

2 确保浏览器对每次请求都接收新的数据

上面的修改完成后,发生了一些有趣的事情。在很短的时间内,相同的Ajax行为被触发了许多次,而浏览器并没有向服务器发送一次请求,而都是从缓存中取得数据。虽然显然让UI变得快了很多,但这并不完全是我所想要的。我的目标是获得最佳的性能,同时还要保证屏幕上出现正确与最新的数据。

浏览器的缓冲行为受到了三个HTTP头的flag状态的影响:cache-controll、pragma和expires

想要关闭浏览器的缓存功能,你可以发送下面的代码:

  1. def set_cache_buster  
  2.     response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"  
  3.     response.headers["Pragma"] = "no-cache"  
  4.     response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"  
  5.   end 

然而我想要做的是这样:

  1. def set_must_revalidate  
  2.     response.headers["Cache-Control"] = "must-revalidate"  
  3.   end 

因为这么做可以让浏览器在每次请求时检查新加入的和被更新的数据,我在我的application_controller.rb中添加了这个方法,并且在before_filter控制器中加以调用。

3在返回集合的GET方法中使用stale?(例如索引)

上面的stale?例子是从控制器的show方法中取出的,这是网络上非常通用的做法。如果想要使用这个方法返回一个集合,比如一个典型的控制器索引方法,那么需要想办法找出当前的集合和上次请求中的是否相同。

我的ListKungFu网站有一个类型列表List,其中包含很多ListItem。每个ListItem从属于一个List。为了在list_items_controller中找出某个ListItem集合是否有变化,我添加了名为list.updated_at的时间戳,每次写入操作时都会更新。

在ListItem.rb中:

  1. class ListItem < ActiveRecord::Base 
  2.   belongs_to :list  
  3.   after_save :update_list  
  4.   after_destroy :update_list  
  5.    
  6.   # [...]  
  7.    
  8.   def update_list  
  9.     self.list.updated_at = Time.now  
  10.     self.list.save  
  11.   end  
  12. end 

这样,list_items_controller的索引方法看上去就像这样:

  1. def index  
  2.     @list_items = @list.list_items  
  3.    
  4.     if stale?( :last_modified => @list.updated_at )  
  5.       respond_with( @list_items )  
  6.     end  
  7.   end 

如果不使用updated_at字段,我也可以给List模型加上一个version字段,但这样看起来没什么必要。如果这个模型不适合你的应用,那么你需要找到另一种方法,检查集合是否被修改了,比如计算一下集合中所有对象的校验和,这也能行得通。

Rails 3.0 主要改进内容:

1. New Active Record query engine

示例代码:

  1. users = User.where(:name => "david").limit(20)  
  2. users.where("age > 29")  
  3. # SELECT * FROM users  
  4. # WHERE name = "david" AND age > 29   
  5. # ORDER BY name  
  6. # LIMIT 20  
  7. users.order(:name).each { |user| puts user.name }  

2. New router for Action Controller

示例代码:

  1. resources :people do  
  2.   resource :avatar  
  3.  
  4.   collection do  
  5.     get :winners, :losers  
  6.   end  
  7. end  
  8.  
  9. # /sd34fgh/rooms  
  10. scope ':token', :token => /\w{5,5}/ do  
  11.   resources :rooms  
  12. end  
  13.  
  14. # /descriptions  
  15. # /pl/descriptions  
  16. # /en/descriptions  
  17. scope '(:locale)', :locale => /en|pl/ do  
  18.   resources :descriptions  
  19.   root :to => 'projects#index'  
  20. end 

3. New Action Mailer

示例代码:

  1. class Notifier < ActionMailer::Base 
  2.   default :from => 
  3.     "Highrise <system@#{APPLICATION_DOMAIN}>"   
  4.  
  5.   def new_project(digest, project, person)  
  6.     @digest, @project, @person = digest, project, person  
  7.  
  8.     attachments['digest.pdf'] = digest.to_pdf  
  9.     attachments['logo.jpg']   = File.read(project.logo_path)  
  10.  
  11.     mail(  
  12.       :subject => "Your digest for #{project.name}",  
  13.       :to => person.email_address_with_name  
  14.     ) do |format|  
  15.       format.text { render :text => "Something texty" }  
  16.       format.html { render :text => "Something <i>textyi>" }  
  17.     end  
  18.   end  
  19. end 

4. Manage dependencies with Bundler

5. 默认启用跨站点工具 XSS 保护

6. 告别字符编码问题困扰

7. Active Model: Validations, callbacks, etc for all models

8. 官方的插件 API

9. 内部重构

10. Agnosticism with jQuery, rSpec, and Data Mapper

11. 文档完善 

Rails 是一个用于开发数据库驱动的网络应用程序的完整框架。Rails基于MVC(模型- 视图- 控制器)设计模式。从视图中的Ajax应用,到控制器中的访问请求和反馈,到封装数据库的模型,Rails 为你提供一个纯Ruby的开发环境。发布网站时,你只需要一个数据库和一个网络服务器即可。

【编辑推荐】

  1. 程序员的另类境界:Rails创始人驾保时捷参加职业赛
  2. 在Nginx上运行Ruby on Rails
  3. 解读Ruby on Rails的成功秘籍
  4. Twitter从Rails迁移到了Java
  5. 基于Ruby On Rails开发高品质Web应用

转载于:https://www.cnblogs.com/ToDoToTry/archive/2011/10/11/2207247.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/410341.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[html] websocket和socket有什么区别?

[html] websocket和socket有什么区别&#xff1f; 1.Socket 是传输控制层的接口。用户可以通过 Socket 来操作底层 TCP/IP 协议族通信。 2.WebSocket 是一个完整应用层协议。 3.Socket 更灵活&#xff0c;WebSocket 更易用。 4.两者都能做即时通讯个人简介 我是歌谣&#xff…

opencv支持python3吗_Python3.4+opencv3

1、安装Python 3.4 for Windows 好的这好像没有什么可以说的 2、下载OpenCV 3和Numpy(OpenCV依赖Numpy库) 大家在这里就出了问题。如果使用直接使用pip install pyopencv安装一定会出错。这里使用了Python界活雷锋封装的安装包&#xff0c;大家根据自己的系统下载&#xff1a; …

Python之浅谈运算符

目录 格式化输出的三种方式基本运算符流程控制格式化输出的三种方式 运算符的语义取决于其操作数的类型 第一种格式化方式&#xff08;3.0&#xff09; name Tim height 170 weight 120 print(My name is:%s,my height is:%s,my weight is:%s%{name,height,weight})第二种格…

[html] websocket和http有什么区别?

[html] websocket和http有什么区别&#xff1f; WebSocket是双向的&#xff0c;在客户端-服务器通信的场景中使用的全双工协议&#xff0c;与HTTP不同&#xff0c;它以ws://或wss://开头。 HTTP是单向的&#xff0c;客户端发送请求&#xff0c;服务器发送响应。个人简介 我是…

Socketpair 简介

socketpair - a slight generalization of pipes used for two-way stream communication. 以下内容来自&#xff1a;匠意雕码 http://my.oschina.net/zengsai/blog/12583 今天用了一个从没玩过的socket函数socketpair()&#xff0c;它的作用是在进程内创建一对sock连接。乍一看…

cacti安装配置详解_MySQL实战001:8.0免安装版服务配置详解

首先我们需要先下载MySQL的安装包&#xff0c;MYSQL官方下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/&#xff0c;这里我下载的是MySQL Community Server 8.0.15版本&#xff0c;以前MySQL还有安装版&#xff0c;现在都是压缩版&#xff0c;解压之后将环境配置…

HttpServletRequest简述

HttpServletRequest简述 HttpServletRequest httpServletRequest (HttpServletRequest) request;/*getRequestURL方法返回客户端发出请求时的完整URL。getRequestURI方法返回请求行中的资源名部分。getQueryString 方法返回请求行中的参数部分。getRemoteAddr方法返回发出请求…

[html] 图片上传时实现本地预览功能的原理是什么?

[html] 图片上传时实现本地预览功能的原理是什么&#xff1f; 通过HTML5 File API读取用户上传的图片&#xff0c;生成一个image对象显示到页面个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录…

推荐两个检索和分类小工具Carrot2 OSS

Carrot2 Carrot2是一个开源搜索结果分类引擎。它能够自动把搜索结果组织成一些专题分类。Carrot2提供的一个架构能够从各种搜索引擎&#xff08;YahooAPI、GoogleAPI、MSN Search API、eTools Meta Search、Alexa Web Search、PubMed、OpenSearch、Lucene index、SOLR&#xff…

Eclipse最常用快捷键

Alt← 前一个编辑的页面 Alt→ 下一个编辑的页面 AltEnter 显示当前选择文件的属性 CtrlF11运行Run As CtrlM 当前窗口最大化 CtrlF7 视窗口切换 CtrlF8 模式切换 CtrlQ 定位到最后编辑的地方 CtrlL 定位在具体某行 CtrlK 选中的Word快速定位到下一个 ctrl.及ctrl1 当某行出错时…

[html] input如何在各个浏览器下保持UI统一?

[html] input如何在各个浏览器下保持UI统一&#xff1f; .ibutton { padding: 3px 15px; *padding: 0 15px; *height: 24px; font-size: 12px; text-align: center; text-shadow: #CF510B 0 1px 0; border:1px solid #ec5c0d; border-radius: 2px; background: #FC750A; backg…

11.27 如何选择具有某一角色的当事人?

/// <summary> ///根据当事人挡任的角色名称、当事人名称、名称拼音、身份证号模糊查询当事人 /// </summary> /// <param name"RoleName">角色名称</param> /// <param name"Name">当事人名称</param> /// <param…

python整数序列求和_Python从菜鸟到高手(14):序列的加法和乘法

1 序列的加法 序列也可以相加&#xff0c;但要注意&#xff0c;这里的相加&#xff0c;并不是相对应的序列元素值相加&#xff0c;而是序列首尾相接。由于字符串属于字符序列&#xff0c;所以字符串相加也可以看做是序列相加。但一个字符串不能和一个序列相加&#xff0c;否则会…

mysql xtrabackup 遭遇严重bug

我们的mysql 备份系统遭遇严重bug源于 开源软件 xtrabackup 的一个bug https://bugs.launchpad.net/percona-xtrabackup/bug/722638之前我们的大规模部署都没有遇到这问题。在做计数器转mysql 后&#xff0c;我们部署了备份系统&#xff0c;屡屡备份失败&#xff0c;于是决定彻…

[html] 能否做到禁止打印页面?如果可以那要怎么做?

[html] 能否做到禁止打印页面&#xff1f;如果可以那要怎么做&#xff1f; document.onbeforeprint function(){ return false; };个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一…

laydate时间控件有时候无效_新角度,如何无效没用地听课

嗨喽&#xff0c;大家好。这一期我想向大家展示一下如何无效地听课。1.上课的时候&#xff0c;全程集中注意力&#xff0c;每一秒都不能放松&#xff0c;使自己的大脑保持高度紧张中。我们这么年轻&#xff0c;精神充沛得很&#xff0c;只要累不死就往死里学。 2.下课的时候也不…

[html] 跨标签页的通讯方式有哪些

[html] 跨标签页的通讯方式有哪些 iframe document.name postMessage个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

让IE和Firefox(包括chrome)浏览器默认产生滚动条的滚动槽

html{overflow-y:scroll;}转载于:https://www.cnblogs.com/yuchav/archive/2011/10/19/2217652.html

Nike Air Jordan Sneakers

http://blog.tangcs.com/2009/05/27/nike-air-jordan-sneakers/转载于:https://www.cnblogs.com/WarrenTang/articles/1490574.html

anaconda python删除pyltp_Anaconda使用

Anaconda 是什么&#xff1f;Anaconda 是一个可用于科学计算的 Python 发行版&#xff0c;支持 Linux、Mac、 Windows系统&#xff0c;内置了常用的科学计算包。它解决了官方 Python 的两大痛点。第一&#xff1a;提供了包管理功能&#xff0c;Windows 平台安装第三方包经常失败…