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,一经查实,立即删除!

相关文章

opencv支持python3吗_Python3.4+opencv3

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

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;解压之后将环境配置…

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

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

anaconda python删除pyltp_Anaconda使用

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

gc日志怎么看_你应该怎么监控Kafka?

监控 Kafka&#xff0c;历来都是个老大难的问题。无论是在我维护的微信公众号&#xff0c;还是 Kafka QQ群里面&#xff0c;大家问得最多的问题&#xff0c;一定是 Kafka 的监控。大家提问的内容看似五花八门&#xff0c;但真正想了解的&#xff0c;其实都是监控这点事&#xf…

c语言 二进制输出_收藏!C语言入门基础知识大全

C语言中的逻辑值只有两个&#xff1a;真(true)和假(flase)。用非零代表真&#xff0c;用零代表假。因此&#xff0c;对于任意一个表达式&#xff0c;如果它的值为零&#xff0c;就代表一个假值&#xff0c;如果它的值为非零&#xff0c;就代表一个真值。只要值不是零&#xff0…

机器学习算法与Python实践之(七)逻辑回归(Logistic Regression)

http://blog.csdn.net/zouxy09/article/details/20319673 机器学习算法与Python实践之&#xff08;七&#xff09;逻辑回归&#xff08;Logistic Regression&#xff09; zouxy09qq.com http://blog.csdn.net/zouxy09 机器学习算法与Python实践这个系列主要是参考《机器学习实战…

protected访问权限_复习封装与访问控制

java 中的封装性是通过对成员变量和方法进行访问控制实现的&#xff0c;访问控制分为个等级 &#xff1a;私有 private &#xff1b;默认 &#xff1b;保护 protected &#xff1b;公有 public &#xff1b;访问权限表控制等级 同一个类 同一个包 不同包的子包 不同包非子类 私…

html日期选择框_第十课 日期选择框(datepicker)的操作

有客户问&#xff1a;datepicker是怎么操作的&#xff1f;我答&#xff1a;datepicker可以直接用"输入文本"组件。客户说&#xff1a;不是&#xff0c;现在我操作的这个网页上datepicker是不能直接输入的&#xff0c;否则就直接用“输入文本”组件搞定&#xff0c;很…

E-triples II_2019牛客暑期多校训练营(第四场)

求用n个3的倍数的数按位或出数字a的方案数有多少种&#xff08;0也算3的倍数&#xff09; 题解 若数b的每个二进制位上的1&#xff0c;在a中也为1&#xff0c;则称b为a的子集容易知道任意个a的子集按位或出来的结果还是a的子集若问题改为按位或出来的结果是a的子集的方案数&…

SRTE测试

网络拓扑&#xff1a; XRV1 hostname XRV1explicit-path name SRTE index 10 next-address strict ipv4 unicast 10.10.2.2 index 20 next-address strict ipv4 unicast 10.10.3.2 index 30 next-address strict ipv4 unicast 10.10.4.1 index 40 next-address strict ipv4 un…

java笔记:自己动手写javaEE框架(七)--使用JSON和Ajax技术

今天我要将json和ajax引入到我所写的框架&#xff0c;不过今天用到的技术有部分不是我框架最终使用到的技术&#xff0c;比如ajax技术&#xff0c;我用到的是最为原始的ajax技术&#xff0c;这次算是对老技术的回顾&#xff0c;不过不管技术如何演进&#xff0c;对技术的本质的…

系统分析师成长之路

去年拿到软件设计师证书后&#xff0c;查了下高级认证中系统分析师&#xff0c;原来发现自己目前工作内容更像系统分析师&#xff08;与用户调研、明确需求内容、熟悉企业数据模型、安排开发人员设计程序、牵头日常维护工作、团队人员管理&#xff09;。去年底马上下决定趁热打…

python 收发邮件_python发送各类邮件的主要基本方法

利用python实现基本的邮件发送。 感谢以下博客的整理&#xff0c;本人在学习的同时也做了一些整理 一、相关模块介绍 发送邮件主要用到了smtplib和email两个模块&#xff0c;这里首先就两个模块进行一下简单的介绍&#xff1a; 1、smtplib模块 smtplib.SMTP([host[, port[, loc…

区分Activity的四种加载模式

在多Activity开发中&#xff0c;有可能是自己应用之间的Activity跳转&#xff0c;或者夹带其他应用的可复用Activity。可能会希望跳转到原来某个Activity实例&#xff0c;而不是产生大量重复的Activity。 这需要为Activity配置特定的加载模式&#xff0c;而不是使用默认的加载模…

laravel常用响应操作

转载于:https://www.cnblogs.com/saintdingspage/p/11298246.html

python中mat函数_python matplotlib中的subplot函数使用详解

python里面的matplotlib.pylot是大家比较常用的&#xff0c;功能也还不错的一个包。基本框架比较简单&#xff0c;但是做一个功能完善且比较好看整洁的图&#xff0c;免不了要网上查找一些函数。于是&#xff0c;为了节省时间&#xff0c;可以一劳永逸。我把常用函数作了一个总…

if else if else语句格式_你还在用if/else吗?

你还在用if/else吗&#xff1f;前提我们在日常开发当中经常会遇到复杂的条件判断&#xff0c;一般的做法是用if/else&#xff0c;或者优雅一点的写法是用switch语句来实现多个条件的判断&#xff0c;这样的话会有很多问题&#xff0c;随着判断条件的增加&#xff0c;代码中if/e…

乔梁专访——让持续交付变为可能

本月起&#xff0c;图灵社区陆续推出专业IT人访谈版块&#xff0c;首期人物是百度公司项目管理部高级架构师、《持续交付》译者乔梁。   本次访谈分三个主题&#xff1a;   1、 从概念和技术两个层次来解释持续交付   2、.持续交付是可实施的   3、持续交付将变成必备…

java 变量锁_并发编程高频面试题:可重入锁+线程池+内存模型等(含答案)

对于一个Java程序员而言,能否熟练掌握并发编程是判断他优秀与否的重要标准之一。因为并发编程是Java语言中最为晦涩的知识点,它涉及操作系统、内存、CPU、编程语言等多方面的基础能力,更为考验一个程序员的内功。那到底应该怎么学习并发编程呢? Java SDK的并发工具包有很多,是…