前端開發代碼優化


 

前端開發規範手冊

參考:https://www.w3cschool.cn/webdevelopment/index.htmljavascript

一、htmlcss

  1.1  標籤中屬性值統一使用 雙引號html

<!-- Not recommended -->
<span id='j-hook' class=text>Google</span>

<!-- Recommended -->
<span id="j-hook" class="text">Google</span>

二、css前端

  2.1   模塊組織html5

    2.1.1   Components 最少以兩個單詞命名,經過 - 分離,例如:java

  • 點贊按鈕 (.like-button)
  • 搜索框 (.search-form)
  • 文章卡片 (.article-card)

三、jsweb

  3.1函數/方法註釋ajax

  1. 函數/方法註釋必須包含函數說明,有參數和返回值時必須使用註釋標識。;
  2. 參數和返回值註釋必須包含類型信息和說明;
  3. 當函數是內部函數,外部不可訪問時,可使用 @inner 標識;
/**
 * 函數描述
 *
 * @param {string} p1 參數1的說明
 * @param {string} p2 參數2的說明,比較長
 *     那就換行了.
 * @param {number=} p3 參數3的說明(可選)
 * @return {Object} 返回值描述
 */
function foo(p1, p2, p3) {
    var p3 = p3 || 10;
    return {
        p1: p1,
        p2: p2,
        p3: p3
    };
}

   3.2性能優化正則表達式

    避免沒必要要的 DOM 操做算法

      瀏覽器遍歷 DOM 元素的代價是昂貴的。最簡單優化 DOM 樹查詢的方案是,當一個元素出現屢次時,將它保存在一個變量中,就避免屢次查詢 DOM 樹了。

// Recommended
var myList = "";
var myListHTML = document.getElementById("myList").innerHTML; for (var i = 0; i < 100; i++) { myList += "<span>" + i + "</span>"; } myListHTML = myList; // Not recommended for (var i = 0; i < 100; i++) { document.getElementById("myList").innerHTML += "<span>" + i + "</span>"; }

即:每次DOM對象都保存到一個變量中。

四、 


 

可維護的JavaScript代碼

一、.全部的 變量和函數的聲明在做用域的最前面

二、全局做用域的變量儘量少,有些函數須要用到函數外面一層的變量時,可使用閉包函數把這個變量放到函數內,隔絕全局變量。

   全局做用須要變量的話能夠設置一個全局做用域的對象( glob$ = { } ),其它的變量掛在這個對象下。

三、閉包函數中最好不雅設一個變量指向DOM對象,DOM對象的屬性再指向這個閉包函數內的對象。(防止內存溢出)

四、事件綁定用onclick建立事件,會被同名覆蓋掉,

 


 

高性能的JavaScript

1、加載和執行

把js放在</body>結束標籤以前而不是<head></head>標籤內部可以避免瀏覽器阻塞,提高用戶體驗,已經算是一個常識。這個常識的背後,涉及到了瀏覽器單進程的概念。

事實上,多數瀏覽器使用單一進程來處理用戶界面(UI)刷新和javascript腳本執行,因此同一時刻只能作一件事。

這裏說的用戶界面刷新,指的是咱們「所能看到的UI」變化(好比點擊一個按鈕,會出現按鈕被按下去的效果)。換句話來講,處理UI就沒法處理javascript,反之亦然。因此若是一份運行時間很長的js腳本放在頁面頂端,會阻塞以後頁面的下載和渲染,給用戶的感受就是「頁面一片空白卡死不會動」。

雖然如今網速和瀏覽器的效率已經獲得了巨大的提高,但隨着移動端的興起以及前端框架如VueReact的大量使用,這個問題仍是很是值得咱們注意的。

2、數據存取

首先對於數據的存取,有如下這麼一句關鍵:

每個js函數都會帶有一個叫作[[Scope]]的內部屬性,也就是該函數的做用域鏈,它決定了哪些數據能被函數訪問。

書上詳細介紹了做用域鏈執行上下文活動對象全局對象閉包等概念,在這裏就不進行復述了。用我本身理解的話來講,就是一個函數若要使用一個變量,它會從最近的地方,也就是定義在函數內部的局部變量裏面去找;若沒有找到,則往更遠處的全局變量(或者上一級做用域)裏面去找。偏偏是這個「找」的過程,產生了性能的問題。書上使用了「解析標識符」來表述「找」這個動做,而js性能偏偏是隨着解析標識符深度的增長而下降,因此在最佳實踐裏,每每是經過把一個較深的變量賦值給一個局部變量,在函數內部直接調用這個局部變量來提高性能。

說完變量,就到了方法。在js中一切皆對象,然而js的對象是基於原型而來,這就引出了一個原型鏈的概念。與前文關於解析標識符的原理相似,要調用一個對象中的方法,首先會從這個對象實例中查找,若找不到,則會沿着其原型鏈一步一步由近到遠地往上查找,其性能也是隨之降低的。

另外,書上也討論到了關於「嵌套成員」的問題。好比window.location.href,它會先找到window對象,而後查找嵌套於內的location對象,再找到這裏面的href屬性,前先後後套了多層,在性能上也有着必定的花銷。因此在實際的編碼過程當中,咱們更多時候會面對的每每是這種嵌套成員的問題,時刻記得緩存對象成員的值,在執行完畢後利用cacheObj = null的方式釋放緩存,能夠有效地提升性能,以下例子:

// bad document.querySelector('.xxx').style.margin = 10 + 'px' document.querySelector('.xxx').style.padding = 10 + 'px' document.querySelector('.xxx').style.color = 'pink' // good let xxxStyle = document.querySelector('.xxx').style xxxStyle.margin = 10 + 'px' xxxStyle.padding = 10 + 'px' xxxStyle.color = 'pink' xxxStyle = null

3、瀏覽器中的DOM

這一章節詳細介紹了關於dom操做的一系列問題。首先要明確一個知識點就是dom操做是具備「天生就慢」的問題。爲何會如此呢?由於在瀏覽器裏面,處理html和js是兩套不一樣的機制,他們經過接口來進行聯繫的。引用書中的原話,就是能夠把html和js理解爲兩座島,他們之間須要一座橋來進行溝通,而過橋則會產生時間與成本上面的開銷,也所以引發了性能的問題。這一章節經過分析不一樣的dom操做函數,來綜合對比了各類方法的速度。

dom操做每每容易引發瀏覽器的重繪與重排。重排,指的是頁面的佈局和幾何屬性改變時所發生的事情;重繪,是指把dom元素繪製到屏幕上面的過程。

會形成性能問題的,每每來自於重排,由於瀏覽器須要從新計算頁面全部元素的大小與位置,而後把它們安置在正確的地方。因此,要提高頁面的性能,很重要的一個舉措就是避免頁面的重排。

值得注意的是,並不是只有在修改頁面元素的大小和位置的時候纔會引起重排,在獲取的時候瀏覽器也會出發重排,以返回正確的值。

然而不少時候咱們不得不直接操做dom,儘管它們會引發重排和重繪。書上給出了幾個方案,都能有效提高性能。其實方法和上文關於js緩存局部變量的方法相似,也是經過緩存的機制,減小對於dom元素屬性的查找,以及批量修改變量再一次性更新dom的辦法去減小查詢與修改。

除此之外,讓元素脫離文檔流也是一個很好的方法。由於元素一旦脫離文檔流,它對其餘元素的影響幾乎爲零,性能的損耗就可以有效侷限於一個較小的範圍。

講完重排與重繪,往dom元素上綁定事件也是引發性能問題的元兇。利用瀏覽器自帶的冒泡或捕獲機制,能夠經過事件委託的方式減小事件處理器的數量,從而把性能優化得更好。

4、算法和流程控制

這一章首先分析了幾種循環類型,結論是隻有for-in循環的性能最慢,由於每次迭代都會同事搜索實例或原型屬性,致使其性能只有其它類型速度的1/7。
循環在代碼中很是常見,既然沒法避免,則須要經過儘可能減小循環次數,減輕每次循環的工做量的方式提高性能。

對於條件語句if else或者switch,其性能在現實中並無太大區別,關鍵是要正確處理語義化的需求。有的時候也可使用查表法進行。

對於遞歸算法,最好的提高性能方法是緩存上次執行的結果,在下一次遞歸的時候直接引用而非從頭開始計算。

5、字符串和正則表達式

6、快速響應的用戶界面

前面五章都是針對JS原生的語法分析性能問題,從這一章開始分析針對用戶界面的可感知性能問題。

因爲瀏覽器是單線程運做的,在處理UI事件的時候沒法處理js事件,反之亦然,因此對於耗時過長的js任務來講,可使用定時器的方法使其讓出線程控制權,讓瀏覽器優先處理UI事件以提高用戶體驗。

html5新增的web worker容許多開線程,意味着耗時較長、性能損耗較大的js任務能夠放到web worker中進行,而無需阻塞瀏覽器UI線程的執行。值得注意的是,web worker沒法使用瀏覽器相關的資源,因此沒法用以進行dom操做等。

7、Ajax

ajax技術已是現在的主流技術,在這裏就無需贅述了。書上關於其性能優化的內容,多集中在瀏覽器資源緩存上。若是可以有效利用瀏覽器的緩存機制,能夠大大減小與服務端的交互,提高性能。

書上沒有說起的是如今逐漸開始流行的fetch API,關於這方面的性能的問題也值得咱們研究。

相關文章
相關標籤/搜索