7.1 数据传输

Ajax从最基本层面来说,是一种与服务器通信而无须重载页面的方法;数据可以从服务器获取或者发送给服务器。有多种不同的方法建立这种通信通道,每种方法都有各自的优点和限制。

7.1.1 请求数据

五种常用技术向服务器请求数据:

1:XMLHttpRequest (XHR)
2:Dynamic script tag insertion
3:iframes
4:Comet
5:Multipart XHR

现代高性能JavaScript使用的是:XHR、动态脚本注入和Multipart XHR,其他两种往往在极端情况下使用,不做讨论。

XMLHttpRequest

XHR是目前最常用的技术,它允许异步发送和接收数据。

 --------------------------------------------------------------------注:如果你对python感兴趣,我这有个学习Python基地,里面有很多学习资料,感兴趣的+Q群:895817687--------------------------------------------------------------------var url = '/data.php';var params = ['id=934875','limit=20'];var req = new XMLHttpRequest();req.onreadystatechange = function() { if (req.readyState === 4) {var responseHeaders = req.getAllResponseHeaders(); // 获取响应头信息var data = req.responseText; // 获取数据// 数据处理。。。}}req.open('GET', url + '?' + params.join('&'), true);req.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); // 设置请求头信息req.send(null); // 发送请求

注意:由于XHR提供了高级的控制,所以浏览器对其增加了一些限制。你不能使用XHR从外域请求数据,而且低版本IE不仅不支持“流”,也不会提供readyState为3的状态。

动态脚本注入

这种技术克服了XHR的最大限制:跨域请求数据。

    var scriptElement = document.createElement('script');scriptElement.src = 'http://any-domain.com/javascript/lib.js';document.getElementsByTagName_r('head')[0].appendChild(scriptElement);

但是与XHR相比,动态脚本注入提供的控制是有限的。不能设置请求头,只能用GET,不能设置超时处理等。最后一点特别重要,不能使用纯XML、纯JSON或其他格式数据,无论哪种格式,都必须封装在一个回调函数里。

    var scriptElement = document.createElement('script');scriptElement.src = 'http://any-domain.com/javascript/lib.js';document.getElementsByTagName_r('head')[0].appendChild(scriptElement); function jsonCallback(jsonString) {var data = ('(' + jsonString + ')');// 数据处理。。。}

注意:使用这种技术从那些你无法直接控制的服务器上请求数据时需要小心。JavaScript没有任何权限和访问控制的概念,因此你使用动态脚本注入添加到页面的任何代码都可以完全控制整个页面。引入外部来源的代码时务必多加小心。

Multipart XHR

MXHR是一项最新的技术,它允许客户端只用一个HTTP请求就可以从服务器向客户端传送多个资源。它通过在服务器将资源打包成双方约定的字符串分割的长字符串并发送给客户端。
这个技术有一些缺点,其中最大的缺点是这种方式获取的资源不能被浏览器缓存。但某些情况下,MXHR依然能显著提高整体性能:

1:页面包含了大量其他地方用不到的资源,即不需要缓存,尤其是图片;
2:网站已经在每个页面中使用一个独立打包的JavaScript或CSS文件以减少HTTP请求;
因为对每个页面来说这些文件都是唯一的,所以不需要缓存中读取数据,触发重载页面;

7.1.2 发送数据

有时并不关心接收数据,只需要向服务器发送数据。当数据只需要发送到服务器时,有两种技术使用广发:XHR和信标(beacons)。

XMLHttpRequest

虽然XHR主要用于从服务器获取数据,但也可以将数据传回服务器。

GET:适用于传输少量数据。因为对于少量数据而言,GET请求只需要往服务器发送一个数据包;而POST至少要发送两个数据包(头信息和正文)。
POST:POST适合发送大数据到服务器。因为它不关心额外数据包的数量;另一个原因是IE对URL长度有限制(2048个字符),URL太长了就不能使用GET请求。

Beacons

这个技术非常类似动态脚本注入。它使用JavaScript创建一个新的Image对象,并把src属性设外服务器上脚本的URL。该URL包含了我们要通过GET请求传回的键值对数据。

    var url = '/status_tracker.php';var params = ['step=2','time=1248027314'];(new Image()).src = url + '?' + params.join('&');

服务器接收到数据并保存下来,无须向客户端返回任何信息,因此没有图片会显示出来。

7.2 数据格式

当考虑数据传输技术时,我们必须考虑:功能集、兼容性、性能及方向。而当考虑数据格式时,唯一需要比较的标准就是:速度。

7.2.1 XML

当Ajax最开始流行时,它选择XML作为数据格式。当时它有很多优势:极佳的通用性、格式严格、易于操作。那时JSON还没有正式作为交换格式,几乎所有的服务端语音都有操作XML的类库。

    <?xml version="1.0" encoding='UTF-8'?><users total="4"><user id="1"> <username>alice</username><realname>Alice Smith</realname><email>alice@alicesmith.com</email></user><user id="2"><username>bob</username><realname>Bob Jones</realname><email>bob@bobjones.com</email></user><user id="3"><username>carol</username><realname>Carol Williams</realname><email>carol@carolwilliams.com</email></user><user id="4"><username>dave</username><realname>Dave Johnson</realname><email>dave@davejohnson.com</email></user></users>可以对其进行优化:<?xml version="1.0" encoding='UTF-8'?><users total="4"><user id="1-id001" username="alice" realname="Alice Smith" email="alice@alicesmith.com" /><user id="2-id001" username="bob" realname="Bob Jones" email="bob@bobjones.com" /><user id="3-id001" username="carol" realname="Carol Williams" email="carol@carolwilliams.com" /><user id="4-id001" username="dave" realname="Dave Johnson" email="dave@davejohnson.com" /></users>

性能优化:简化版的XML更有效率,但是比那些最快的格式依然慢上一个数量级。在高性能Ajax中,XML没有立足之地。

7.2.2 JSON

JSON是一种JavaScript对象和数组直接量编写的轻量级且易于解析的数据格式。

    [{"id":1, "username":"alice", "realname": "Alice Smith", "email":"alice@alicesmith.com"},{"id":2, "username":"bob", "realname": "Bob Jones", "email":"bob@bobjones.com"},{"id":3, "username":"carol", "realname": "Carol Williams","email":"carol@carolwilliams.com"},{"id":4, "username":"dave", "realname": "Dave Johnson", "email":"dave@davejohnson.com"}]

可以进行简化:

    [{ "i": 1, "u": "alice", "r": "Alice Smith", "e": "alice@alicesmith.com" },{ "i": 2, "u": "bob", "r": "Bob Jones", "e": "bob@bobjones.com" },{ "i": 3, "u": "carol", "r": "Carol Williams", "e": "carol@carolwilliams.com" },{ "i": 4, "u": "dave", "r": "Dave Johnson", "e": "dave@davejohnson.com" }]

进一步简化:

[[ 1, "alice", "Alice Smith", "alice@alicesmith.com" ],[ 2, "bob", "Bob Jones", "bob@bobjones.com" ],[ 3, "carol", "Carol Williams", "carol@carolwilliams.com" ],[ 4, "dave", "Dave Johnson", "dave@davejohnson.com" ]
]

在不断的简化过程中,可读性越来越差,也更脆弱。但是文件尺寸却小得多:大约只有标准JSON的一半。解析也必须按照数据的顺序进行。

    function parseJSON(responseText) {var users = [];var usersArray = ('(' + responseText + ')');for (var i = 0, len = usersArray.length; i < len; i++) {users[i] = {id: usersArray[i][0],username: usersArray[i][1],realname: usersArray[i][2],email: usersArray[i][3]};}return users;}

7.2.3 HTML

一种可考虑的技术是在服务器端构建好整个HTML再传回客户端,JavaScript可以通过innerHTML属性把它插入页码相应位置。但问题是HTML是一种臃肿的数据格式,比XML更复杂。因此,作为一种数据格式,它既缓慢,又臃肿。

7.2.4 自定义格式

理想的数据格式应该只包含必要的结构,以便你可以分解出每个独立的字段。

    1:alice:Alice Smith:alice@alicesmith.com;2:bob:Bob Jones:bob@bobjones.com; 3:carol:Carol Williams:carol@carolwilliams.com;4:dave:Dave Johnson:dave@davejohnson.com

这种格式非常简洁,“数据/结构”比例相当高,比其他任何格式都高(除了纯文本)。只需要简单地调用字符串split()方法并传入分隔符作为参数即可,复杂一点的加上循环就好了。JavaScript中的循环和split()方法都是相当快的。

7.2.5 数据格式总结

通常来说,数据格式越轻量级越好,JSON和字符分隔的自定义是最好的。

7.3 Ajax性能指南

7.3.1 缓存数据

最快的Ajax请求就是没有请求。可以有两种方法来实现:

在服务端,设置HTTP头信息以确保响应会被浏览器缓存;
在客户端,把获取到的信息存储在本地,以避免再次请求。

7.3.2 了解Ajax类库的局限

所有得JavaScript库都允许你访问一个Ajax对象,它屏蔽浏览器之间的差异,给你一个统一的接口。大多数情况下这非常好,因为它使你可以关注你的项目,而不是那些古怪的浏览器上XHR的工作细节。然而,为了给你一个统一的接口,这些库必须简化接口,因为不是所有浏览器都实现了每个功能。这使得你不能访问XMLHttpRequest的完整功能。

性能优化:直接操作XHR对象减少了函数的开销,进一步提升了性能。但是,如果放弃Ajax类库,那么你可能在一些古怪的浏览器上遇到一些问题。

《高性能JavaScript》第七章 Ajax相关推荐

  1. 《高性能JavaScript》第九章 构建并部署高性能JavaScript应用

    本章使用到的技术可能已经过时,主要理解其思想.本章的目的是了解如何有效地组织并部署基于JavaScript的Web应用的一些必要知识. 1:Apache Ant:是一个软件构建自动化工具: 2:合并多 ...

  2. 《高性能JavaScript》第二章 数据存取

    JavaScript四种数据存储位置: 1:字面量:字面量只代表自身,不存储在特定位置.JavaScript中的字面量有:字符串.数字.布尔值.对象.数组.函数.正则表达式,以及null和undefi ...

  3. 《高性能JavaScript》第一章 加载和执行

    1.1 脚本位置 描述 将所有 原因 UI渲染和JavaScript运行共用一个线程, 反例 ----------------------------------------------------- ...

  4. JavaScript 第七章总结

    前言 主要介绍了关于 JavaScript 中有关 type 的问题.讲了很多关于各种 type 的 idiosyncrasies. 谈谈JavaScript types 在 JavaScript 中 ...

  5. Javascript第七章cookie的读取和写入源码第一课

    写入cookie <!DOCTYPE html> <html lang="en"> <head><meta charset="U ...

  6. 【读书笔记】《高性能JavaScript》

    缺陷 这本书是2010年出版的,这本书谈性能是有时效性的,现在马上就2018年了,这几年前端发展的速度是飞快的,书里面还有一些内容考虑IE6.7.8的东西,殊不知现在这些都已经不再考虑了,所以不可避免 ...

  7. 构建高性能ASP.NET站点 第七章 如何解决内存的问题(后篇)—托管资源优化—监常用优化措施...

    构建高性能ASP.NET站点 第七章 如何解决内存的问题(后篇)-托管资源优化-监常用优化措施   前言:有段时间没有写这个系列了,希望大家见谅,本篇主要将会介绍一些常用的CLR优化措施. 本篇的议题 ...

  8. Javascript第四章匿名函数第七课

    匿名函数的作用: 1.用于回调 2.一次性执行函数 Javascript第四章定义函数的形式.回调函数第五课 https://blog.csdn.net/qq_30225725/article/det ...

  9. 《高性能JavaScript》(读书笔记)

    这次主要是对<高性能JavaScript>一书的读书笔记,记录下自己之前没有注意到或者需要引起重视的地方 第一章 加载和执行 js代码在执行过程中会阻塞浏览器的其他进程,比如用户界面的绘制 ...

最新文章

  1. 35岁以后,不要成为程序员中的钻石
  2. CentOS 6.4安装配置LNMP服务器(Nginx+PHP+MySQL)
  3. 新概念英语(1-73)The way to King Street
  4. android 入门-工序
  5. 陈桥五笔用户编号获取_用户群组分析
  6. centos mate桌面_CentOS 7安装桌面汇总
  7. Ubuntu 18.04 + Anaconda 5.2 + Pycharm
  8. V星入侵(V 2009)第一季全集下载
  9. 【Linux】vim简介及安装
  10. linux DHCP安装和测试
  11. Android之drawable下快速生成icon图片vector
  12. 丙烯颜料试用心得和丙烯绘画入门
  13. xiunobbs 4 mysql_xiunobbs
  14. django mongo engine
  15. 用keil如何编写c类型语言,keil怎么写程序
  16. 如何高效地为室友电脑清理 C 盘?
  17. 扬帆际海教育:跨境电商需要了解的主流社媒平台
  18. 写了一个疫苗信息管理系统!(附源码)
  19. 物联网考计算机是跨专业,2014考研计算机等专业 加入物联网技术方向_跨考网
  20. [译] C++ 和 Android 本地 Activity 初探

热门文章

  1. vue 项目引用static目录资源_vuejs-templates静态资源目录src/assets、和static/区别
  2. Spring Boot-@Value获取值和@ConfigurationProperties获取值的比较
  3. securecrt7.0.0合并多个窗口
  4. SpringFox 3.0.0(包含springfox-swagger2-3.0.0)——无法访问/swagger-ui.html解决方案
  5. Can you raed it croretcly?
  6. Sequence in the Pocket
  7. Filter和Listener-学习笔记01【Filter 快速入门】
  8. Android 新闻客户端
  9. 观察者模式——解耦利器
  10. SpringBoot 2.x 监控中心:Actuator