高性能Javascript筆記

.) 下載並執行javacript會阻塞頁面渲染,所以比較推薦js腳本放在頁面底部,在</body>標籤上邊...
.) 儘可能減小script標籤。若是外鏈多個script文件,能合併就合併(利用合併的工具),一樣適用內嵌的。
.) 動態腳本加載,無阻塞的比較好的解決方案:建立script DOM
好比:javascript

var script = document.createElement("script");
script.type = "text/javascript";
//Firefox, Opera, Chrome, Safari 3+ 
//js文件src下載完的觸發事件
script.onload = function(){
  alert(1);
};
script.src = "jquery.js";
document.getElementsByTagName("head")[0].appendChild(script);

 

.) 另外一種無阻塞載入,利用xhr對象獲取腳本注入,這種方法不能跨域獲取(--ajaxphp

 var xhr = new XMLHttpRequest();
    xhr.open("get", "file1.js", true);
    xhr.onreadystatechange = function(){
        if (xhr.readyState == 4){
            if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){
                var script = document.createElement ("script");
                script.type = "text/javascript";
                script.text = xhr.responseText;// 至關於內聯聊本的<script>標籤
                document.body.appendChild(script);
            }
        }
    };
    xhr.send(null);

 

事件委託:前端

dom以下所示,java

span上都要有點擊事件的反饋。若是在每一個span上綁定click事件的話,當li不少時候,這樣比較浪費性能。
事件綁定佔用了處理時間,瀏覽器須要跟蹤每一個事件處理器,佔用了更多內存。
此時可使用事件委託。利用冒泡機制,在其父節點,好比只須要在ul上監聽一個點擊事件。而後判斷節點哪一個是哪一個就ok了。node

<div>
    <ul id="ul">
        <li>
            <span id="a">aaaaa</span>
        </li>
        <li>
            <span id="b">bbbb</span>
        </li>
        <li>
            <span id="c">ccccc</span>
        </li>
        <li>
            <span id="d">ddddd</span>
        </li>
    </ul>
</div>

<script type="text/javascript">
    $('#ul').click(function(e){
            var target = e.target;
           // 只有點擊的是span標籤才觸發事件
            if(target.nodeName.toLowerCase() != 'span'){
                return false;
            }
            var id = target.id; // 判斷目標對象是哪一個span
            switch(id){
                case 'a': alert(1);break;
                case 'b': alert(2);break;
                case 'c': alert(3);break;
                case 'd': alert(4);break;
            }

        });
</script>        

 

 

 

字符串鏈接;jquery

str += "one" + "two";

str += "one";
str += "two";

str = str + "one" + "two";

第一行代碼比較浪費,內存須要分配一個臨時字符串來鏈接 "onetwo",而後再連str。ajax

剩下兩種方式,則不須要內存額外分配變量。編程

 

 

做用域鏈和原型鏈得知,一個全局變量在局域使用,最好是賦值給局域變量。鏈上遠的變量查找更耗時,更消耗性能。跨域

 

在操做dom集合(類數組而不是數組)的時候,涉及到length,儘可能把這個集合的length賦值給一個變量,而後在循環裏使用這個變量。遍歷集合沒有遍歷數組快。數組

 

大多數時候不必使用eval()和Function(),每次調用eval()時都要建立一個新的解釋器/編譯器示例。
儘可能避免使用他們。至於setTimeout()和setInterval(),建議傳入函數而不是字符串做爲第一個參數。好比:

setTimeout(function(){
    sum = a+b;
}, 100);

 

使用Object/Array時,建議使用直接量,這樣更快。
好比:

var obj = new Object();
obj.name = 'a';
obj.age = 12;

// 更推薦這種方式:
var obj = {
name: 'a',
age: 12
};

// ============
// 數組好比:
var arr = new Array();
arr[0] = 'a';
arr[1] = 'b';

// 更推薦這種:
var arr = ['a', 'b'];

 

不要重複工做:
好比根據一個判斷(好比這裏的 a 和 b 大小比較)處理一個邏輯:

var a=1;
var b=2;
function test(){
    if(b>a){
       xxx;// 幾行代碼
    } else {
       yyy;//
    }
}

好比這個 test() 函數在頁面上可能會頻繁遭到調用,那麼每次都要去判斷 a 和 b 的大小(若是是更復雜的邏輯判斷,那麼頻繁調用必定會浪費性能)。那麼不如在代碼中從新覆蓋這個 test() 函數:

function test(){
    if(b>a){
       test = function(){// 從新給test賦值
           xxx;
        };
    } else {
        test = function(){
           yyy;
        };
    }
    test();// 固然結尾不要忘記執行
}          

 

這樣的話,下一次再去調用這個test()的話,直接就是了。


數字運算的話,能夠多考慮下,是否能夠按位運算。好比奇數偶數這個...和1按位與操做。

儘可能使用原生js,比較原生的都是js引擎低級編程語言編譯好的,要更快。

 


Ajax:

經常使用的向服務器請求數據的方法:
1. XMLHttpRequest(XHR) 最經常使用的技術
2. 動態腳本注入
3. Multipart XHR

1). xhr(ajax經常使用技術,IE低版本要使用 ActiveXObject )是最經常使用的,它容許異步發送和接收數據。瀏覽器支持好,get、post方式都可,能夠讀取http響應頭信息和響應文本。缺點不能跨域。
代碼:

var url = '/data.php?a=1&b=2';
var req = new XMLHttpRequest();

req.onreadystatechange = function(){
    if(req.readyState === 4){// 4表示整個響應接收完畢;3表示接收到部分信息,還沒完
        var responseHeaders = req.getAllResponseHeaders();// 獲取響應頭信息
        var data = req.responseText;// 獲取響應文本
        // 邏輯處理
        // ...
    }
}

req.open('GET', url, true);// true表示異步
req.setRequestHeader('', '');// 能夠設置請求頭信息
req.send(null);// 發送請求

 

2). 動態腳本注入
這個方法利用動態建立 script 元素來請求數據。它克服了xhr最大限制:能夠跨域請求。這固然算是個Hack。

xhr的缺點:不能夠設置請求頭信息;也只能使用get方式;須要等這個腳本下載完,才能訪問它們;返回的數據須要封裝在函數裏。
由於響應信息是腳本標籤的源碼(script),所以他必須是可執行的javascript代碼,因此數據格式須要封裝在函數裏,或者說調用一個函數。
代碼:

var scriptEle = document.createElement('script');
scriptEle.src = 'http://xxx/test.js';// 能夠請求與當前腳本所在不一樣域的文件。
document.getElementsByTagName('head')[0].appendChild(scriptEle); // 在head頭部插入腳本
function callfun(data){
    // 接收到服務端過來的 data
    alert(data.a);
}


// test.js 文件內容
callfun({a:1,b:'qq'});// 數據被包含在回調函數裏。

 

 

向服務器傳輸數據:
一種xhr的技術,還有一種信標的方法。
所謂信標,就是建立一個Image對象,利用屬性src向服務器傳輸數據。然而這種方法,效率雖高,可是存在侷限性,通常只是像服務器傳輸數據,而不關心返回結果(固然服務端的確能夠返回一個圖片,而後前端根據圖片的好比寬度來判斷邏輯,這個寬度也能夠算是服務端的返回狀態。不過通常使用這種方法,不考慮服務端返回結果...),並且src表示也只能以get方式傳輸,而且參數長度也有所限制。
代碼:

(new Image()).src = 'http://www.test.com/xxx.php?a=1&b=x';// 傳輸了a、b兩個參數值過去

 

 

-

相關文章
相關標籤/搜索