国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

js編寫的可維護(hù)與性能優(yōu)化

YFan / 964人閱讀

摘要:可維護(hù)解耦采用引入文件的方式取代在頁面寫代碼避免在中創(chuàng)建大量當(dāng)用于插入數(shù)據(jù)時,盡量不要直接插入標(biāo)記。簡化循環(huán)體循環(huán)體是執(zhí)行最多的,所以要確保其被最大限地優(yōu)化,確保沒有某些可以被很容易移除循環(huán)的密集計算。

可維護(hù) 解耦HTML/JavaScript

1、采用引入js文件的方式取代在html頁面寫js代碼
2、避免在js中創(chuàng)建大量html
(1)當(dāng)js用于插入數(shù)據(jù)時,盡量不要直接插入標(biāo)記。一般可以在頁面中直接包含并隱藏標(biāo)記,然后等到整個頁面渲染好之后,就可以用js顯示該標(biāo)記,而非生成它
(2)也可以通過Ajax請求獲得更多要顯示的html,這個方法可以讓同樣的渲染層(PHP、JSP、Ruby等等)來輸出標(biāo)記,而不是直接嵌在js

解耦CSS/JavaScript

盡量不要在js中更改樣式,而是采用動態(tài)更改樣式類,從而做到對于樣式的問題應(yīng)只查看CSS文件來解決,例:

element.style.color = "red";
element.style.backgroundColor = "blue";

更改后:
element.className = "edit";
解耦應(yīng)用邏輯/事件處理程序

每個web應(yīng)用一般都有相當(dāng)多的事件處理程序,監(jiān)聽這無數(shù)不同的事件,然而,很少有能仔細(xì)得將應(yīng)用邏輯從事件處理程序中分離的,如下:

function handleKeyPress (event) {
    if(event.keyCode == 1){
        let target = event;
        let value = 5 * parseInt(target.value);
        if(value > 10){
            document.getElementById("tip-msg").style.display = "block";
        }
    }
}

這個事件處理程序處理包含了應(yīng)用邏輯,還進(jìn)行了事件處理,這種方式的問題有其雙重性
(1)、處理通過事件之外就沒有辦法執(zhí)行應(yīng)用邏輯
(2)、調(diào)試?yán)щy,如果沒有發(fā)生預(yù)想的結(jié)果,并不知道是事件沒被調(diào)用還是應(yīng)用邏輯失敗
(3)、如果后續(xù)的事件需要執(zhí)行相同的應(yīng)用邏輯,那么就必須復(fù)制功能代碼或?qū)⒋a抽到一個多帶帶的函數(shù)中所以就好進(jìn)行兩者的解耦,即一個事件處理程序應(yīng)該從事件對象中提取相關(guān)信息,并將這些信息傳送到處理應(yīng)用邏輯的某個方法中,前面例子重寫如下:

function validateValue (value) {
    value = 5 * parseInt(value);
    if(value > 10){
        document.getElementById("tip-msg").style.display = "block";
    }
}

function handleKeyPress (event) {
    if(event.keyCode == 13){
        let target = event;
        validateValue(target.value);
    }
}

從而使validateValue()中沒有任何東西會依賴于任何事件處理程序邏輯,他只接收一個值,并根據(jù)該值進(jìn)行其他處理
好處:如果事件最初只有鼠標(biāo)事件觸發(fā),那么現(xiàn)在只需少量修改就可以實現(xiàn)按鍵觸發(fā)

避免全局變量

最多創(chuàng)建一個全局變量,讓其他對象和函數(shù)存在其中,如:

//兩個全局變量——避免!!
let name= "bad";
function sayName() {
    alert(name);
}    

//一個全局變量——推薦
let good = {
    name: "nice",
    sayName: function () {
        alert(this.name);
    }
}

多人協(xié)作開發(fā)可以使用命名空間

//創(chuàng)建全局對象
let wrox = {};

//為Tony創(chuàng)建命名空間
wrox.Tony = {};

//為Tony(可以以人名劃分)創(chuàng)建方法
wrox.Tony.sayName = function () {
    ...
};

上述例子,wrox是全局變量,其他命名空間在此之上創(chuàng)建,只要所有人都按這樣寫,那么就不用當(dāng)心不同開發(fā)者創(chuàng)建相同的方法等,因為它存在于不同的命名空間

避免與null進(jìn)行比較

應(yīng)該讓條件與預(yù)想的類型進(jìn)行比較而不是與null

//bad
function sortArray(values) {
    if(values != null){
        ...
    }
}
//good
function sortArray(values) {
    if(values instanceof Array){
        ...
    }    
}
抽離常量
const constants = {
    INVALID_VALUE_MSG:"Invalid value!",
    INVALID_VALUE_URL:"/errors/invalid.php"
}
性能優(yōu)化

因為訪問全局變量要比訪問局部變量慢,因為要遍歷作用域鏈,所以減少花費(fèi)在作用域鏈上的時間,就可以增加腳本的整體新能

避免全局查找
//bad
function updateUI () {
    let imgs = document.getElementsByTagName("img");
    for(let i=0, len=imgs.length; i

上面將document對象保存在doc變量中,然后替換原來的document,與原來相比,只需進(jìn)行一次全局查找,速度肯定更快

循環(huán)優(yōu)化

循環(huán)優(yōu)化基本步驟如下:
1、減值迭代——大多數(shù)循環(huán)使用一個從0開始、增加到某個特定值的迭代器。在很多情況下,從最大值開始,在循環(huán)中的迭代器更加高效。
2、簡化終止條件——由于每次循環(huán)過程都會計算終止條件,所以必須保證它盡可能快。也就是說避免屬性查找或者其他O(n)的操作。
3、簡化循環(huán)體——循環(huán)體是執(zhí)行最多的,所以要確保其被最大限地優(yōu)化,確保沒有某些可以被很容易移除循環(huán)的密集計算。
4、使用后側(cè)試循環(huán)——最常用的for循環(huán)和while循環(huán)都是前測試循環(huán)。而入do—while這種后側(cè)試循環(huán),可以避免最初終止條件的計算

//基本for循環(huán)
for(let i=0;i=0; i--){
    process(values[i]);
}
//再進(jìn)行改造成后測試循環(huán),此處主要的優(yōu)化是將終止條件和自減操作符組合成了單個語句
let i = values.length - 1;
if(i> -1){
    do{
        process(valeus[i]);
    }while(--i>=0)
}
最小語句數(shù)

1、多個聲明變量

//bad
let count = 5;
let color = "blue";
let values = [1,2,3];
let now = new Date();
//good
let count = 5,
    color = "blue",
    values = [1,2,3],
    now = new Date();

2、插入迭代值

//bad
let name = values[i];
i++;
//good
let name = values[i++];

3、使用數(shù)組和對象字面量

//bad
let values = new Array();
values[0] = 123;
values[1] = 456;
values[2] = 789;
//bad
let person = new Object();
person.name = "Tony";
person.age = 18;
person.sayName = function () {
    alert(this.name);
}

//good
let values = [123,456,789];
let person = {
    name: "Tony",
    age: 18,
    sayName: function () {
        alert(this.name);
    }
}
優(yōu)化DOM交互

1、最小現(xiàn)場更新

//bad
let list = document.getElementById("myList"),
    item,
    i;
for(i=0; i<10; i++){
    item = document.createElement("li");
    list = appendChilde(item);
    item.appendChild(document.createTextNode("Item" + i);
}

上述代碼為列表添加了10個項目,每添加個項目時,都有2個現(xiàn)場更新:一個添加

  • 元素,另一個給他添加文本節(jié)點(diǎn),這樣添加10個項目,這個操作總共要完成20個現(xiàn)場更新。
    解決方法:
    1、將列表從頁面上移除,最后進(jìn)行更新,最后在將列表插回到同樣的位置,看似很美好,但這樣做會導(dǎo)致在每次更新的時候它會不必要的閃爍
    2、使用文檔碎片來構(gòu)建DOM結(jié)構(gòu),接著將其添加到list元素中,這個方式避免了閃爍,如下:

    //good,只有一次現(xiàn)場更新
    let list = document.getElementById("myList");
        framgent = document.createDocumentFragment(),
        itme,
        i;
    for(i=0; i<10; i++){
        item = document.createElement("li");
        fragment.appendChild(item);
        item.appendChild(document.createTextNode("Item" + i));
    }
    list.appendChild(fragment);

    2、使用innerHTML
    有兩種方式在頁面上創(chuàng)建DOM節(jié)點(diǎn):使用諸如createElement()appendChild()之類的DOM方法,以及使用innerHTML。對于小的DOM而言,兩者效率差不多,對于大的DOM改動,使用innerHTML要快得多。
    原因:當(dāng)把innerHTML設(shè)置為某個值時,后臺會創(chuàng)建一個HTML解析器,然后使用內(nèi)部的DOM調(diào)用來創(chuàng)建DOM結(jié)構(gòu),而非基于jsDOM調(diào)用,由于內(nèi)部方法是編譯好的而非解釋執(zhí)行的,所以執(zhí)行快得多,所以上面例子還可以優(yōu)化

    let list = document.getElementById("myList"),
        html = "",
        i;
    for(i=0; i<10; i++){
        html += `
  • Item${i}
  • `; } list.innerHTML = html; //tip同樣要避免多次調(diào)用innerHTML,即要做到構(gòu)建好一個字符串然后一次性調(diào)用innerHTML
    使用事件代理

    頁面上的事件處理程序的數(shù)量和頁面的響應(yīng)用戶交互的速度之間是負(fù)相關(guān)的
    任何冒泡的事件都不僅僅可以在事件的目標(biāo)上進(jìn)行處理,目標(biāo)的任何祖先節(jié)點(diǎn)上也能處理,如果可能,在文檔級別附加事件處理程序,這樣就可以處理整個頁面的事件

    注意HTMLCollection

    任何時候要訪問HTMLCollection,不管是一個屬性還是一個方法,都是在文檔上進(jìn)行的一個查詢,這個查詢開銷很昂貴,爾等消費(fèi)不起

    let images = document.getElementsByTagName("img");
        imags,
        i,
        len;
    for(i=0; len=images.length; i
    

    tip:發(fā)生以下情況會返回HTMLCollection對象:
    (1)、進(jìn)行了對getElementsByTagName()的調(diào)用;
    (2)、獲取了元素的childNodes屬性;
    (3)、獲取了元素的attribute屬性;
    (4)、訪問了特殊的集合,如document.forms、document.images

    展開循環(huán)(Duff)

    當(dāng)循環(huán)的次數(shù)是確定的,消除循環(huán)并使用多次函數(shù)調(diào)用往往更快,

    //low
    for(let i=0;i<3;i++){
        process(values[i]);
    }
    //fast,消除建立循環(huán)和處理終止條件的額外開銷
    process(values[0]);
    process(values[1]);
    process(values[2]);

    如果迭代次數(shù)事項不能確定,可以使用Duff裝置的技術(shù)
    Duff:通過計算迭代的次數(shù)是否為8的倍數(shù)將一個循環(huán)展開為一系列語句

    let iterations = Math.ceil(values.length / 8); //向上取整確保結(jié)果是整數(shù)
    let startAt = values.length % 8; //獲取無法通過上面進(jìn)行處理的項,如果values.length為10,那么startAt為2
    let i = 0;
    
    do {
        switch(startAt) {
            case 0: process(values[i++]);
            case 7: process(values[i++]);
            case 6: process(values[i++]);
            case 5: process(values[i++]);
            case 4: process(values[i++]);
            case 3: process(values[i++]);
            case 2: process(values[i++]);
            case 1: process(values[i++]);
        }
        startAt = 0;
    } while (--iterations > 0);

    上面運(yùn)行的結(jié)果是先運(yùn)行startAt次的process(),然后startAt設(shè)置為0,后面循環(huán)都執(zhí)行8次process(),展開循環(huán)可以提升大數(shù)據(jù)集的處理速度。
    do-while循環(huán)分成2個多帶帶的循環(huán)可以讓Duff更快

    let iterations = Math.ceil(values.length / 8); //向上取整確保結(jié)果是整數(shù)
    let startAt = values.length % 8; //獲取無法通過上面進(jìn)行處理的項,如果values.length為10,那么startAt為2
    let i = 0;
    
    if(leftover > 0){           
        do{
            process(values[i++]);
        } while (--leftover > 0);
    }
    do {
        process(values[i++]);
        process(values[i++]);
        process(values[i++]);
        process(values[i++]);
        process(values[i++]);
        process(values[i++]);
        process(values[i++]);
        process(values[i++]);
    } while (--iterations > 0);

    上面代碼讓剩余的計算部分不會在實際循環(huán)中處理,而是在一個初始化循環(huán)中進(jìn)行除以8的操作,當(dāng)處理掉了額外的元素,繼續(xù)執(zhí)行每次調(diào)用8次process()的主循環(huán),這個方法幾乎比原始的Duff裝置快40%
    tip:以上只適用于處理大數(shù)據(jù)集

    其他性能優(yōu)化注意事項

    下面并非主要影響性能的主要問題,應(yīng)用得當(dāng),會有相當(dāng)大的提升
    1、原生方法較快——只要有可能,使用原生方法而不是自己用js重寫一個,因為原生方法是用注入C/C++之類的編譯型語言寫出來的,所以要比js快得多,比如要用Math對象的數(shù)學(xué)運(yùn)算
    2、Swithc語句較快——如果有一系列復(fù)雜的if-else語句,可以轉(zhuǎn)換成單個switch語句則可以得到更快的代碼,還可以通過將case語句按照最可以能的到最不可能的順序進(jìn)行組織,來進(jìn)一步優(yōu)化switch語句。
    3、位運(yùn)算符較快——當(dāng)進(jìn)行數(shù)學(xué)運(yùn)算時,位運(yùn)算符操作要比任何布爾運(yùn)算或者算數(shù)運(yùn)算快,諸如取模,邏輯與和邏輯或都可以考慮用位運(yùn)算替換

    以上內(nèi)容參考自《JavaScript 高級程序設(shè)計(第三版)》
    終于寫完了(~ ̄▽ ̄)~

  • 文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

    轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/99157.html

    相關(guān)文章

    • 前端每周清單半年盤點(diǎn)之 Node.js

      摘要:前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn)分為新聞熱點(diǎn)開發(fā)教程工程實踐深度閱讀開源項目巔峰人生等欄目。對該漏洞的綜合評級為高危。目前,相關(guān)利用方式已經(jīng)在互聯(lián)網(wǎng)上公開,近期出現(xiàn)攻擊嘗試爆發(fā)的可能。 前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn);分為新聞熱點(diǎn)、開發(fā)教程、工程實踐、深度閱讀、開源項目、巔峰人生等欄目。歡...

      kid143 評論0 收藏0
    • 盤點(diǎn) PHP 和 ASP.NET 的10大對比!

      摘要:谷歌,,,雅虎和最近因世界杯獲得龐大觀眾數(shù)量的都在使用。因此,數(shù)據(jù)庫服務(wù)器的能力是毋庸置疑的。微軟的服務(wù)器,服務(wù)器以及未來的更新價格昂貴。更依賴于微軟數(shù)量有限的開發(fā)者做出的改進(jìn)和更新。 【編者按】本文主要針對開源 PHP 和非開源的 ASP.NET 在性能、成本、可擴(kuò)展性,技術(shù)支持和復(fù)雜性等方面進(jìn)行比較。 在網(wǎng)上論壇,總是有成百上千的文章和帖子在討論 PHP 和 ASP.NET,究竟誰...

      hosition 評論0 收藏0
    • 用WijmoJS玩轉(zhuǎn)您的Web應(yīng)用 —— Vue.js

      摘要:相反,我們將專注于將添加到用編寫的簡單應(yīng)用程序中。使用創(chuàng)建應(yīng)用程序。示例應(yīng)用程序有兩個組件應(yīng)用程序和。除在全球率先支持外,現(xiàn)已全面應(yīng)用于等主流框架中。 showImg(https://segmentfault.com/img/bVbcvaQ?w=500&h=278); 概述 在本文中,我們將展示如何將WijmoJS與NPM和Webpack一起使用來創(chuàng)建最流行的基于JavaScript應(yīng)...

      OnlyMyRailgun 評論0 收藏0
    • 前端每周清單第 51 期: React Context API 模式變遷, Webpack W

      摘要:前端每周清單第期與模式變遷與優(yōu)化界面生成作者王下邀月熊編輯徐川前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn)分為新聞熱點(diǎn)開發(fā)教程工程實踐深度閱讀開源項目巔峰人生等欄目。 showImg(https://segmentfault.com/img/remote/1460000013279448); 前端每周清單第 51 期: React Context A...

      Jiavan 評論0 收藏0

    發(fā)表評論

    0條評論

    最新活動
    閱讀需要支付1元查看
    <