网页优化之DNS和页面预拉取
网站优化之预拉取分作两个方面来讨论,一个方面是页面元素的预拉取,一个方面是DNS的预拉取。
一 首先来说说DNS的预拉取
DNS 实现域名到IP的映射。通过域名访问站点,如果DNS信息不在缓存中话,每次请求都要做DNS解析。目前每次DNS解析,通常在200ms以下。针对DNS解析耗时问题,一些浏览器通过DNS 预拉取 来提高访问的流畅性。
DNS 预拉取是一种DNS 预解析技术,当你浏览网页时,浏览器会在加载网页时对网页中的链接或者link中的href的域名进行解析缓存,整个操作是并行地运行在后台,不会影响当前的用户体验;这样在用户真正单击当前网页中的连接时就无需进行DNS的解析,减少用户等待时间,提高用户体验。
不仅客户端可以通过配置项来控制是否开启DNS缓存,服务器也是可以控制的,通过HTTP协议头部增加x-dns-prefetch-control为on或者off或者直接在页面中通过meta信息来进行控制:<meta http-equiv="x-dns-prefetch-control" content="off">
对于网页开发者而言,可以通过link标签来强制对某一个域名进行DNS的预拉取:
<link rel="dns-prefetch" href="http://www.qq.com/">
Firefox的话,可以通过about:config中的network.dnsCacheEntries和network.dnsCacheExpiration 来调整DNS缓存的大小和过期的时间。默认的过期时间是60秒。
Firefox的DNS缓存设置插件:
https://addons.mozilla.org/zh-CN/firefox/addon/5914/
目前支持 DNS Prefetch 的浏览器有 google chrome 和 firefox 3.5
对于chrome而言,可以通过about:histograms 命令,查询DNS.PrefetchQueue可以看到相关的dns缓存的情况。
参考文档:
https://developer.mozilla.org/En/Controlling_DNS_prefetching
备注:
IE浏览器4.x以后的版本,DNS缓存默认的时间是10分钟,可以通过修改注册表来达到修改这个默认缓存时间。
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings
在编辑菜单上,单击添加数值,然后添加以下注册表值:
数值名称:DnsCacheTimeout
数据类型:REG_DWORD
基数:十进制
数值:(以秒为单位的时间)
二 页面元素预拉取
用户在打开首页后,如果停留较长时间,而且根据统计得知用户进入某些个二级页面的概率很高,如在x.soso.com这样的站点,从首页到某一个电影的详情页,这样的概率是很高的。
如何在首页或者网站入口的地方,为后面的一些常常需要访问的页面做一些后续页面元素预拉取操作呢,通过预拉取提高后续页面的访问速度。
对于firefox而言,页面元素的预拉取变得比较简单一些,通过link标签或者meta标签就可以实现预拉取:
<link rel="prefetch" href="/images/big.jpeg"> 通过将rel的值设置为prefetch或者next就可以进行预拉取。
<meta http-equiv="Link" content="/images/big.jpeg; rel=prefetch">
Firefox浏览器会判断当前页面空闲的时候才会去拉取指定的预拉取的元素,而且对于预拉取的元素也会带上当前页面作为引用页(避免一些防盗链设置),和添加一些特定的http头部X-moz: prefetch便于服务器进行标识。
<html>
<head>
<title>firefox prefetch</title>
<link href="http://ime.qq.com/fcgi-bin/getword?key=0f2bff76ec96181f1078250ba3e8245f&cb=window.QQWebIME.callback402&q=fgh&p=5" rel="prefetch"></link>
<meta http-equiv="Link" content="http://articles.csdn.net/uploads/allimg/100928/100QK645-0.jpg; rel=prefetch">
</head>
<body>
firefox prefetch test
<p>
normal image<br/>
<img src="http://img.cnbeta.com/newsimg/100924/11502901065691984.jpg"></img><br/>
</p>
</body>
</html>
Firefox下通过about:cache?device=disk命令可以实时查看到页面元素的缓存情况,模仿上面的例子你就会看到在firebug下抓不到包的请求,这里会有缓存的。
参考文档:
https://developer.mozilla.org/en/Link_prefetching_FAQ
IE下的一些插件如IE Pro可以实现累死的预拉取的功能:
http://www.downloadsquad.com/2008/05/20/ie7pro-2-3-adds-prefetching-session-management-to-internet-expl/
Chrome的一些插件也可以实现类似的功能:
https://chrome.google.com/extensions/detail/lcgjcablhbecaaheaiebnjingaocdmdf
总结:
对于预拉取而言,都会额外的耗费一些带宽,只有在有必要的时候才去实施。如qzone这种会弹出一个引导页面的时候,可以做一些用户博客元素的预拉取;另一方面,国内的浏览器大多还是ie,这种情况下通过一些简单的标记是很难实现预拉取的,这时需要通过js在业务层来实现预拉取,一般而言,最好是通过js来判断当前页面已经onload完毕,然后通过new Image的方式来预拉取一些想要拉取的元素。如果有必要,尽量将这种预拉取的操作放到清晨或者夜深的时候才来做。
DNS的预拉取在手机上来实现是比较好的,手机上打开页面的速度比较慢,正好可以并行的来进行预拉取的动作。
页面元素的预拉取对于一些页面元素相对较多,如很多CSS和JS文件、大的图片文件的时候以及一些常用页面里面一些变动比较大的页面元素的时候,这个时候进行预拉取的效果会更好一些。如果用户不需要的话,毕竟预拉取会浪费用户和服务器的带宽。
最近遇到的怪事越来越多,之前是因为在页面内嵌javascript代码中的一段小小的注释引来的xss漏洞。昨天又遇到一个javascript代码考虑不周导致的不停刷新页面的情况,如果这个页面被别人发现了,很容易就会导致站点的ddos攻击。
网站的很多登录操作最终都会转到一个页面去统一处理,这个页面根据传入的参数的不同,然后跳转到对应的页面去。如果这个跳转页面的js没有判断好要跳转过去去的页面是不是自己。
一些用户就会将跳转的页面设置为这个页面,将导致这个页面不停的在自身进行跳转,不停的刷新。如果规模过大的话,这个攻击就变得很强大了。
所以在写js代码的时候还是要多多考虑一些边界的条件,js代码也会攻击的。例如,下面这段代码,如果前面增加一些输入的判断,不小心判断出错,让自己跳转到自己的话,该页面不停的刷新自己,麻烦就到了。
<html>
<head>
<title>location auto reload</title>
</head>
<body>
location auto reload
<script type="text/javascript">
var url = window.location.href;
window.location.reload(url);
</script>
</body>
</html>
呵呵,注意一下location这个对象:
Location 对象的 reload() 方法可以重新装载当前文档,replace() 可以装载一个新文档而无须为它创建一个新的历史记录,也就是说,在浏览器的历史列表中,新文档将替换当前文档。
Location 对象属性
属性
描述
IE
F
O
hash
设置或返回从井号 (#) 开始的 URL(锚)。
4
1
9
host
设置或返回主机名和当前 URL 的端口号。
4
1
9
hostname
设置或返回当前 URL 的主机名。
4
1
9
href
设置或返回完整的 URL。
4
1
9
pathname
设置或返回当前 URL 的路径部分。
4
1
9
port
设置或返回当前 URL 的端口号。
4
1
9
protocol
设置或返回当前 URL 的协议。
4
1
9
search
设置或返回从问号 (?) 开始的 URL(查询部分)。
4
1
9
Location 对象方法
属性
描述
IE
F
O
assign()
加载新的文档。
4
1
9
reload()
重新加载当前文档。
4
1
9
replace()
用新的文档替换当前文档。
4
1
9
在我们的页面中,如果不是显示指出来的话,javascript是同步加载的,也就是javascript的加载是阻塞的,后面的元素需要等待javascript加载完毕后才能进行再加载。呵呵,对于一些意义不是很大的javascript,如果放在页面的头部,如果加载很慢的话,会严重影响用户的体验的。
有人会问这时为什么呢?因为有可能你的javascript代码会动态的植入一些元素到页面的dom中。
因此对于那些会有修改dom的javascript(最简单如里面会有document.writlen这样的语句),我们只能阻塞的加载,而且最好也是放在页面的最底部。但是对于那些不会导致dom修改的javascript,如一些统计的javascript,如google的统计等,我们完全可以异步的来加载,不必同步阻塞的来等待。如何异步加载一个javascript文件呢?
一 defer方式
在w3c的html中定义的script标签有一个defer的属性,这个属性开启的话表示这段javascript代码可以延迟加载。
<!ELEMENT SCRIPT - - %Script; -- script statements -->
<!ATTLIST SCRIPT
charset %Charset; #IMPLIED -- char encoding of linked resource --
type ...
我们写的javascript不一定都能保证是没有问题,可能在某些特殊的环境下,后者某些浏览器上,某些用户的cookie环境等导致javascript代码执行出错。这个时候我们需要知道javascript代码执行有问题,从而在下一个版本中解决这个问题。
怎么来发现我们的javascript代码有问题呢,通过damnit网站提供的工具可以方便的解决这个问题。
1 在ie和firefox下onerror这个事件,当javascript代码执行出错的时候,会触发这个事件,我们添加这个事件的处理函数,在处理函数里面添加上报即可。
如果需要利用 onerror 事件,就必须创建一个处理错误的函数。你可以把这个函数叫作 onerror 事件处理器 (onerror event handler)。这个事件处理器使用三个参数来调用:msg(错误消息)、url(发生错误的页面的 url)、line(发生错误的代码行)
onerror=handleErr
var txt=""
function handleErr(msg,url,l)
{
txt="There was an error on this page.\n\n"
txt+="Error: " + msg + "\n"
txt+="URL: " + url + "\n"
txt+="Line: " + l + "\n\n"
txt+="Click OK to continue.\n\n"
alert(txt);
return ...
Cookie是什么,估计搞了很久的web开发人员也会很困惑,path是什么意思,secure是什么意思,时间是什么意思....
我也是困扰了很久。cookie到底是什么?使用的过程中需要注意一些什么?经过一番折腾之后,终于忍不住开完了rfc的英文文档,事情终于解决了,一切恢复了平静。且让我慢慢到来,cookie到底是什么。
通过抓包可以比较方便的看到一次服务器端返回的cookie的样子:
Set-Cookie:customer=test; path=/; domain=test.com; expires= Wednesday, 19-MAY-10 23:12:40 GMT; [secure];
其中每个属性的解释:
customer=test; 这个键值对表示的是想要传递的信息,键叫做customer,值是test
domain: 关联的域名,例如www.qq.com, 它的domain = test.com,该domain默认为当前请求的域,但是如果cookie中domain的值和请求的域不相符的话,这个cookie就会被忽略.
path: 控制哪些网站上目录的访问能触发发送.例如请求的地址是上面的URL,如果path=/,这个cookie就会被发送,但是path为其他的话,该cookie会被忽略.
expires: cookie的过期时间,这里的时间是GMT格林威治时间,不是我们中国当前的时间哦,GMT加上8个小时就是我们的中国的北京时间了。如果没有明确填写这里的话,表示这是一个会话cookie,只是在浏览器的一次回话中有用,一旦浏览器关闭这个cookie就不存在了,很多登陆使用到cookie会使用会话cookie。expires还有一个用处就是在服务器想要清除一个cookie的时候,只需要设置expires为当前时间之前的一个时间,如设置为1970年,这样的话浏览器就会把cookie清除掉了,因为已经过期。
secure: 如果secure 这个词被作为Set-Cookie 头的一部分,那么cookie 只能通过安全通道传输(目前即SSL通道)。否则,浏览器将忽略此Cookie,这里一般是在https时才有用。
看看rfc中对cookie中的几个字段的详细解释吧:
set-cookie = "Set-Cookie:" cookies
cookies ...
在众多的网站优化手册中,你会听到很多这样的说法,有的说要开启服务器的etag,有的说不要。
但是很少有人说不开启 Last-Modified,这是为什么呢,ETAG和Last-Modified之间又有什么关系呢。
Etag和Last-Modified都是有服务器端生成,并且随着文件的改变而改变,这样浏览器端就会只重新请求时,服务器会根据之前返回的etag值和last-modified的值来判断请求的文件是否发生变化,
如果没有变化的话,就给请求的agent(一般理解为浏览器)一个304的http头部,not modified的回应,告诉agent说你本地的文件还是新的,目前服务器还没有变更,你就拿本地的来用吧。从而减少浏览器端和agent端数据的流量(想想如果每次请求都返回完整的内容,当访问量大的时候,流量的有多大),加快浏览器的反应速度;另一方面,也减轻服务器端的压力,提高了服务器并发的能力。所以服务器端Etag和last modified配置上都比较重要。
呵呵,那么etag和last modified之间有什么不同点呢?
任何东东的出现都是有原因的,last modified只能精确到秒,如果一个文件1秒内被改了好些次,那么last moidfied就没有用了;再或者分布式部署的时候,由于机子的时钟有可能不一样,用户从一台机子到另外一台机子的时候,last modified就没有用了。于是etag这个类似基于文件唯一标识的hash的就出现了,这样的话,不管你服务器怎么变化,不管你1秒变化多少次,只要唯一标识的hash不变,文件不变。
一般而言,etag是根据文件的innode(文件的索引节点值)以及mtime(文件修改时间)以及size(文件大小)三个部分组成。但是这里也还是有点问题的,因为不同的服务器上,文件的innode节点有可能是不一样的,所以在配置的时候需要小心,根据自己系统的特点选择唯一的标识。但是在集群服务器上,这个是很难实现的,于是乎就有的网站优化手册里建议你关闭etag这个选项,也是有道理的。不过明晰事情的真相后,自己也可以根据自己的业务特点来使用了。
呵呵,有的服务器etag和last modified都使用了。那么web服务器处理这两个条件的优先级如何呢?(这个估计很少人去追究了)
通过跟踪了一下apache1.3的源码,得知etag的优先级高于last modified。呵呵,所以yahoo的优化法则上说关闭etag,不无道理晒。
看看apache的源码,让你来个明白:
关注加黑部分,其它的都是一些参数检查和配置检查。
int set_last_modified(request_rec *r, time_t mtime)
{
char *etag, weak_etag[MAX_STRING_LEN];
char *if_match, *if_modified_since, *if_unmodified, *if_nonematch;
time_t now = time(NULL);
if (now < 0)
now = r->request_time;
table_set(r->headers_out, "Last-Modified",
gm_timestr_822(r->pool, (mtime > now) ? now : mtime));
/* Make an ETag header out of various pieces of information. We use
* the ...
网站优化之优雅整洁的CSS代码
整洁优雅的代码读起来让人赏心悦目,同时在重构和维护的过程中也你能让人得心应手。
优雅的代码能够体现一个 程序员的素质以及架构考虑方面的技巧。
1 文件组织
全局样式,如body、p、a以及字体、背景色等,这里针对的是全局的html标签的样式的定义。
类样式,如.Pagetitle,.Warning,对于站点页面中多处出现的元素的抽象,如一个警告文本这样的。
<!--HTML--><p class="warning">出错信息提示</p>
布局样式,如#container、#header、#content等,主要是页面的主体布局框架的元素的一些样式,对于布局而言,由于较少变化,所以尽量使用ID来标识这些元素。如
<div id="container">
<div id="header">
<div id="navigation"></div>
</div>
<div id="content"></div>
</div>
#container { }
#container #header{ }
#container #header #navigation { }
页面样式,具体一个页面元素的样式。由于布局已经确定了,剩下到每个单独的页面了,每个单独的页面由于有自己的一些独特呈现的需要,所以需要为每个页面的指定一个样式
2 具体的一些操作细则
全局样式使用reset.Css,可以参考Yahoo Reset CSS, Eric Meyer’s CSS Reset, Tripol
使用缩略的css样式,一方面节约空间,同时可读性也好一些。
.header {
background-color: #fff;
background-image: url(image.gif);
background-repeat: no-repeat;
background-position: top left;
}
.header {
background: #fff url(image.gif) no-repeat top left
}
制作一个圆角边框
[caption id="" align="aligncenter" width="380" caption="css圆角边框"][/caption]
类名一定要有语义,一定要能够抽象适应未来的变化
建议改成warning或者其它什么的,如果那天需要变成了其它颜色呢?
让字体交给css来处理吧,如大小写这样的东西,将变化交给css去完成。
[caption id="" align="aligncenter" width="490" caption="css控制文本大小写 "][/caption]
参考文档:
1 http://www.smashingmagazine.com/2008/11/12/12-principles-for-keeping-your-code-clean/
2 http://www.hongkiat.com/blog/20-useful-css-tips-for-beginners/
网站优化之优雅整洁的HTML代码
一个程序员不仅要实现功能,还要做的是写出优雅整洁的代码。这样在自己后来阅读以及交接给别人的时候才能够将工作量降到最小化。
优雅整洁的代码的核心就是------尽量将自己的代码语义化!
1.别忘记头部的声明,它会告诉浏览器如何渲染你的HTML。
2.设置title,字符集.将CSS和JS外链(包括一个打印用的CSS)。
3.给body一个ID。这里作者提到的原因是,为多页面的中容器选择提供便利。比如通过给page1和page2中BODY设置不同的ID,就可以通过#page1 h2和#page2 h2来设置两种不同的效果,我感觉这个到是要看情况和具体架构再具体使用。
4.编写符合语意的菜单代码。
<ul id="menu">
<li><a href=../../"index.php">Home</a></li>
<li><a href=../../"about.php">About</a></li>
<li><a href=../../"contact.php">Contact</a></li>
</ul>
5.要有一个主体DIV包含所有的内容。方便固定主体的宽度,边距等等。
6.先写主要内容,再写次要内容.如果你的导航或者侧边栏不是很重要,最好将他们写在最后。(浏览器会根据先后顺序来渲染DOM)
7.将导航,页尾等公用的部分用动态调用的方式引入,比如PHP的include,web服务器的SSI,这样的话更改一个地方就能更改整个站点,如遇到特殊事件时就能全站方便的变黑等。
8.缩进代码.不要用tab,用4个空格来缩进标签;或者tab需要说明好是几个空格。
9.标签一定要结束
10.在合适的地方使用标题标签,如<h1>~<h6>,来划分段落。
11.最后一点,也是最重要的一点。
不要把样式写在标签上,HTML只是用来表示结构。表现还是交给CSS吧。
[caption id="" align="aligncenter" width="570" caption="html代码规范"][/caption]
后续会再整理一些优雅整洁的css、javascript代码是什么样的。
原文http://css-tricks.com/what-beautiful-html-code-looks-like/
附加:
1.注意标签间的正确嵌套
<a href="test.html"><h1>test</h1></a>标签a是inline的,h1是block的,应该把h1放在外层才对
<h1><a href="test.html>test</a></h1>
2.去掉无用的标签
<div id="nav">
<ul class="nav"><li>test</li></ul>
</div>其中这个div就是多余的了
3.使用合适的DTD,目前div的布局的话建议使用strict的DTD
4.尽量转义html字符,如&,@这样的字符.
如<title>我&你</title>转换成<title>我&你</title>
网站优化之网站图标网站头像favicon.ico制作
现在很多浏览器都会在地址栏、收藏栏、tab页上面显示一个网站的图标。这个图标就是你站点根目录下的favicon.ico文件。这是浏览器默认的动作,通过抓包工具可以很明显的看到,如tt浏览器,没有缓存的情况下,打开页面的时候就回去get一下/favicon.ico。
当然也可以显示去指定,这样的话可以控制ico图片所在的路径,以及这个图片的格式。在html文件中加入如下的代码就好了:
<link rel="shortcut icon" href="你ico图片的url">
如何方便的来制作这个网站图标呢,参考如下的一些在线制作的工具,可以省去很大一部分的工作:
国产 制作ico图标 不过生成的ico文件稍微有一点大。
国外 制作ico图标 效果好一些。
更多参考和推荐
车东的博客还带有图片展示的,可以去看个究竟哦。
备注:
1 上传了ico到你的网站的根目录下后,如果通过地址获取的时候提示你保存的话,说明你的服务器不支持这种类型的mime-type,需要修改一下服务器的配置。
如lighttpd,在mime-type配置下,增加:
“.ico” => “image/x-icon”,
还不行的话,打开这个选项:mimetype.use-xattr = “enable”
2 对于很多服务器的设置都没有明显的针对ico类型的文件来设置过期时间的,由于ico文件很少进行变化,需要将其过期时间设置长一点。我的是一年。
lighttpd中修改配置如下:
$HTTP["url"] =~ “\.ico$” {
expire.url = ( “” => “access 1 years” )
}
3 如果你刷新了浏览器还是看不到你的网站图标的话,你需要清空一下浏览器的cache。重启浏览器试一下。
追加说明:
1 如果你没有设置favicon而且有空的话,看看你的web服务器的error log,你会看到大量的404请求,都是请求这个图片的。
所以加上这个 ...
网站优化之wordpress站点性能优化
对于偶们这些无钱购买大带宽、高性能服务器的同志来说。使用一个国外的性能差的vps,流量、网速的限制促使我们不得不对自己的小小站点进行优化。
让其能够稍微快一点的展现在访问者面前,对于web站点来说,速度是第一位的,其它都是第二位的。
所以对网站的优化就像呼吸,不能停止!
对于wordpress站点来说,优化的核心和重点主要就是静态话,减少页面元素的数量。呵呵,两者做到了,速度就上去了。
优化过程如下,不断更新中:
一 gzip
http://redmine.lighttpd.net/wiki/1/Docs:ModCompress
php:(这里需要注意php.ini的位置)
zlib.output_compression = On
zlib.output_handler = On
lighttpd:
compress.cache-dir = “/var/www/cache/”
compress.filetype = (”text/plain”, “text/html”)
二 expire
expire.url = ( “/wp-content/” => “access 1 years”,
“/wp-includes/” => “access 1 years”)
$HTTP["url"] =~ "\.(html|htm)$" {
expire.url = ( "" => "access 4 hours" )
}
#对于后台管理的目录也不放过:)
$HTTP["url"] =~ "^/wp-admin/" {
expire.url = ( "" => "access 1 years" )
}
三 静态化
安装cos-html-cache插件,使得站点的页面静态化
配置lighttpd支持404的处理
server.error-handler-404 = “/index.php”
四 合并css以及js文件
通过firebug或者fiddler来抓包,分析css和js加载的顺序,将这些css并入到一个文件中,然后通过css整理工具,将其中的无用的字符如空格、回车换行等信息去掉。
css整理工具,csscompressor:
css整理工具,csscompressor
工具使用和相关信息参考我的博客:
css压缩工具 网站优化
js整理工具,jsmin.
然后修改主题模板对应的header-default.php
将原来导入css和js的地方替换为新生成的js和css
五 ...