<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Thinking for Fun &#187; HTML</title>
	<atom:link href="http://jsfox.cn/blog/tag/html/feed" rel="self" type="application/rss+xml" />
	<link>http://jsfox.cn/blog</link>
	<description>网络 ● 生活 ● 技术</description>
	<lastBuildDate>Tue, 01 Jun 2010 01:52:41 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>理清URL编码</title>
		<link>http://jsfox.cn/blog/learning/understand-url-encodin.html</link>
		<comments>http://jsfox.cn/blog/learning/understand-url-encodin.html#comments</comments>
		<pubDate>Mon, 31 May 2010 11:05:23 +0000</pubDate>
		<dc:creator>yongbin</dc:creator>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Browser]]></category>
		<category><![CDATA[charset]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[编码]]></category>

		<guid isPermaLink="false">http://jsfox.cn/blog/?p=187</guid>
		<description><![CDATA[URL中，什么字符需要编码？
关于URL编码，RFC1738做了如下的规定：
&#8220;Only alphanumerics [0-9a-zA-Z], the special characters &#8220;$-_.+!*&#8217;(),&#8221; [not including the quotes - ed], and reserved characters used for their reserved purposes may be used unencoded within a URL.&#8221;
RFC继而说明了保留字、特殊符号、不安全字符的含义——也就是说，下面三类字符可以不经过编码，直接出现在URL上：

[0-9a-zA-Z]
特殊字符：$-_.+!*&#8217;(),
保留字符：&#38;/:;=?@

为了让我们思路更清晰，我们再总结一下，哪些字符必须要编码：

ASCII表中没有对应可显示字符的，例如汉字
不安全字符，包括：#&#8221;%&#60;&#62;[]{}&#124;\^`~
不当做保留字符来使用的保留字符，即&#38;/:;=?@


详见这张图，一目了然（点击看大图）：
如何编码？
众所周知，字符是可由八位字节数（octet）来表示的，八位字节数可用十六进制来表示它的值。如字符“&#60;”的八位字节数十六进制值是3C。在URL中，字符的编码方式为：“%”加上字符的两个十六进制数值。举几个例子：

“&#60;”可以被编码为%3C，空格“SP”可被编码为“%20”
“田”的GB2312编码十六进制值是CC EF，这时“田”的URL编码为%CC%EF
“囧”的GBK编码十六进制值是87 E5，这时“囧”的URL编码为%87%E5
“田”的UTF-8编码十六进制值是E7 94 B0，这时“田”的URL编码为%E7%94%B0

URL中包含汉字时的更多话题
RFC1738没有规定汉字的编码方式，而是让浏览器自己去决定，因此造成了URL汉字编码的不统一。经过研究，对于URL中的“查询字符串”和“路径”中包含汉字，不同浏览器有不同的处理。
1. 查询字符串中包含汉字
在网址输入：http://www.baidu.com/s?wd=田囧 ，敲击回车，使用Fiddler观察浏览器发出的请求（以IE8和Firefox为例）：
IE8将汉字作为GBK编码，直接发往服务器（这其实是不符合RFC规范的）；Firefox则多了一次加%的操作。Windows操作系统是GBK编码。得到结论，地址栏直接访问URL，汉字作为查询字符串(Query string)时，IE和Firefox会使用系统编码发至服务器端，Firefox会按规矩编码。
注意1：不要用Google进行测试，Google的搜索URL（类似：http://www.google.com/#hl=en&#38;source=hp&#38;q=田囧 ），搜索关键词那里不是查询字符串，因为前面有个#……我开始没注意到，被搞迷茫了很久……
注意2：这只是对URL直接访问的规律。如果页面时从链接点击打开的，例如从A页面含中文的链接打开了B页面，那么浏览器对中文的编码取决于A页面的编码。
2. URL路径中包含汉字
在网址直接输入：http://www.hudong.com/wiki/田囧 ，敲击回车，观察请求：
IE8和Firefox都把汉字作为UTF8，按规范进行了URL编码，还好。
总结
什么字符应该编码，什么字符不用编码，URL编码的基本问题，到此已经解决啦。
]]></description>
			<content:encoded><![CDATA[<h2>URL中，什么字符需要编码？</h2>
<p>关于URL编码，<a href="http://tools.ietf.org/html/rfc1738">RFC1738</a>做了如下的规定：</p>
<blockquote><p>&#8220;Only alphanumerics [0-9a-zA-Z], the special characters &#8220;$-_.+!*&#8217;(),&#8221; [not including the quotes - ed], and reserved characters used for their reserved purposes may be used unencoded within a URL.&#8221;</p></blockquote>
<p>RFC继而说明了保留字、特殊符号、不安全字符的含义——也就是说，下面三类字符可以不经过编码，直接出现在URL上：</p>
<ul>
<li>[0-9a-zA-Z]</li>
<li>特殊字符：$-_.+!*&#8217;(),</li>
<li>保留字符：&amp;/:;=?@</li>
</ul>
<p>为了让我们思路更清晰，我们再总结一下，哪些字符必须要编码：</p>
<ul>
<li>ASCII表中没有对应可显示字符的，例如汉字</li>
<li>不安全字符，包括：#&#8221;%&lt;&gt;[]{}|\^`~</li>
<li>不当做保留字符来使用的保留字符，即&amp;/:;=?@</li>
</ul>
<p><span id="more-187"></span></p>
<p>详见这张图，一目了然（点击看大图）：</p>
<div id="attachment_188" class="wp-caption aligncenter" style="width: 310px"><a href="http://jsfox.cn/blog/wp-content/uploads/2010/05/URLEncodingASCII.png"><img class="size-medium wp-image-188" title="URL编码在ASCII表中的体现" src="http://jsfox.cn/blog/wp-content/uploads/2010/05/URLEncodingASCII-300x147.png" alt="URL编码在ASCII表中的体现" width="300" height="147" /></a><p class="wp-caption-text">URL编码在ASCII表中的体现</p></div>
<h2>如何编码？</h2>
<p>众所周知，字符是可由八位字节数（octet）来表示的，八位字节数可用十六进制来表示它的值。如字符“&lt;”的八位字节数十六进制值是3C。在URL中，字符的编码方式为：“%”加上字符的两个十六进制数值。举几个例子：</p>
<ul>
<li>“&lt;”可以被编码为%3C，空格“<span style="text-decoration: underline;">SP</span>”可被编码为“%20”</li>
<li>“田”的GB2312编码十六进制值是CC EF，这时“田”的URL编码为%CC%EF</li>
<li>“囧”的GBK编码十六进制值是87 E5，这时“囧”的URL编码为%87%E5</li>
<li>“田”的UTF-8编码十六进制值是E7 94 B0，这时“田”的URL编码为%E7%94%B0</li>
</ul>
<h2>URL中包含汉字时的更多话题</h2>
<p>RFC1738没有规定汉字的编码方式，而是让浏览器自己去决定，因此造成了URL汉字编码的不统一。经过研究，对于URL中的“查询字符串”和“路径”中包含汉字，不同浏览器有不同的处理。</p>
<h3>1. 查询字符串中包含汉字</h3>
<p>在网址输入：http://www.baidu.com/s?wd=田囧 ，敲击回车，使用Fiddler观察浏览器发出的请求（以IE8和Firefox为例）：</p>
<div id="attachment_189" class="wp-caption aligncenter" style="width: 310px"><a href="http://jsfox.cn/blog/wp-content/uploads/2010/05/query_string_han.png"><img class="size-medium wp-image-189" title="查询字符串中含有中文" src="http://jsfox.cn/blog/wp-content/uploads/2010/05/query_string_han-300x139.png" alt="查询字符串中含有中文" width="300" height="139" /></a><p class="wp-caption-text">查询字符串中含有中文</p></div>
<p>IE8将汉字作为GBK编码，直接发往服务器（这其实是不符合RFC规范的）；Firefox则多了一次加%的操作。Windows操作系统是GBK编码。得到结论，地址栏直接访问URL，汉字作为查询字符串(Query string)时，IE和Firefox会使用系统编码发至服务器端，Firefox会按规矩编码。</p>
<blockquote><p><strong>注意1</strong>：不要用Google进行测试，Google的搜索URL（类似：http://www.google.com/#hl=en&amp;source=hp&amp;q=田囧 ），搜索关键词那里不是查询字符串，因为前面有个#……我开始没注意到，被搞迷茫了很久……</p>
<p><strong>注意2</strong>：这只是对URL直接访问的规律。如果页面时从链接点击打开的，例如从A页面含中文的链接打开了B页面，那么浏览器对中文的编码取决于A页面的编码。</p></blockquote>
<h3>2. URL路径中包含汉字</h3>
<p>在网址直接输入：http://www.hudong.com/wiki/田囧 ，敲击回车，观察请求：</p>
<div id="attachment_190" class="wp-caption aligncenter" style="width: 310px"><a href="http://jsfox.cn/blog/wp-content/uploads/2010/05/url_directory_han.png"><img class="size-medium wp-image-190" title="路径中含有中文" src="http://jsfox.cn/blog/wp-content/uploads/2010/05/url_directory_han-300x110.png" alt="路径中含有中文" width="300" height="110" /></a><p class="wp-caption-text">路径中含有中文</p></div>
<p>IE8和Firefox都把汉字作为UTF8，按规范进行了URL编码，还好。</p>
<h2>总结</h2>
<p>什么字符应该编码，什么字符不用编码，URL编码的基本问题，到此已经解决啦。</p>
]]></content:encoded>
			<wfw:commentRss>http://jsfox.cn/blog/learning/understand-url-encodin.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>HTML5 历史、现状及未来</title>
		<link>http://jsfox.cn/blog/others/html5-history-and-future.html</link>
		<comments>http://jsfox.cn/blog/others/html5-history-and-future.html#comments</comments>
		<pubDate>Tue, 20 Apr 2010 11:31:38 +0000</pubDate>
		<dc:creator>yongbin</dc:creator>
				<category><![CDATA[Others]]></category>
		<category><![CDATA[Browser]]></category>
		<category><![CDATA[Chrome]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[IE8]]></category>
		<category><![CDATA[Opera]]></category>
		<category><![CDATA[Safari]]></category>

		<guid isPermaLink="false">http://jsfox.cn/blog/?p=179</guid>
		<description><![CDATA[分享一下HTML5的东西。
HTML5 历史、现状及未来
View more presentations from Yongbin Tian.


]]></description>
			<content:encoded><![CDATA[<p>分享一下HTML5的东西。</p>
<div id="__ss_3787971" style="width: 425px;"><strong><a title="HTML5 历史、现状及未来" href="http://www.slideshare.net/duckuu/html5-3787971">HTML5 历史、现状及未来</a></strong><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=html5-100420061434-phpapp01&amp;stripped_title=html5-3787971" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=html5-100420061434-phpapp01&amp;stripped_title=html5-3787971" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div style="padding: 5px 0 12px;">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/duckuu">Yongbin Tian</a>.</div>
<p><span id="more-179"></span></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://jsfox.cn/blog/others/html5-history-and-future.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Even Faster Web Sites: 读书笔记(二)</title>
		<link>http://jsfox.cn/blog/javascript/even-faster-websites-notes2.html</link>
		<comments>http://jsfox.cn/blog/javascript/even-faster-websites-notes2.html#comments</comments>
		<pubDate>Sun, 24 Jan 2010 08:54:18 +0000</pubDate>
		<dc:creator>yongbin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Browser]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[优化]]></category>
		<category><![CDATA[前端]]></category>
		<category><![CDATA[性能]]></category>

		<guid isPermaLink="false">http://jsfox.cn/blog/?p=170</guid>
		<description><![CDATA[这次因为一个项目的原因，又重读了《Even Faster Web Sites》书里的第四章：Loading scripts without blocking，并且在Cuzillion里做了大量测试，又发现了很多有意思的细节。发现自己读书太糙，自责一下。结合实际工作，加上自己的理解，再把这一章的实用内容总结一下。
要解决的问题
页面的script标签引入外部js文件时，会阻塞后续外部资源的下载和加载，包括图片、CSS文件、iframe等等。
1. Script DOM Element比较常用
&#8220;Script DOM Element&#8221;方法是常见的方法，也就是createElement(&#8220;script&#8221;)的方法下载js文件，以此并行加载后续资源。这其实是很棒的一个方法，因为不需要担心跨域，而且我们在中文应用中，不用担心编码的问题（可以为&#60;script&#62;指定编码）。但这里需要注意的是，非IE浏览器下，这种方法会阻止window.onload事件，因此如果你的js文件很大，可能会带来用户体验不好。IE浏览器对这种贴script标签的行为是“无动于衷”的，不会在状态栏、光标和进度圈上做任何指示。看来IE也不是一无是处嘛，哈哈！测试地址。
2. 个人不提倡使用XHR Eval
XHR Eval方法我不提倡使用，首先是中文编码上会遇到麻烦，其次跨域问题。另外就是下面这句：
eval(xhrObj.responseText);
当js文件比较大的时候，用eval会相对较慢，并带来安全性隐患。
3. XHR Inject是个好东西
如果编码和跨域问题都不是问题，那么XHR Inject就是最好的方法了。这是XHR Eval和DOM Script的一个这种办法，实现机制就是：
var s = document.createElement('script');
s.text = xhrObj.responseText;
这种方法避开了evil eval，并且和DOM Script一样，可以按顺序加载js文件，当然，不会阻塞后续资源的加载。更为重要的是，在所有浏览器下，这种方法都不会阻止渲染和onload事件，体现了XMLHTTPRequest的本色。测试地址在此。
4. defer属性可以快速尝试
Script标签的defer属性，可以让后续资源并行加载。在实际的项目中，偶尔也可以尝试使用，因为比较快捷。Firefox 3.1以后，也开始支持script的defer属性啦。
5. document.write(&#8220;a.js&#8221;)的注意事项
注意：在&#60;head&#62;用document.write来插入js脚本，只能让浏览器并行加载&#60;head&#62;里的资源。也就是说，&#60;head&#62;里write脚本，会阻塞&#60;body&#62;的加载。测试地址。另外关于document.write，还有两个需要注意的问题。第一，它只能带来“并行加载js文件”的效果，对其他资源无效；第二，IE、Chrome支持，Firefox不支持。
6. Script in Iframe方法强烈不赞同
在iframe放js，来实现页面资源并行加载，无疑是得不偿失的行为。首先，iframe太沉重了；其次，你还得改你的js代码。反正我是不能接受的，哈哈。
结束语
在开发中，如果要加载数个js大文件，比较实际的做法还是插入script标签的方法。如果没有编码和跨域问题，用XHR Inject方法当然更好啦。
欢迎指正！
]]></description>
			<content:encoded><![CDATA[<p>这次因为一个项目的原因，又重读了《Even Faster Web Sites》书里的第四章：Loading scripts without blocking，并且在Cuzillion里做了大量测试，又发现了很多有意思的细节。发现自己读书太糙，自责一下。结合实际工作，加上自己的理解，再把这一章的实用内容总结一下。</p>
<h3>要解决的问题</h3>
<p>页面的script标签引入外部js文件时，会阻塞后续外部资源的下载和加载，包括图片、CSS文件、iframe等等。</p>
<h3>1. Script DOM Element比较常用</h3>
<p>&#8220;Script DOM Element&#8221;方法是常见的方法，也就是createElement(&#8220;script&#8221;)的方法下载js文件，以此并行加载后续资源。这其实是很棒的一个方法，因为不需要担心跨域，而且我们在中文应用中，不用担心编码的问题（可以为&lt;script&gt;指定编码）。但这里需要注意的是，非IE浏览器下，这种方法会阻止window.onload事件，因此如果你的js文件很大，可能会带来用户体验不好。IE浏览器对这种贴script标签的行为是“无动于衷”的，不会在状态栏、光标和进度圈上做任何指示。看来IE也不是一无是处嘛，哈哈！<a title="IE对Script DOM Element方法无动于衷" href="http://stevesouders.com/cuzillion/?c0=bj1dfff10_0_f&amp;c1=bi1hfff2_0_f&amp;c2=bi1hfff2_0_f&amp;t=1264320241" target="_blank">测试地址</a>。</p>
<h3>2. 个人不提倡使用XHR Eval</h3>
<p>XHR Eval方法我不提倡使用，首先是中文编码上会遇到麻烦，其次跨域问题。另外就是下面这句：<span id="more-170"></span></p>
<pre>eval(xhrObj.responseText);</pre>
<p>当js文件比较大的时候，用eval会相对较慢，并带来安全性隐患。</p>
<h3>3. XHR Inject是个好东西</h3>
<p>如果编码和跨域问题都不是问题，那么XHR Inject就是最好的方法了。这是XHR Eval和DOM Script的一个这种办法，实现机制就是：</p>
<pre>var s = document.createElement('script');
s.text = xhrObj.responseText;</pre>
<p>这种方法避开了evil eval，并且和DOM Script一样，可以按顺序加载js文件，当然，不会阻塞后续资源的加载。更为重要的是，在所有浏览器下，这种方法都不会阻止渲染和onload事件，体现了XMLHTTPRequest的本色。<a title="使用XHR Inject" href="http://stevesouders.com/cuzillion/?c0=bj1ifff10_0_f&amp;c1=bi1hfff2_0_f&amp;c2=bi1hfff2_0_f&amp;c3=bj1ifff10_0_f&amp;t=1264321809123" target="_blank">测试地址在此</a>。</p>
<h3>4. defer属性可以快速尝试</h3>
<p>Script标签的defer属性，可以让后续资源并行加载。在实际的项目中，偶尔也可以尝试使用，因为比较快捷。Firefox 3.1以后，也开始支持script的defer属性啦。</p>
<h3>5. document.write(&#8220;a.js&#8221;)的注意事项</h3>
<p>注意：在&lt;head&gt;用document.write来插入js脚本，只能让浏览器并行加载&lt;head&gt;里的资源。也就是说，&lt;head&gt;里write脚本，会阻塞&lt;body&gt;的加载。<a title="测试head里document.write" href="http://stevesouders.com/cuzillion/?c0=hj1wfff2_0_f&amp;c1=hj1dfff2_0_f&amp;c2=bi1hfff2_0_f&amp;c3=bi1hfff2_0_f&amp;c4=bj1dfff3_1_f&amp;c5=bj1dfff3_1_f&amp;c6=bi1hfff2_0_f&amp;c7=bi1hfff2_0_f&amp;t=1264319269150" target="_blank">测试地址</a>。另外关于document.write，还有两个需要注意的问题。第一，它只能带来“并行加载js文件”的效果，对其他资源无效；第二，IE、Chrome支持，Firefox不支持。</p>
<h3>6. Script in Iframe方法强烈不赞同</h3>
<p>在iframe放js，来实现页面资源并行加载，无疑是得不偿失的行为。首先，iframe太沉重了；其次，你还得改你的js代码。反正我是不能接受的，哈哈。</p>
<h3>结束语</h3>
<p>在开发中，如果要加载数个js大文件，比较实际的做法还是插入script标签的方法。如果没有编码和跨域问题，用XHR Inject方法当然更好啦。</p>
<p>欢迎指正！</p>
]]></content:encoded>
			<wfw:commentRss>http://jsfox.cn/blog/javascript/even-faster-websites-notes2.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Even Faster Web Sites: 读书笔记(一)</title>
		<link>http://jsfox.cn/blog/javascript/even-faster-websites-notes1.html</link>
		<comments>http://jsfox.cn/blog/javascript/even-faster-websites-notes1.html#comments</comments>
		<pubDate>Fri, 21 Aug 2009 04:31:43 +0000</pubDate>
		<dc:creator>yongbin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[优化]]></category>
		<category><![CDATA[前端]]></category>
		<category><![CDATA[性能]]></category>

		<guid isPermaLink="false">http://jsfox.cn/blog/?p=156</guid>
		<description><![CDATA[《Even Faster Web Sites》是Steve Souders的新书。Steve Souders现在是Google工程师，《High Performance Web Sites》一书的作者，Google Web Ex系列讲座的主持人，对前端优化有很专业的研究。他的UA Profiler和Cuzillion项目尤其引人注目。
《High Performance Web Sites》这本书相信大家都比较熟悉，Souders在其中主要讲解了Yahoo!的14条网站性能军规。很是期待这本《Even Faster Web Sites》，可惜国内市面上还没有。偶得电子版一套，迫不及待打印出来，细细读来。
这本书只有一多半是Souders写的，其他部分是Crockford, NCZ等人的贡献，因此十分有内容。这次先记一些关于页面加载性能方面的读书笔记。
Splitting the initial payload

要提高前端性能，可以这样：页面在第一次加载时，只加载渲染页面所需要的资源（主要针对js），以及一个ScriptLoader方法。其他js资源在需要的时候再动态加载。这样做的挑战就是分离用于初次渲染的js资源，也就是找到split。微软有一个Doloto项目是做这个的，但Doloto还没有向外公布，所以我们得手动搞分裂了。
Loading scripts without blocking
外部js文件在下载和执行时，大多数浏览器都会阻塞其后面的内容（ps这也是可以理解的）。要防止这种阻塞，有若干种办法。我们比较常用的大概是XHR注入和Script tag。Souders还介绍了XHR Eval, Script in Iframe, Script Defer, document.write(&#60;script&#62;)等，并且画出了决策树。这些方法原理都是用异步加载外部js文件，以提高页面渲染速度。方法类似于我们用script tag来实现类ajax跨域应用。
大家可以用Cuzillion来真实测试一下堵塞情形，非常有意思，非常有必要，非常好。
前两天NCZ在他的博客上也对这种异步加载作了介绍，The best way to load external JavaScript。他认为这项技术的best practice是，首先写一个scriptLoader.js，再把页面所需要的其他js都放在second.js里，把scriptLoader.js放在&#60;/body&#62;之前，再紧跟行内js加载second.js文件。确实不错，而且YUI和Google Analytics都这么做了。
那么到底用哪种方法来做script loader呢，在实际应用中，我认为如果不需要跨域、不考虑多个js文件加载顺序的话，XHR Injection最好，因为它不会阻塞onload事件（发现TinyMCE加载插件就是这个原理）；否则的话，就是用script tag方法。
Positioning inline scripts
行内js在执行时，会阻塞其后内容的并行加载、页面渲染。顺便说，如果执行时间过长（100ms以上），用户会感觉到卡，体验非常不好。为了防止阻塞，可以用setTimeout来实现异步调用。那么文档下载完之后，为了给浏览器喘息的机会（进行渲染），延时多久才让这些js执行呢，IE下0ms即可，Firefox下是250ms。
另外有一个大忌，就是外部css文件紧跟行内js的情况。这样会造成比较严重的阻塞。是什么原因呢？行内js一般不会被阻塞，除非代码前面有css。
&#60;link rel='stylesheet' type='text/css' href='a.css' /&#62;
&#60;script type="text/javascript"&#62;
// do a lot [...]]]></description>
			<content:encoded><![CDATA[<p>《Even Faster Web Sites》是<a title="Steve Souders" href="http://stevesouders.com/" target="_blank">Steve Souders</a>的新书。Steve Souders现在是Google工程师，《High Performance Web Sites》一书的作者，Google Web E<sup>x</sup>系列讲座的主持人，对前端优化有很专业的研究。他的<a title=" ua profiler" href="http://stevesouders.com/ua/" target="_blank">UA Profiler</a>和<a title="Cuzillion" href="http://stevesouders.com/cuzillion/" target="_blank">Cuzillion</a>项目尤其引人注目。</p>
<p>《High Performance Web Sites》这本书相信大家都比较熟悉，Souders在其中主要讲解了Yahoo!的14条网站性能军规。很是期待这本《Even Faster Web Sites》，可惜国内市面上还没有。偶得电子版一套，迫不及待打印出来，细细读来。</p>
<p>这本书只有一多半是Souders写的，其他部分是Crockford, NCZ等人的贡献，因此十分有内容。这次先记一些关于页面加载性能方面的读书笔记。</p>
<h4>Splitting the initial payload</h4>
<p><span id="more-156"></span></p>
<p>要提高前端性能，可以这样：页面在第一次加载时，只加载渲染页面所需要的资源（主要针对js），以及一个ScriptLoader方法。其他js资源在需要的时候再动态加载。这样做的挑战就是分离用于初次渲染的js资源，也就是找到split。微软有一个Doloto项目是做这个的，但Doloto还没有向外公布，所以我们得手动搞分裂了。</p>
<h4>Loading scripts without blocking</h4>
<p>外部js文件在下载和执行时，大多数浏览器都会阻塞其后面的内容（ps这也是可以理解的）。要防止这种阻塞，有若干种办法。我们比较常用的大概是XHR注入和Script tag。Souders还介绍了XHR Eval, Script in Iframe, Script Defer, document.write(&lt;script&gt;)等，并且画出了决策树。这些方法原理都是用异步加载外部js文件，以提高页面渲染速度。方法类似于我们用script tag来实现类ajax跨域应用。</p>
<p>大家可以用Cuzillion来真实测试一下堵塞情形，非常有意思，非常有必要，非常好。</p>
<p>前两天NCZ在他的博客上也对这种异步加载作了介绍，<a title="The best way to load external JavaScript" href="http://www.nczonline.net/blog/2009/07/28/the-best-way-to-load-external-javascript/" target="_blank">The best way to load external JavaScript</a>。他认为这项技术的best practice是，首先写一个scriptLoader.js，再把页面所需要的其他js都放在second.js里，把scriptLoader.js放在&lt;/body&gt;之前，再紧跟行内js加载second.js文件。确实不错，而且YUI和Google Analytics都这么做了。</p>
<p>那么到底用哪种方法来做script loader呢，在实际应用中，我认为如果不需要跨域、不考虑多个js文件加载顺序的话，XHR Injection最好，因为它不会阻塞onload事件（发现TinyMCE加载插件就是这个原理）；否则的话，就是用script tag方法。</p>
<h4>Positioning inline scripts</h4>
<p>行内js在执行时，会阻塞其后内容的并行加载、页面渲染。顺便说，如果执行时间过长（100ms以上），用户会感觉到卡，体验非常不好。为了防止阻塞，可以用setTimeout来实现异步调用。那么文档下载完之后，为了给浏览器喘息的机会（进行渲染），延时多久才让这些js执行呢，IE下0ms即可，Firefox下是250ms。</p>
<p>另外有一个大忌，就是外部css文件紧跟行内js的情况。这样会造成比较严重的阻塞。是什么原因呢？行内js一般不会被阻塞，除非代码前面有css。</p>
<pre>&lt;link rel='stylesheet' type='text/css' href='a.css' /&gt;
&lt;script type="text/javascript"&gt;
// do a lot of things
&lt;/script&gt;</pre>
<p>假如行内js前有一个外部css文件（如上述代码），那么这段js要等到css文件完全下载完才会被执行，js被阻塞，造成了页面剩余内容被阻塞，恶劣的连锁反应被引发。</p>
<p>先总结这么多，欢迎指正！</p>
]]></content:encoded>
			<wfw:commentRss>http://jsfox.cn/blog/javascript/even-faster-websites-notes1.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>获得原始href属性的方法</title>
		<link>http://jsfox.cn/blog/javascript/get-right-href-attribute.html</link>
		<comments>http://jsfox.cn/blog/javascript/get-right-href-attribute.html#comments</comments>
		<pubDate>Sat, 08 Aug 2009 05:35:16 +0000</pubDate>
		<dc:creator>yongbin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[cross-browser]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[href]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[IE]]></category>

		<guid isPermaLink="false">http://jsfox.cn/blog/?p=141</guid>
		<description><![CDATA[JavaScript里得到某个链接的href属性时，有三种方式，总结一下：
1. 直接获得href属性，也就是
var url = el.href;  // el是一个a元素
2. 使用getAttribute方法，像这样：
var url = el.getAttribute("href");
3. IE下的getAttribute方法有第二个参数，参见msdn的这篇。第二个参数如果是2，意思是以字符串形式返回。
var url = el.getAttribute("href", 2);
获得href属性的这三种方法，同样的，有三点，让人很费解，而且浏览器实现各不相同。

如果href写的是相对地址，得到属性时，浏览器可能会自动转为绝对地址。（很多情况下我们是不希望这样的）
如果href里有汉字，浏览器会自动编码吗？
如果href里有特殊字符，浏览器会自动编码吗？例如大括号{}。

为此我做了一个小测试页面（点这里可测试），得到了如下的结果：



获得href和src属性的浏览器差异（相对地址与自动编码情况）



.href
getAttribute(&#8220;href&#8221;)
getAttribute(&#8220;href&#8221;, 2)


IE6
转绝对，不编码
转绝对，不编码
正常


IE7
转绝对，汉字不编码，特殊符号编码
转绝对，汉字不编码，特殊符号编码
正常


IE8 as IE7
转绝对，汉字不编码，特殊符号编码
转绝对，汉字不编码，特殊符号编码
正常


IE8 standard
转绝对，汉字不编码，特殊符号编码
正常
正常


Firefox 3.0+
转绝对，全部编码
正常
正常


Chrome 2.0
转绝对，全部编码
正常
正常


Safari 4.0
转绝对，汉字编码，特殊符号不编码
正常
正常


Opera 10.0beta
转绝对，汉字编码，特殊符号不编码
正常
正常



其中，“正常”的意思是，得到href属性里原始链接，不自动转绝对地址、汉字和符号都不编码。
结论，如果想得到href里的未经转换、未经编码的原始内容，IE浏览器下全部使用getAttribute(&#8220;href&#8221;, 2)，其他浏览器下使用getAttribute(&#8220;href&#8221;)即可，这在序列化DOM时会非常有用；如果想得到绝对地址、编不编码没关系，那就用href属性。
]]></description>
			<content:encoded><![CDATA[<p>JavaScript里得到某个链接的href属性时，有三种方式，总结一下：</p>
<p>1. 直接获得href属性，也就是</p>
<pre>var url = el.href;  // el是一个a元素</pre>
<p>2. 使用getAttribute方法，像这样：</p>
<pre>var url = el.getAttribute("href");</pre>
<p>3. IE下的getAttribute方法有第二个参数，参见<a title="msdn getAttribute notes" href="http://msdn.microsoft.com/en-us/library/ms536429(VS.85).aspx" target="_blank">msdn的这篇</a>。第二个参数如果是2，意思是以字符串形式返回。</p>
<pre>var url = el.getAttribute("href", 2);</pre>
<p>获得href属性的这三种方法，同样的，有三点，让人很费解，而且浏览器实现各不相同。</p>
<ol>
<li>如果href写的是相对地址，得到属性时，浏览器可能会自动转为绝对地址。（很多情况下我们是不希望这样的）</li>
<li>如果href里有汉字，浏览器会自动编码吗？</li>
<li>如果href里有特殊字符，浏览器会自动编码吗？例如大括号{}。</li>
</ol>
<p>为此我做了一个小测试页面（<a title="测试获得链接的href属性" href="http://jsfox.cn/blog/test/test_href.html" target="_blank">点这里可测试</a>），得到了如下的结果：<span id="more-141"></span></p>
<table border="0">
<tbody>
<tr>
<th style="font-size:12px" colspan="4">获得href和src属性的浏览器差异（相对地址与自动编码情况）</th>
</tr>
<tr>
<td width="20%"></td>
<td width="25%"><strong>.href</strong></td>
<td width="25%"><strong>getAttribute(&#8220;href&#8221;)</strong></td>
<td width="30%"><strong>getAttribute(&#8220;href&#8221;, 2)</strong></td>
</tr>
<tr>
<td><strong>IE6</strong></td>
<td>转绝对，不编码</td>
<td>转绝对，不编码</td>
<td>正常</td>
</tr>
<tr>
<td><strong>IE7</strong></td>
<td>转绝对，汉字不编码，特殊符号编码</td>
<td>转绝对，汉字不编码，特殊符号编码</td>
<td>正常</td>
</tr>
<tr>
<td><strong>IE8 as IE7</strong></td>
<td>转绝对，汉字不编码，特殊符号编码</td>
<td>转绝对，汉字不编码，特殊符号编码</td>
<td>正常</td>
</tr>
<tr>
<td><strong>IE8 standard</strong></td>
<td>转绝对，汉字不编码，特殊符号编码</td>
<td>正常</td>
<td>正常</td>
</tr>
<tr>
<td><strong>Firefox 3.0+</strong></td>
<td>转绝对，全部编码</td>
<td>正常</td>
<td>正常</td>
</tr>
<tr>
<td><strong>Chrome 2.0</strong></td>
<td>转绝对，全部编码</td>
<td>正常</td>
<td>正常</td>
</tr>
<tr>
<td><strong>Safari 4.0</strong></td>
<td>转绝对，汉字编码，特殊符号不编码</td>
<td>正常</td>
<td>正常</td>
</tr>
<tr>
<td><strong>Opera 10.0beta</strong></td>
<td>转绝对，汉字编码，特殊符号不编码</td>
<td>正常</td>
<td>正常</td>
</tr>
</tbody>
</table>
<p>其中，“正常”的意思是，得到href属性里原始链接，不自动转绝对地址、汉字和符号都不编码。</p>
<p>结论，如果想得到href里的未经转换、未经编码的原始内容，IE浏览器下全部使用getAttribute(&#8220;href&#8221;, 2)，其他浏览器下使用getAttribute(&#8220;href&#8221;)即可，这在序列化DOM时会非常有用；如果想得到绝对地址、编不编码没关系，那就用href属性。</p>
]]></content:encoded>
			<wfw:commentRss>http://jsfox.cn/blog/javascript/get-right-href-attribute.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>由IE一例处理comment节点的bug得到的结论</title>
		<link>http://jsfox.cn/blog/javascript/ie-comment-element-bug.html</link>
		<comments>http://jsfox.cn/blog/javascript/ie-comment-element-bug.html#comments</comments>
		<pubDate>Thu, 09 Jul 2009 12:05:18 +0000</pubDate>
		<dc:creator>yongbin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[HTML]]></category>

		<guid isPermaLink="false">http://jsfox.cn/blog/?p=29</guid>
		<description><![CDATA[近期处理一个项目，需要“翻译”页面的注释节点。功能在Firefox下一切正常，项目进行非常顺利。拿到IE全系列下，却非常不正常，把注释翻译成ELEMENT Node，页面立刻飞掉。检查不出来原因，抓狂了好几天。
后来发现，问题出在IE渲染li的时候。我们的项目里，有时候要求注释节点需要插入在li的后面。虽然这不太标准，但是实际应用中，也是没办法的事。IE6+会把注释节点包进li里面，真是无语。
例如页面上的代码：
&#60;ul id="test"&#62;
  &#60;!-- comment_begin --&#62;
  &#60;li&#62;asdf&#60;/li&#62;
  &#60;li&#62;asdf&#60;/li&#62;
  &#60;li&#62;asdf&#60;/li&#62;
  &#60;!-- comment_end --&#62;
&#60;/ul&#62;
试试document.getElementById(&#8220;test&#8221;).innerHTML，弹出：
&#60;!-- comment_begin --&#62;
&#60;LI&#62;asdf
&#60;LI&#62;asdf
&#60;LI&#62;asdf &#60;!-- comment_end --&#62;&#60;/LI&#62;

用IE8的开发者工具，也能看到同样的效果。IE其实是用这个代码来渲染页面的。最后的解决办法只好先“预处理”一下，把注释节点挪出来，大概是这样：
var lis = document.getElementsByTagName("li");
for (var i = 0, l = lis.length; i &#60; l; i++) {
  if (lis[i].lastChild.nodeType === \8) {
    lis[i].parentNode.appendChild(lis[i].lastChild);
  }
}
这个bug说明一个问题，IE系列浏览器，包括IE8，内部的渲染还是使用的陈旧的HTML渲染方式，哪怕页面的文档类型DOCTYPE是xhtml。像这次遇到的问题，真是很难发现。IE浏览器真是无端耗费我们的青春啊！
]]></description>
			<content:encoded><![CDATA[<p>近期处理一个项目，需要“翻译”页面的注释节点。功能在Firefox下一切正常，项目进行非常顺利。拿到IE全系列下，却非常不正常，把注释翻译成ELEMENT Node，页面立刻飞掉。检查不出来原因，抓狂了好几天。</p>
<p>后来发现，问题出在IE渲染li的时候。我们的项目里，有时候要求注释节点需要插入在li的后面。虽然这不太标准，但是实际应用中，也是没办法的事。IE6+会把注释节点包进li里面，真是无语。</p>
<p>例如页面上的代码：</p>
<pre>&lt;ul id="test"&gt;
  &lt;!-- comment_begin --&gt;
  &lt;li&gt;asdf&lt;/li&gt;
  &lt;li&gt;asdf&lt;/li&gt;
  &lt;li&gt;asdf&lt;/li&gt;
  &lt;!-- comment_end --&gt;
&lt;/ul&gt;</pre>
<p>试试document.getElementById(&#8220;test&#8221;).innerHTML，弹出：</p>
<pre>&lt;!-- comment_begin --&gt;
&lt;LI&gt;asdf
&lt;LI&gt;asdf
&lt;LI&gt;asdf &lt;!-- comment_end --&gt;&lt;/LI&gt;</pre>
<p><span id="more-29"></span></p>
<p>用IE8的开发者工具，也能看到同样的效果。IE其实是用这个代码来渲染页面的。最后的解决办法只好先“预处理”一下，把注释节点挪出来，大概是这样：</p>
<pre>var lis = document.getElementsByTagName("li");
for (var i = 0, l = lis.length; i &lt; l; i++) {
  if (lis[i].lastChild.nodeType === \8) {
    lis[i].parentNode.appendChild(lis[i].lastChild);
  }
}</pre>
<p>这个bug说明一个问题，IE系列浏览器，包括IE8，内部的渲染还是使用的陈旧的HTML渲染方式，哪怕页面的文档类型DOCTYPE是xhtml。像这次遇到的问题，真是很难发现。IE浏览器真是无端耗费我们的青春啊！</p>
]]></content:encoded>
			<wfw:commentRss>http://jsfox.cn/blog/javascript/ie-comment-element-bug.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>开发WYSIWYG编辑器可能遇到的问题</title>
		<link>http://jsfox.cn/blog/javascript/developing-wysiwyg-editor.html</link>
		<comments>http://jsfox.cn/blog/javascript/developing-wysiwyg-editor.html#comments</comments>
		<pubDate>Mon, 29 Jun 2009 03:51:58 +0000</pubDate>
		<dc:creator>yongbin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[WYSIWYG]]></category>

		<guid isPermaLink="false">http://jsfox.cn/blog/?p=8</guid>
		<description><![CDATA[最近从头开发了一个简单实用的页面可视化编辑器，感觉从中学到了不少东西。功能就是用一个脚本把前端页面的某些块搞成可以编辑的状态。遇到了几个主要的问题，让我印象最深刻。汇总一下吧：
Firefox 3+开始支持contenteditable属性，这让可视化编辑变得简单。想要“可视化”一个节点，只要给它赋上contenteditable属性即可。如果你想让某一个页面上实现简易的在线编辑功能，那么思路就是：
1. 前端页面，通过JavaScript给需要编辑的节点赋上contenteditable属性，为true。注意这里要用o.contentEditable = “true”，用setAttribute在IE下设置不成功。
2. 用js生成一个按钮工具条，包括一些常用的按钮，例如加粗、修改链接等等。用document.execCommand来执行一些常用的命令，但可用的不多，只有createlink, unlink, bold等。需要的话，还是自己写。
3. 需要弹出对话框的指令，例如修改链接，用行内对话框（inline popup）来实现，不用window.open。一来比较方便，二来可以避免某些浏览器把弹窗block掉。

4. 重写innerHTML，也就是写一个getHTMLContent()。因为IE sucks，它的innerHTML会把你的代码搞得非常不规范，标签大写，属性丢失，文本节点、注释节点丢失……重写innerHTML的方法是递归序列化一个DOM节点，遇到ELEMENT节点，写一串ELEMENT字符串，遇到COMMENT节点，写  &#60;!&#8211;，挺有意思的。我是参考TinyMCE来搞了一个轻量级的DOM serializer，回头发出来共享。对了，Firefox下，只要简单的innerHTML，就可以了。哦，给我一个不爱Firefox的理由！
5. 重写setHTML。如果仅仅使用o.innerHTML = str，那么IE还是会给你带来麻烦。如果str以注释开头，哦，那你的注释就再也找不到了。还有一些其他的问题，例如把&#8221;&#60;p&#62;&#60;ul&#62;&#60;li&#62;&#60;/li&#62;&#60;/ul&#62;&#60;/p&#62;&#8221;在IE下set进一个元素的innerHTML，IE会自作主张地给你搞乱。
总的来说，其实不难，只是用一个contenteditable属性把页面的一块区域搞成WYSIWYG Editing，然后一个实现一个set，一个get，整体思路就是这样，hoho！
]]></description>
			<content:encoded><![CDATA[<p>最近从头开发了一个简单实用的页面可视化编辑器，感觉从中学到了不少东西。功能就是用一个脚本把前端页面的某些块搞成可以编辑的状态。遇到了几个主要的问题，让我印象最深刻。汇总一下吧：</p>
<p>Firefox 3+开始支持contenteditable属性，这让可视化编辑变得简单。想要“可视化”一个节点，只要给它赋上contenteditable属性即可。如果你想让某一个页面上实现简易的在线编辑功能，那么思路就是：</p>
<p>1. 前端页面，通过JavaScript给需要编辑的节点赋上contenteditable属性，为true。注意这里要用o.contentEditable = “true”，用setAttribute在IE下设置不成功。</p>
<p>2. 用js生成一个按钮工具条，包括一些常用的按钮，例如加粗、修改链接等等。用document.execCommand来执行一些常用的命令，但可用的不多，只有createlink, unlink, bold等。需要的话，还是自己写。</p>
<p>3. 需要弹出对话框的指令，例如修改链接，用行内对话框（inline popup）来实现，不用window.open。一来比较方便，二来可以避免某些浏览器把弹窗block掉。</p>
<p><span id="more-8"></span></p>
<p>4. 重写innerHTML，也就是写一个getHTMLContent()。因为IE sucks，它的innerHTML会把你的代码搞得非常不规范，标签大写，属性丢失，文本节点、注释节点丢失……重写innerHTML的方法是递归序列化一个DOM节点，遇到ELEMENT节点，写一串ELEMENT字符串，遇到COMMENT节点，写  &lt;!&#8211;，挺有意思的。我是参考TinyMCE来搞了一个轻量级的DOM serializer，回头发出来共享。对了，Firefox下，只要简单的innerHTML，就可以了。哦，给我一个不爱Firefox的理由！</p>
<p>5. 重写setHTML。如果仅仅使用o.innerHTML = str，那么IE还是会给你带来麻烦。如果str以注释开头，哦，那你的注释就再也找不到了。还有一些其他的问题，例如把&#8221;&lt;p&gt;&lt;ul&gt;&lt;li&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&#8221;在IE下set进一个元素的innerHTML，IE会自作主张地给你搞乱。</p>
<p>总的来说，其实不难，只是用一个contenteditable属性把页面的一块区域搞成WYSIWYG Editing，然后一个实现一个set，一个get，整体思路就是这样，hoho！</p>
]]></content:encoded>
			<wfw:commentRss>http://jsfox.cn/blog/javascript/developing-wysiwyg-editor.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
