前端要给力之:URL应该有多长?
URL到底应该有多长?我为什么要提这个问题呢?有许多优化指南里都写着:要尽量减小COOKIE、缩短URL,以及尽可能地使用GET
请求等等,以便优化WEB页面的请求和装载。但是,这种所谓“尽可能”、“尽量”只是定性的描述,定量的来看,要缩短到多少个字节才算少呢?
就以我们某次首页的改版中,通过http analyzers我看到几个有趣的.js文件的URL,是这样的:
-
https://static.alipay.net/build/js/app/tracker.js?
v
=
083
-
https://static.alipay.net/build/js/home/home.js?t
=
20101012
-
https://static.alipay.net/build/js/pa/alieditcontrol-update.js?t
=
20101012
-
https://static.alipay.net/javascript/arale_v1.0.js
-
https://static.alipay.net/min/?b
=
javascript
&
f
=
arale
/lang/aspect.js,arale/lang/md5.js,arale/lang/uri.js,arale/lang/tmpl.js,arale/lang/date.js,arale/lang/number.js,arale/http/jsonp.js,arale/http/ajax.js,arale/http/core.js,arale/event/event-chain.js,arale/class/declare.js,arale/fx/animator.js,aralex/widget.js,aralex/tplwidget.js,aralex/view.js,aralex/tab/tab.js,aralex/dropdown/dropdown.js,aralex/slider/slider.js,aralex/slider/switchslider.js
注意最后一条。嗯,不要惊讶,的确是这样长的URL,确切的长度是443bytes。但这是长了呢?还是不算长呢?
要知道以IE为例,可以处理的URL长度为2048 bytes,也就是说,反正~~无论如何,IE是能处理的。其实,一般浏览器也没问题,所以,“正确性”是没问题。所以,接下来我们要说的是效率。
一、TCP/IP协议中的包头问题
在TCP/IP网络中,底层协议是一回事,应用层协议又是一回事。所以作为应用层协议的HTTP,自身可以传输多大的内容,以及如何传输(例如
HTTP包一般以48K为界限,超过48K时会出现应用层的分包,即所谓的multipart)这些都是由应用层来约定的。而在底层协议中,链路层与传输
层对“传多大的包”有各自的约定。简单的说,传输层约定了IP数据包的MSS(最大分段尺寸),链路层约定了MTU(最大传输单元)。如果一个IP数据包
的大小超过MTU(即MSS+TCP报头+IP报头>MTU),则在链路层会将IP数据包拆成多个信息包传输。
MSS与不同的传输环境相关,有两个推荐值。一般来说,
- 目标地址非本地地址(与源地址在不同一个网段)时,MSS默认值通常是536;否则,
- MSS默认值通常为1460。
MTU与网络环境相关,也有两个推荐值。一般来说,
- 串口为576字节;
- 以太网为1500字节。
MTU/MSS的两种推荐值中都有40个字节的差异,即是(TCP报头+IP报头)的一般值,该值以120
bytes为上限(20+20字节的IP/TCP头部;40+40字节IP/TCP可选头部)。所以在复杂的网络环境中,应用层的网络协议可用的单个数据
包的大小,最佳值应小于536-80=456字节,尽量限制在1460-80 =
1380字节以内。这样的限制,是综合考虑传输层与链路层协议的结果。不过一些常见的建议中,也会用536/1460这两个值,与这里的讨论没有太本质的
差异。我只是强调,如果我们要一个“足够优化的请求”,那么极限值应该是多少?
二、HTTP协议中的包头问题
那么,现在来到HTTP这个应用层协议。一个HTTP请求由头部与数据区构成,对于HTTP GET请求来说,可以只有头部而没有数据区,原因是HTTP头部的内容如下(头部需要以2个连续回车换行结束):
-
---------
-
GET (...) HTTP/1.1
-
Accept:*/*
-
Referer:http://www.alipay.net/
-
Accept-Language:zh-cn
-
User-Agent: (...)
-
Accept-Encoding:gzip, deflate
-
Host:static.alipay.net
-
Connection:Keep-Alive
-
Cookie: (...)
-
---------
这里的GET
(...)可以跟着一个完整的GET请求的URL,而GET请求的参数也都放在这个URL上,因此可以不需要有单独的数据区。在上述的这个HTTP请求
中,某些特定的客户端可能会多几个或少几个http head
field,但通常字段都会比较短。我们仅以这个例子来说明,那么这个“缺省的(不完整的)HTTP头”用掉了多少字节呢?
答案是184字节。不过还需要强调,Referer与当前正在浏览的网址直接相关,例如当前正在浏览的页面是500字节长的URL,那么当前网页上
的超链接点击时Referer字段都会填上这个500字节的URL,网页中过长的URL会使得点击超链接时消耗更多的传输,这里也是一例了。
那么不讨论Referer字段的影响,仅以上述为例,我们能用的最佳值,就只剩下了456-184=272字节了。这272字节会有三个地方使用,
就是上面标为(...)的三个地方:GET、User-Agent和Cookie。User-Agent这个字段与浏览器相关,不同的浏览器以及该浏览器
处理不同的操作系统环境时,都会出现不同。在JS以及服务器上的统计软件中,也常常使用这个字段来判断浏览器环境,例如OS、版本等。这个字段的值有时候
会比较长,以我当前的机器为例,该值为:
---------
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; QQWubi 108; EmbeddedWB 14.52 from:
http://www.bsalsa.com/
EmbeddedWB 14.52; .NET CLR 2.0.50727; InfoPath.2; .NET CLR
3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 1.1.4322; .NET CLR
3.5.21022; .NET4.0C; .NET4.0E)
---------
占用了274字节。也就是说,事实上理想环境下的使用456字节就已经不够用了。按此前讨论的,我们可以退而求其次:
- 使用536字节的边界值,即不考虑80字节的tcp/ip可选头部。
此外,需要强调的是User-Agent长度的可变性,例如上面的“EmbeddedWB……”等64字节在一般的电脑中可能就没有,这是一个第三
方组件。同样的,也可能因为其它的浏览器环境(例如傲游)导致这个字段更长。基于这个事实,我仍以本例中的这一特殊情况来做分析。
以536字节为例,我们事实上还有78字节可用,因此在这里我们将优化的第一等级设为:70字节。
建议公司可以根据服务器端收集的数据取一个平衡值。
三、COOKIE耗用可以降到0
现在,Cookie是消耗最大的地方,以我当前的机器为例,该值有几种情况(对于不同的协议与域,是不一样的):
(1) 对于首页
http://www.alipay.net/
,值有49字节:
ali_apache_id=12.1.11.70.1275978936200.5; lastpg=
(2) 对于
http://*.alipay.net/
,值有171字节:
ali_apache_id=12.1.11.70.1275978936200.5;
ali_apache_sid=12.1.46.46.128998714836.4|1289988948;
ALIPAYJSESSIONID=bYWcn4Wq0Z5FBCoHzfpn2f1XxDAmBepay;
ali_apache_tracktmp=uid=
(3) 对于
https://static.alipay.net/
,值有307字节:
cna=AKaaAhYBhU0BAeMdAHlnHNcd;
ali_apache_id=169.17.198.19.1272623861747.7; payMethod=directPay;
_tb_order=38016166656317; defaultBank=ICBC;
__utma=22931947.260433774.1277279158.1277279158.1282287558.2;
__utmz=22931947.1282287558.2.2.utmcsr=life.alipay.net|utmccn=(referral)|utmcmd=referral|utmcct=/index.php
(4) 对于http(s)://img.alipay.net/,值有379字节:
apay_id=159588238.127262386236866.128979461890689.1289969142342368.137;
cna=AKaaAhYBhU0BAeMdAHlnHNcd;
ali_apache_id=169.17.198.19.1272623861747.7; payMethod=directPay;
_tb_order=38016166656317; defaultBank=ICBC;
__utma=22931947.260433774.1277279158.1277279158.1282287558.2;
__utmz=22931947.1282287558.2.2.utmcsr=life.alipay.net|utmccn=(referral)|utmcmd=referral|utmcct=/index.php
(5) 其它情况。
为什么在2、3、4情况下出现了cookie使用的暴增呢?事实上,3、4两种情况虽然略有差异,但产生问题的根源与情况2是完全一致的。所以后文仅以情况2为例。跟踪其http request过程可知:
- 请求首页时,服务器端返回了四个set-cookie应答。
这四个应答(http response head)如下:
--------
Set-Cookie:ali_apache_sid=10.2.46.46.128998714836.4|1289988948; path=/; domain=.alipay.net
Set-Cookie:JSESSIONID=A8CE523AEA03E2C990D6796D6BAEC81E; Path=/
Set-Cookie:ALIPAYJSESSIONID=bYWcn4Wq0Z5FBCoHzfpn2f1XxDAmBepay; Domain=.alipay.net; Path=/
Set-Cookie:ali_apache_tracktmp=uid=; Domain=.alipay.net; Path=/
--------
所以在此后的所有http请求中,都将使用如前例(3)中的171字节的cookie。但是,显然的,至少有以下几种情况这些cookie是无意义的:
- 如果访问的是重定向页面,包括返回Status Code:302的重定向,以及html页面中使用http-meta的重定向;
- 如果访问的页面是被缓存的,例如返回Status Code:304的“Not Modified”;
- 如果访问的页面是静态的、无需识别cookie的,例如static.alipay.net中的.img、.js和.css文件等。
显然,我们在img、static中的图片或其它静态资源是可以被缓存的,而且无论是缓存还是第一次存取,cookie值都完全没有意义。对于静态
页面(.html)来说,如果我们不是要通过http
server来统计分析静态页面的访问情况,那么这些cookie也是不需要的。所以,对于这些资源、内容,我们应该强调的使这些cookie不被发送,
或尽量少的使用(对于部分的.html静态页,我们可能仅仅需要用于分析用户访问链的session id)。
优化cookie的方式很简单:将这些静态资源部署在不以.alipay.net为domain的服务器/组里,或使用其它的独立域名。这种情况下,对于特定的——当然也是最大量的一部分——资源,COOKIE耗用可以降到0。
四、缩短url
总算来到我们的正题:URL可以有多长?通过前面的分析,我们仍然还有70字书可以用,即使在特定条件下,我们需要给一些页面访问留下track数据(例如session),那么我们仍然有40~50个字节可以用
。不过,仅此而已,我们离本文最开始提到的443 bytes仍然有相当相当长的距离。
但我们真的需要这么长的URL吗?
答案是不需要,我们完全可以缩短URL。例如前面的例子,我们原始的URL的get部分是:
-
---------
-
/min?b
=
javascript
&
f
=
arale
/lang/aspect.js,arale/lang/md5.js,arale/lang/uri.js,arale/lang/tmpl.js,arale/lang/date.js,arale/lang/number.js,arale/http/jsonp.js,arale/http/ajax.js,arale/http/core.js,arale/event/event-chain.js,arale/class/declare.js,arale/fx/animator.js,aralex/widget.js,aralex/tplwidget.js,aralex/view.js,aralex/tab/tab.js,aralex/dropdown/dropdown.js,aralex/slider/slider.js,aralex/slider/switchslider.js
-
---------
仔细观察,它的意思其实是
---------
/min?b=javascript&f=...
---------
字段f后面的,其实是arale这个脚本项目中的一些静态资源的拼接。在服务器端,min这个程序根据参数"b=javascript&
f=..."将一些脚本碎片拼接成一个单独.js文件并返回到浏览器,如果没有变化,则直接返回Status Code:304。
那么,事实上我们每次请求的“f=...”字段后面的参数块将会是完全一样的。或者,即使在不同的情况下要求拼接的文件列表不一样,也仅有相当有限
的组合。这使我们自然的想到一个东西:求和。用这种方式对上述的字符串求一个key(例如hash、md5、crc),然后我们就可以用这个唯一key来
查找拼接后的.js内容——这也意味着min程序不需要每次都拼接文本。这样一来,上面的URL可以变成(以对f字段后的396字节求crc32为例):
---------
/min?b=javascript&f=313466DB
---------
考虑到不同的版本管理:
---------
/min?b=javascript&v=0.9b&f=313466DB
---------
现在,我们将URL控制在了一个相当小的规模,而且加上了版本管理和内容的有效性验证,需要的情况下,服务器端的min程序也可以做动态生成以及缓存。这些改造与我们原始的需求并没有任何的冲突。重要的是,我们成功地将get请求控制在了35字节,余留的空间完全满足我们
整体优化的需要:第一等级的优化,70字节!
五、技术成熟性与价值
1、twritter中早就使用这样的技术了。
2、与arale项目类似的,YQL(Yahoo! Query Language)项目也有类似的需求,因此他们将“在URL上传入一个sql”通过上述技术变成了一个短名,例如:
http://y.ahoo.it/iHQ8c0sv
相当于
http://developer.yahoo.com/yql/console/?q=select%20woeid%20from%20geo.places%20where%20text%3D%22san%20francisco%2C%20ca%22
3、微软还“傻傻说不清楚”,所以你看他们的官网很慢。^^.
4、当我们有条件将http头部减小到456字节以下时,应尽力为之。例如旺旺因为有独立客户端,所以可以定制http request head,以缩减User-Agent等字段。
5、当我们总是从浏览器端发出最小化的HTTP请求时,网络总是可以最快速的将请求提交到服务器,无需等待多个包并组合。这在慢速网络,以及存在大
量丢包的网络中效果将为极为明显。简单地说,如果有人在局域网中用迅雷或BT,那么最小化HTTP请求将会使网页的浏览体验提升得相当相当明显。
6、我们应该做脚本等静态资源的版本管理了。
原文地址:http://blog.csdn.net/aimingoo/archive/2010/12/17/6081964.aspx
分享到:
相关推荐
- `视频教程大全.url`、`电子书大全.url`、`更多给力作品.url`:这些可能是相关学习资源的快捷方式。 通过整合这些资源,开发者可以逐步构建并调试一个完整的"JS抽奖转盘效果",为用户提供互动性强且吸引人的抽奖...
7. **URL书签**:`视频教程大全.url`、`电子书大全.url`和`更多给力作品.url`看起来像是指向资源的快捷方式或书签,可能是为了方便用户访问相关的学习资料或开发者其他作品。 8. **响应式设计**:为了确保在不同...
6. **链接资源**:`.url`文件是快捷方式,`视频教程大全.url`、`电子书大全.url`和`更多给力作品.url`可能是提供进一步学习资料或开发者其他项目的链接。 7. `images`文件夹通常存储项目中使用的图像资源,如图标、...
- `更多给力作品.url`:可能是作者其他项目的链接,展示其更多的开发成果。 - `js`:这可能是插件的核心JavaScript文件,包含了实现城市三级联动逻辑的代码。 通过研究`demo.html`和`js`文件,可以了解插件的具体...
2. 视频教程大全.url、电子书大全.url、更多给力作品.url:这些可能是链接到相关学习资源或作者其他作品的快捷方式,帮助用户获取更多关于Web开发和特效制作的知识。 3. js:这个文件可能包含实现3D标签云特效的...
5. **链接资源**:`视频教程大全.url`、`电子书大全.url`和`更多给力作品.url`看起来是快捷方式文件,可能指向与Google搜索相关的在线教程或其他资源。这些链接可以作为学习和深入了解的起点。 6. **图片处理**:`...
另外,“电子书大全.url”和“视频教程大全.url”可能是提供相关学习资源的链接,而“更多给力作品.url”可能指向作者的其他项目或作品集。 总的来说,这个项目展示了HTML5和jQuery结合3D设计的能力,为网页开发者...
`index.html`可能是展示收款二维码和相关操作的网页文件,而`.url`文件通常用于创建快捷方式,指向特定的网址,如`爱Q生活网.url`和`给力么-天猫优惠券.url`可能是与收款码服务相关的网站链接,可能提供了更多关于...
而“更多数据库脚本.url”和“更多给力作品.url”可能是其他相关数据库脚本或开发者的作品集,供进一步参考和学习。 在实际应用中,实现四级联动通常需要考虑以下几点: 1. 数据库设计:合理规划表结构,可能包括省...
`视频教程大全.url`、`电子书大全.url`和`更多给力作品.url`可能是指向相关学习资源的快捷链接,帮助用户进一步了解Jquery和日程管理的开发;`css`、`images`和`js`文件夹则包含了插件所需的样式表、图像资源和...
至于“给力技术.url”,这通常是一个快捷方式文件,指向一个关于jQuery Textarea插件的在线资源,如开发者的博客、教程或者示例页面。通过打开这个URL,我们可以获取更多的使用指南、示例代码以及可能的更新信息。 ...
`视频教程大全.url`、`电子书大全.url`和`更多给力作品.url`看起来是链接到其他资源,可能对学习jQuery分页有所帮助。 总的来说,使用jQuery实现数据动态加载分页需要结合前端和后端的知识,通过监听用户滚动事件、...
4. **更多给力作品.url**:这个链接可能指向该开发者或团队的其他项目或作品集,展示他们使用CSS3创建的各种视觉效果或网页设计。 5. **css**:这是一个文件夹,可能包含了用于demo.html的CSS3样式文件,用户可以...
另外,`.url`文件通常是快捷方式文件,这里出现的`视频教程大全.url`、`电子书大全.url`、`更多给力作品.url`可能是指向相关的教学资源或作者其他作品的链接。这些链接可以帮助我们进一步学习浮动导航的实现技巧,...
【标签】"给力的扥啊看看扥了看" 这个标签似乎没有提供太多具体的信息,"给力"通常用来形容某事物效果显著或非常有用,可能是指这个压缩包中的资源非常实用。而"扥"在这里可能是个误打或者拼写错误,没有明确的含义...
`video教程大全.url`、`电子书大全.url`和`更多给力作品.url`可能是链接到其他资源的快捷方式,它们与瀑布流布局和图片预加载直接关系不大,但在实际项目中可能提供额外的学习材料或作品展示。 总的来说,瀑布流+...
`视频教程大全.url`和`更多给力作品.url`可能是相关教程或作者其他项目的链接,供学习者进一步探索。 实现这个特效需要熟悉jQuery的基本用法,以及如何结合HTML和CSS构建动态、交互式的Web界面。通过实践这个项目,...
在本例中,`视频教程大全.url`、`电子书大全.url`、`更多给力作品.url`可能是指向相关学习资源或作者其他项目的链接,方便用户进一步学习和探索。 总的来说,这个压缩包提供了一个完整的HTML5视频播放器实现,包括...
文件列表中的“demo.html”可能是一个包含以上功能的实际示例网页,而“视频教程大全.url”、“电子书大全.url”、“更多给力作品.url”看起来可能是链接到相关学习资源的快捷方式。另外,“images”目录可能包含了...
5. `视频教程大全.url`、`电子书大全.url`、`更多给力作品.url`:这些可能是指向相关学习资源的快捷方式,帮助用户进一步了解jQuery和前端开发的相关知识。 要实现"jquery弹出层特效",首先在HTML文件中引入jQuery...