• 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。

想知道更详细的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. def update_list
  7. self.list.updated_at = Time.now
  8. self.list.save
  9. end
  10. end

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

  1. def index
  2. @list_items = @list.list_items
  3. if stale?( :last_modified => @list.updated_at )
  4. respond_with( @list_items )
  5. end
  6. 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. collection do
  4. get :winners, :losers
  5. end
  6. end
  7. # /sd34fgh/rooms
  8. scope ':token', :token => /\w{5,5}/ do
  9. resources :rooms
  10. end
  11. # /descriptions
  12. # /pl/descriptions
  13. # /en/descriptions
  14. scope '(:locale)', :locale => /en|pl/ do
  15. resources :descriptions
  16. root :to => 'projects#index'
  17. end

3. New Action Mailer

示例代码:

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

Rails 3:提高Ajax应用速度相关推荐

  1. Web前端优化,提高加载速度

    研究表明:用户最满意的打开网页时间是2-5秒,如果等待超过10秒,99%的用户会关闭这个网页.也许这样讲,各位还不会有太多感触,接下来我列举一组数据:Google网站访问速度每慢400ms就导致用户搜 ...

  2. 如何让提高网站访问速度

    如何让提高网站访问速度 整理方案一: 网站访问速度可以直接影响到网站的流量,而网站的访问量几乎与网站的利益直接挂钩,因此网站的速度问题成为企业及站长十分关注的问题.现在网站越来越多,不少朋友的网站打开 ...

  3. mysql年月分表_MySQL之按月拆分主表并按月分表写入数据提高数据查询速度

    使用场景: 主表数据量特别大,为了提高查询的速度,可以考虑按月进行分表,要求就是当月的数据到当月表查询,上月的数据到上月表查询,当天的数据到主表来查询.这样在一定程度上也是提高了数据的查询速度 过程演 ...

  4. 利用curl并发来提高页面访问速度

    在我们平时的程序中难免出现同时访问几个接口的情况,平时我们用curl进行访问的时候,一般都是单个.顺序访问,假如有3个接口,每个接口耗时500毫秒那么我们三个接口就要花费1500毫秒了,这个问题太头疼 ...

  5. 计算机录入速度标准,怎么提高电脑录入速度?

    要想提高汉字的录入速度,上面的两种方法都应该掌握.其中第一种方法必须靠多练熟记掌握,我不想过多叙述,这里着重就第二种方法作简要叙述,供录入人员参考. 一.必须充分发挥词组和段操作的功能 熟练地使用词组 ...

  6. 6条策略提高mysql查询速度 潇湘博客

    6条策略提高mysql查询速度 1,表设计一定要优化,冗余数据最少,少用连接查询.如果在实际应用中,使用了极其复杂的连接,子查询,则数据表的设计得要重新考虑了. 2,尽量用char而不是varchar ...

  7. 处理上百万条的数据库如何提高处理查询速度

    处理上百万条的数据库如何提高处理查询速度 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 ...

  8. ASP.NET状缓存Cache的应用-提高数据库读取速度

    ASP.NET状缓存Cache的应用-提高数据库读取速度 原文:ASP.NET状缓存Cache的应用-提高数据库读取速度 一. Cache概述        既然缓存中的数据其实是来自数据库的,那么缓 ...

  9. edge浏览器运行不流畅怎么办 提高edge浏览器速度的方法

    edge浏览器是win10系统的专用浏览器,它代替了慢吞吞的IE,很多人觉得edge浏览器运行速度快,但是有时候浏览某些网站的时候会不流畅,所以怎么提高edge浏览器的运行速度呢,小编就来教教大家. ...

最新文章

  1. 【组队学习】【33期】吃瓜教程——西瓜书+南瓜书
  2. cython安装、使用
  3. Codeforces Beta Round #11 A. Increasing Sequence 贪心
  4. tensorflow常见函数
  5. 启动文件、简单的消息框
  6. echarts 中 symbol 自定义图片
  7. 【Kafka】Kafka如何彻底删除Kafka中的topic
  8. Unity 利用FFmpeg实现录屏、直播推流、音频视频格式转换、剪裁等功能
  9. js双击事件条件触发_js页面触发chargeRequest事件和Nginx获取日志信息
  10. 按键精灵 android,按键精灵手机版
  11. MCU通过UART实现OTA在线升级流程
  12. java 微信公众号消息推送 微信发送消息
  13. python 常用模块列表
  14. uniapp适配pc_uniapp+Html5端实现PC端适配
  15. 丙烯酸酯PEG丙烯酸酯,DA-PEG-DA
  16. MATLAB算法实战应用案例精讲-【图像处理】小目标检测(补充篇)(附python代码实现)
  17. 一、安装docker
  18. linux与linux之间共享目录
  19. 【路径规划】基于matlab蚁群优化遗传算法机器人栅格地图最短路径规划【含Matlab源码 1581期】
  20. 什么是画中画模式,画中画视频怎么操作

热门文章

  1. 详细讲解Quartz.NET
  2. 吴恩达机器学习+林轩田机器学习+高等数学和线性代数等视频领取
  3. 彻底搞懂 JS 中 this 机制
  4. 【无删减】Python老司机收藏夹的17个国外免费学习网站
  5. 视觉智能产品发布 阿里云这项世界第一的技术现在人人可用
  6. Struts2国际化
  7. 基于beego一键创建RESTFul应用
  8. 天龙2 场景地图人物 方向箭头 方法
  9. python内置函数多少个_每个数据科学家都应该知道的10个Python内置函数
  10. leetcode 26. 删除有序数组中的重复项