如題:
JSA介紹:http://www.javaeye.com/article/77776
posted @
2007-06-05 18:34 金大為 閱讀(307) |
評論 (4) |
編輯 收藏
JSI2 Alpha即將發(fā)布,關于兩類特殊文件的命名方式,想聽聽大家的建議:
包定義文件,原先為 __$package.js
缺點:$符號再linux上處理有點麻煩,通過shell命令創(chuàng)建時需要使用轉義字符(\$)
預裝載緩存腳本(編譯結果,用于支持延遲同步非阻塞式裝載),原先與原文件同名,只是映射到其他目錄.
缺點:同一個包的資源處在不同目錄,發(fā)布,部署都有點麻煩.
現(xiàn)在的修改想法:
方式一:
__[package].js
file.js
file[preload].js
缺點:[]也算特殊字符.
優(yōu)點:看起來比較直觀,也不容易和已有文件沖突.linux系統(tǒng)中,通過控制臺還是可以直接創(chuàng)建的,不用轉義.
方式二:
__package__.js
file.js
file__preload__.js
缺點:看起來沒有上面的直觀.已有別的類庫采用這個名字,不便于編輯工具識別
.
優(yōu)點:無特殊字符.
大家感覺如何?給點建議吧:)
posted @
2007-06-03 14:31 金大為 閱讀(629) |
評論 (3) |
編輯 收藏
JSI是一個簡單、無侵入(被管理的腳本無需考慮JSI的存在)的腳本管理框架, JSI的出現(xiàn),可以做到如下幾點:
* 按需裝載。
* 管理依賴,避免依賴的保露、擴散,提高類庫的易用性。
* 執(zhí)行環(huán)境的隔離,避免名稱沖突。
類庫裝載
動態(tài)裝載類庫是按需裝載的基礎,JSI的裝載方式有三種:即時同步裝載(可能阻塞)、延遲同步裝載(需要編譯)、異步裝載。這里先演示一下最簡單的方式,即時同步導入:
示例:重寫一下jQuery的hello world。
….
<!-- 加入引導腳本 -->
<script src="../scripts/boot.js"></script>
….
<script>
//導入jQuery的$函數(shù)
$import("org.jquery.$");
//使用jQuery的$函數(shù)
$(document).ready(function(){
alert("Hello World");
});
</script>
….
這是默認的導入方式,當能,如果網絡環(huán)境不好,這可能產生阻塞問題。所以JSI2開始增加了仍外兩種導入模式。延遲同步導入,異步導入。具體用法請查看文章后面的導入函數(shù)參考。
依賴管理
Java可以隨意的使用第三方類庫,可是JavaScript卻沒那么幸運,隨著類庫的豐富,煩雜的依賴關系和可能的命名沖突將使得類庫的發(fā)展越來越困難。程序的易用性也將大打折扣。
命名沖突的危險無形的增加你大腦的負擔;隨著使用的類庫的增加,暴露的依賴也將隨之增加,這是復雜度陡增的極大禍根,將使得系統(tǒng)越來越復雜,越來越難以控制。潛在的問題越來越多,防不勝防。
所以,我們建議類庫的開發(fā)者將自己類庫的依賴終結在自己手中,避免依賴擴散,以提高類庫的易用性。
為了演示一下JSI的依賴管理,我們編寫一個復雜一點的類庫:類似Windows XP文件瀏覽器左側的滑動折疊面板(任務菜單)效果。
1.編寫我們的折疊面板函數(shù)(org/xidea/example/display/effect.js):
/**
* 滑動面板實現(xiàn).
* 當指定元素可見時,將其第一個子元素向上滑動至完全被遮掩(折疊)。
* 當指定元素不可見時,將其第一個子元素向下滑動至完全顯示(展開)。
*/
function slidePanel(panel){
panel = $(panel);
if(panel.style.display=='none'){
//調用Scriptaculous Effect的具體滑動展開實現(xiàn)
new Effect.SlideDown(panel);
}else{
//調用Scriptaculous Effect的具體滑動閉合實現(xiàn)
new Effect.SlideUp(panel);
}
}
2.編寫包定義腳本,申明其內容及依賴(org/xidea/example/display/__$package.js):
//添加slidePanel(滑動面板控制)函數(shù)
this.addScript("effect.js","slidePanel",null);
//給effect.js腳本添加對us.aculo.script包中effects.js腳本的裝載后依賴this.addScriptDependence("effect.js",
"us/aculo/script/effects.js",false);
//給effect.js腳本添加對net.conio.prototype包中$函數(shù)的裝載后依賴this.addScriptObjectDependence("effect.js",
"net.conio.prototype.$",false);
3.HTML代碼:
<html>
<head>
<title>重用aculo Effect腳本實例</title>
<link rel="stylesheet" type="text/css" href="/styles/default.css" />
<script src="/scripts/boot.js"></script>
<script>
$import("org.xidea.display.slidePanel");
</script>
</head>
<body>
<div class="menu_header"
onclick="slidePanel('menu_block1')">
面板 1
</div>
<div class="menu_block" id="menu_block1">
<ul>
<li>text1</li>
<li>text2</li>
<li>text3</li>
</ul>
</div>
</body>
</html>
onclick="slidePanel('menu_block1')"這個事件函數(shù)將在我們點擊面板標題時觸發(fā),能后會調用Scriptaculous Effect的具體實現(xiàn)去實現(xiàn)我們需要的滑動折疊功能。
這個效果只是八行代碼,比較簡單,但是它用到了Scriptaculous Effect類庫,Scriptaculous Effect又簡接用到了Prototype類庫,所以,傳統(tǒng)方式使用起來還是比較復雜,有一堆腳本需要導入prototype.js,effects.js,builder.js,更加痛苦的是這些腳本的導入還要遵守一定的順序。
但是,如果我們使用JSI 明確申明了這些依賴,那么使用起來就簡單多了,只一個import就可以完全搞定。
此外 這里還有一個額外的好處,我們類庫中依賴的那些腳本,并不會對外部保露,在頁面上是不可見的,也就是說,這些依賴完全終結在剛才編寫的類庫中,不必擔心使用這些類庫帶來的名稱污染問題。
環(huán)境隔離
眾所周知, Scriptaculous所依賴的Prototype庫與jQuery存在沖突。所以同時使用比較困難。
下面的例子,我們將在同一個頁面上同時使用Scriptaculous和 jQuery 類庫。示范一下JSI隔離沖突功能。
示例頁面(hello-jquery-aculo.html):
<html>
<head>
<title>Hello jQuery And Scriptaculous</title>
<!-- 加入引導腳本 -->
<script src="../scripts/boot.js"></script>
<script>
//導入jQuery
$import("org.jquery.$");
//導入Scriptaculous
$import("us.aculo.script.Effect");
$(document).ready(function(){
//使用jQuery添加一段問候語
$("<p id='helloBox' style='background:#0F0;text-align:center;font-size:40px;cursor:pointer;'>\
Hello jQuery And Scriptaculous</p>")
.appendTo('body');
$('#helloBox').ready(function(){
//使用Scriptaculous高亮顯示一下剛才添加的內容
new Effect.Highlight('helloBox');
}).click(function(){
//當用戶單擊該內容后使用jQuery實現(xiàn)漸出
$('#helloBox').fadeOut();
});
});
</script>
</head>
<body>
<p>文檔裝載后,jQuery將在后面添加一段問候語;并使用Scriptaculous高亮顯示(Highlight);在鼠標點擊后在使用jQuery漸出(fadeOut)。</p>
</body>
</html>
其他話題
JSI組件模型:
頁面裝飾引擎:用于裝飾樸素html元素的框架,實現(xiàn)零腳本代碼的web富客戶端編程,更多細節(jié)請訪問jsi官方網站。
參考:
腳本導入函數(shù)
腳本導入函數(shù)是JSI唯一的一個在頁面上使用的系統(tǒng)函數(shù)。
function $import(path, callbackOrLazyLoad, target )
path 類庫路徑
callbackOrLazyLoad 可選參數(shù),如果其值為函數(shù),表示異步導入模式;如果其值為真,表示延遲同步導入模式,否則為即時同步導入(默認如此)。
Target 可選參數(shù)(默認為全局變量,所以說,這種情況等價于直接聲明的全局變量),指定導入容器。
名詞解釋:
* 自由腳本
通過<script>標記引入或直接編寫的腳本,我們不建議在使用JSIntegration之后,仍舊使用script src導入JSI啟動腳本(boot.js)之外的腳本。
* 托管腳本
通過$import函數(shù)直接或間接加載的腳本。這些腳本將在一個獨立的執(zhí)行上下文裝載,不會污染全局環(huán)境。
* 腳本依賴
若要使用A,需要導入B,則A依賴B。
A、B可以是腳本文件,也可以是腳本文件中的某個腳本元素。
* 類庫使用者
類庫的使用者,您只需再頁面上書寫腳本,導入類庫,編寫自己的簡單腳本,一般情況請不要編寫js文件,那是類庫開發(fā)者做的事.
* 類庫開發(fā)者
在此框架下開發(fā)出方便實用的腳本庫,您需要編寫一些通用腳本,同時設置腳本依賴,做到任何類/函數(shù),導入即可運行。
posted @
2007-06-02 14:16 金大為 閱讀(1631) |
評論 (0) |
編輯 收藏
先申明一下,我討厭Ajax這個名詞。舊藥裝新瓶。(像那個80來歲的楊某一樣令人討厭,呵呵)。
正題:
Ajax所謂的異步加載,為何需要異步,可以說異步操作通常都是一個成熟的程序設計人員會盡力回避的東西。復雜度徒增,不好控制,容易出錯。
但是,這個問題放在瀏覽器上就是另外一個情形,瀏覽器上的腳本+事件通常只有一個線程。那些看是多線程的函數(shù):setTimeout,
setInterval,其實都不會插入或中斷任何一個其他的在執(zhí)行中的任務,而且一旦你的腳本尚在運行,那么不管你是否在掛起等待,所有的事件都將阻
塞。窗口重畫,拖動...也都得靠邊站著,感覺就像是某個程序進入一個死循環(huán)了。
以前得腳本都是做一些簡單得事情,需要的時間,用戶基本上都感覺不到,后來XMLHttpRequest的興起,問題出來了,訪問網絡資源,你得受網速得
限制,如果同步的獲取,那你就等吧,等個幾秒幾分幾十分的,不是不可能。這時瀏覽器可沒那么聰明,站旁邊傻等,什么窗口重畫,移動啊,都裝個沒聽見。
瀏覽器傻了,用戶可不傻,靠,這個網站咋的,吧我的瀏覽器都搞死了?加入黑名單,或者碰到個脾氣好點的,把你辛辛苦苦、沒日沒夜、綿綿數(shù)月敲下來的腳本,一律禁止運行... 傻了把,可憐的腳本程序員。
看似瀏覽器的問題嘛,可是,誰叫你是中年諸葛亮呢,扶不起的阿斗你也得背著,朽木上刻章方顯你的出眾嘛。于是異步操作遍地開花,第N次世界大亂從此開始。
確實這里使用異步操作很有見成效,先告訴xmlhttp后臺加載網絡資源。一邊涼快涼快,加載完了通知一下。喝喝茶,看看報,N+1秒鐘過去了,報告: 001.xml全體元素集合完畢,帳前待命...,ok,..... (機密,隱藏...)。
不錯把,你不必焦急的盯著屏幕上所不期望的白大塊,不用使勁的失望的拖動著沒有的鼠標。你只需要東瞧瞧西瞅瞅,隨意的打發(fā)點時間,一會,東西準備好了,歸你了,愛怎么辦就怎么辦吧。
沒看明白?簡單點說吧,就是把資源加載這一操作放在腳本線程之外,那么就不會有長時間運行的腳本,那么用戶就覺得你的程序響應快。就是是說ajax,其實asynchronism也就這一個地方而已。
記住一點,瀏覽器上單純的腳本程序,本身是不支持多線程的,異步也就無從談起,而現(xiàn)在所說的異步,都不是純粹的ECMAScript,都是利用瀏覽器帶有的某些原生對象實現(xiàn)的。
雕蟲小技而已,結果吹得雞毛滿天飛。眾嘴紜紜之勢,眾目睽睽之下,公雞下蛋,鯉魚上坡,皆有可能。
posted @
2007-06-02 14:11 金大為 閱讀(996) |
評論 (13) |
編輯 收藏
循環(huán)反轉示例:
for(var i = 0;i<data.length;i++){
//
.
}
//反轉后代碼
for(var i = data.length-1;i>=0;i--){
//
.
}
這類優(yōu)化的作用是明顯的,但是具體有多大作用呢?
用一個長度為100 000 的數(shù)組測試一下:
515/313
500/313
516/312
516/328
516/328
可見,循環(huán)反轉后,只需要原來3/5的時間.
但是,這種東西到底有多大價值?FF上200次循環(huán)僅需要1毫秒的時間.所以,個人認為,只要循環(huán)的內容不是太長,使用不算非常頻繁,那么沒有太大必要.
加入循環(huán)的長度需要通過函數(shù)取得,且不變,那么,反轉的效率還是可觀的,在IE上,函數(shù)調用消耗是普通操作的十多倍.
測試代碼:
var incTime = 0;
var decTime = 0;
var inc = 0;
var data = new Array(10*10000);
//while(inc++<50)
{
var t1 = new Date();
for(var i = 0;i<data.length;i++){
}
var t2 = new Date();
for(var i = data.length-1;i>=0;i--){
}
var t3 = new Date();
incTime+=(t2-t1);
decTime+=(t3-t2);
}
prompt("incTime/decTime",incTime +'/'+decTime)
posted @
2007-05-31 12:30 金大為 閱讀(916) |
評論 (5) |
編輯 收藏
在
JSI的實現(xiàn)中,有這樣一種需求,將有自帶命名空間的腳本元素名數(shù)組轉換成沒有命名空間的變量名數(shù)組.
比如 :
['YAHOO.util.XXXX,YAHOO.util.YYYY,YAHOO.event.XX'] ->['YAHOO']
以前一直是較長的一段處理代碼,今天突發(fā)奇想,這個用正則表達式處理效果如何?
于是,就這種處理,分別測試了正則表達式和javascript代碼的效率.
測試數(shù)據(jù)如下(regTime /codeTime):
620/4536
729/4068
719/4250
645/4152
655/4642
FF和IE結果差不多,上面是FF2的數(shù)據(jù)
總結:
經常看見很多地方對正則表達式的效率的懷疑,但是這個問題放在javascript里面,好像情況又不同了. 適當使用正則式,反而可以大大提高效率.
在javascript這類\較慢的解釋型語言里面,少即快,能用原生代碼就不要自己寫.
測試代碼:
var data = [];
for(var i = 0;i<20;i++){
data[i] = "NS"+i/10+'.'+i
}
document.write(
//(data == data.sort()) +"/"+
data +"<hr>")
var i = 0;
var regTime = 0;
var codeTime = 0;
var inc = 0;
var reg = /(\b[\$\w]+)[\$\w\.]*(,\1\b[\$\w\.]*)*/g;
var regResult,codeResult;
while(inc++<100){
var i=0;
var t1 = new Date();
while(i++<100){
regResult = data.join(',').replace(reg,'$1').split(',');
}
var t2 = new Date();
while(i++<200){
codeResult = [];
var flagMap = {};
for(var j=data.length-1;j>=0;j--){
key = data[j];
key = key.substr(0,key.indexOf('.'));
if(!flagMap[key]){
codeResult[codeResult.length] = (key);
//codeResult.push(key);
flagMap[key] = true;
}
}
}
var t3 = new Date();
regTime +=(t2-t1);
codeTime+=(t3-t2);
}
document.write(
"regResult:"+
regResult)
document.write(
"<hr>codeResult:"+
codeResult)
prompt("regTime /codeTime",regTime +'/'+codeTime)
posted @
2007-05-30 13:22 金大為 閱讀(918) |
評論 (0) |
編輯 收藏
一直都認為,javascript的函數(shù)調用是一個相對耗時的操作。
開始
JSI的優(yōu)化,這些問題現(xiàn)在必須認真考慮了,測試一把:
一個簡單的++操作,直接操作和函數(shù)內操作(注,函數(shù)參數(shù)對原始類型是值傳遞,所以這不會影響被傳入的變量,這里測試里面,兩類操作的行為是不一樣的)
FF2測試結果(callTime/opTime):
2871/2582
2919/2675
2734/2704
2953/2516
3732/3346
IE7測試結果:
3140/376
3173/327
3238/247
3265/235
3217/299
通過測試可見,函數(shù)調用的消耗基本可以忽略。每次調用時間僅為:3000/(200*1000*5) ==0.3毫秒 ,這個時間還包含函數(shù)內部的++操作
從示例可見,F(xiàn)F的函數(shù)調用消耗基本可以府略,IE雖然相當于十倍++類簡單操作,但依然不足以重視。
奇怪的是,第一次碰見ie的運行效率高于ff的情況。
測試代碼
var i = 0;
var callTime = 0;
var opTime = 0;
var inc = 0;
function plus(z){z++};
while(inc++<200){
var i=0;
var x = 1;
var t1 = new Date();
while(i++<1000){
plus(x);
plus(x);
plus(x);
plus(x);
plus(x);
}
var t2 = new Date();
while(i++<2000){
x++;
x++;
x++;
x++;
x++;
}
var t3 = new Date();
callTime+=(t2-t1);
opTime+=(t3-t2);
}
prompt("callTime/opTime",callTime +'/'+opTime)
posted @
2007-05-29 18:00 金大為 閱讀(927) |
評論 (0) |
編輯 收藏
前幾天無意中看到一個網友blog上關于這個循環(huán)效率的問題,說要盡量避免使用。
有點害怕,我在
JSI中可是用了不少,呵呵。
測試一下,負擔終于可以放下來了:
測試對象:
一個對象模擬map,測試for in 循環(huán)
兩個數(shù)組,測試for(;;)循環(huán)
連續(xù)4次運行時間比。
957/1278;955/1357;1014/1282;968/1392
明顯,要實現(xiàn)類似map的功能,還是for in 快點。上面的數(shù)據(jù)是ff2上的結果,ie7上也差不多,差距更小一點。
測試代碼:
function C(i){
return i<62?
String.fromCharCode(i+=
i<26?65
:i<52?71//97-26
:-4//48-26-26
)
:i<63?'_'
:i<64?'$'
:C(i>>6)+C(i&63)
}
var map = {};
var arr1 = [];
var arr2 = [];
for(var i = 0;i<1000;i++){
var c = C(i);
map[c] = i;
arr1.push(c);
arr2.push(i);
}
var i = 0;
var mapTime = 0;
var arrTime = 0;
var inc = 0
while(inc++<500){
var t1 = new Date();
for(var n in map){
n = map[n];
}
var t2 = new Date();
for(var j = 0;j<1000;j++){
n =arr1[j];
n =arr2[j];
}
var t3 = new Date();
mapTime+=(t2-t1);
arrTime+=(t3-t2);
}
prompt("mapTime/arrTime",mapTime +'/'+arrTime)
posted @
2007-05-27 17:18 金大為 閱讀(1499) |
評論 (13) |
編輯 收藏
無賴,自己外語太差,就算想去也難辦,呵呵。
懷疑 sourceforge是不是在搞販人服務呢?
posted @
2007-05-27 10:36 金大為 閱讀(139) |
評論 (0) |
編輯 收藏
剛剛修正了一個JSA的bug。
順便測試了一下文本壓縮的性能,和純packer 壓縮,ShrinkSafe+packer壓縮。
壓縮大小:
jquery-jsa-s.js(JSA的語法壓縮):29766
jquery.compressed.js(ShrinkSafe語法壓縮):33992
jquery-jsa-st.js(JSA的語法壓縮+文本壓縮):19526
jquery-packer.js(Packer文本壓縮):20977
jquery.compressed-packer.js(ShrinkSafe語法壓縮+Packer文本壓縮):21839
有點奇怪的是,文本壓縮和語法壓縮是有一定互補性的,但是ShrinkSafe+Packer比單純的Packer文本壓縮效率還低??
我想可能是ShrinkSafe做的一些語法補全(可省略的 {、}、;、),jQuery編碼的風格導致。
Firefox測試數(shù)據(jù)(10次壓縮時間的毫秒數(shù),連續(xù)5回測試數(shù)據(jù))
jquery-jsa-st.js:784
jquery-packer.js:1265
jquery.compressed-packer.js:1529
jquery-jsa-st.js:718
jquery-packer.js:922
jquery.compressed-packer.js:766
jquery-jsa-st.js:753
jquery-packer.js:872
jquery.compressed-packer.js:828
jquery-jsa-st.js:1438
jquery-packer.js:1484
jquery.compressed-packer.js:1735
jquery-jsa-st.js:687
jquery-packer.js:1236
jquery.compressed-packer.js:1234
IE5 測試數(shù)據(jù)(連續(xù)三回測試數(shù)據(jù))
jquery-jsa-st.js:766
--------------------------------------------------------------------------------
jquery-packer.js:9765
--------------------------------------------------------------------------------
jquery.compressed-packer.js:10547
jquery-jsa-st.js:671
--------------------------------------------------------------------------------
jquery-packer.js:9002
--------------------------------------------------------------------------------
jquery.compressed-packer.js:10265
jquery-jsa-st.js:704
--------------------------------------------------------------------------------
jquery-packer.js:8232
--------------------------------------------------------------------------------
jquery.compressed-packer.js:10314
總結
文本壓縮是個比較耗時的操作,像JQuery這樣大的類庫普遍需要接近100毫秒的解壓時間。
如果需要兼容IE5這種老古董,那么最好不要用packer的文本壓縮,太耗時。
JSA1 對文本壓縮做了些改進,表現(xiàn)還可以。
如果要計較腳本文本壓縮后的解壓開銷,建議使用JSA的語法壓縮,配合服務器端的gzip壓縮。
不推薦dojo 的ShrinkSafe,原因是它的幾個安全問題。
posted @
2007-05-24 09:28 金大為 閱讀(966) |
評論 (0) |
編輯 收藏