今天無意間打開了一個CSDN上的個人blog,發現窗口無法拖動,Firefox的標簽頁也無法切換。
查看代碼:
<script type="text/javascript">Include("Csdn.Blog.UserOnline");</script>
<script type="text/javascript">Include("Csdn.Blog.ShowmeDataDeal");</script>
<script type="text/javascript">Include("Csdn.Blog.ShowmeDataDeal");</script>
看到Include函數,馬上可以想到,它很可能使用了動態包含腳本的設計。
//http://blog.csdn.net/scripts/jsframework.js
window.Include=function(namespace, path)
{
..
};
S.load=function(namespace, path)
{

}
window.Include=function(namespace, path)
{

};
S.load=function(namespace, path)
{


}
仔細閱讀這兩個函數代碼,發現它是通過XMLHttpRequest對象同步裝載腳本資源的(對IE,它采用userdata緩存優化)。而這必將導致一種完全阻塞問題(這種問題我在仍外一篇blog上描述過:http://jindw.javaeye.com/blog/66702)。
說到阻塞問題,我想大家可能會以為只是一種下載延遲,其實不然。
下載延遲不是完全阻塞,瀏覽器依然可以響應用戶事件。而同步XHR請求阻塞是一種完全的阻塞。
瀏覽器在腳本運行與事件響應共用同一個線程(我的猜測)。任何腳本尚在運行時(包括被同步XHR請求阻塞的時間),瀏覽器將無法響應任何用戶事件(無法拖放窗口、切換標簽、重畫頁面等等,就像程序死了一樣)。與普通的下載延遲造成的阻塞,感覺明顯不同。
我對這個問題可以說深有體會,起初,在構建JSI1的項目站點時。因為網站放在sourceforge上,訪問數度不是一般的慢,幾個簡單的例子,瀏覽器就要完全阻塞好幾妙鐘。正是厭惡這種完全阻塞的現象,我才開發了JSI2。
事實上,現在的一堆堆js框架中,采用XHR同步裝載資源的有不少,JSVM、dojo、a9engine、hax的pies;其中JSVM, dojo都提供打包工具,將可能裝載的腳本打包到啟動文件中,所以也可以避免XHR同步請求。不過這樣也就失去了部分動態裝載的意義了。
總之,我非常討厭這種完全阻塞現象,認為這個嚴重影響用戶體驗。
可能也有些主觀因素把,希望聽聽大家的看法。