跳到主要內容
黯羽輕揚每天積累一點點

JS 程式碼指導原則

免費2015-03-17#JS#Mind#js代码优化#平稳退化#渐进增强

web 前端不像後台那麼直接,前端有很多繁瑣的事情需要處理,比如讓人深惡痛絕的瀏覽器相容性問題。好的 JS 程式碼應該能夠平穩退化,向後相容,而且要經過性能優化。為了寫出好的程式碼,所以有必要遵循一些指導原則,如漸進增強等等

一。什麼是平穩退化?

如果含有 JS 程式碼的網頁在使用者瀏覽器不支援 JS(或者禁用 JS)時,使用者仍然能夠順利瀏覽(網站功能正常,只是視覺效果可能差一些),那麼這個網頁就能夠平穩退化

網頁能夠平穩退化是很必要的,因為 JS 向來名聲不好(各種廣告,各種彈窗,甚至還有 XSS 等等陰暗的東西),所以有一個使用者群是習慣禁用瀏覽器的 JS 支援的,這個使用者群可能不大,但是作為編碼人員應該儘量讓自己的程式碼儘可能的完善(就像培養自己的孩子一樣),我們應該考慮到這種情況,給各種使用者完美的體驗

如果上面的理由還不夠充分,那麼可能有一點更值得重視:SEO,也就是搜尋引擎優化,想讓自己的網站在搜尋結果裡靠前些,就有必要做好 SEO,搜尋引擎的搜尋機器人無法理解 JS 程式碼的含義,所以搜尋機器人相當於一個堅持使用老式瀏覽器(不支援 JS)的使用者,顯然,這個使用者很重要

二。怎樣才能平穩退化?

要平穩退化只需要遵循一個原則:漸進增強

所謂的“漸進增強”就是用一些原始的可靠的方法去實現最基本最重要的功能,先保證功能的完整,再用一些額外的資訊層去包裹原始頁面(實現顯示特效,實現更好的視覺效果和使用者體驗),即便衣服被屏蔽了,功能仍然完整,只是可能不好看而已

把 JS 程式碼與 HTML 程式碼徹底分離就可以實現“漸進增強”,HTML 是功能完整的原始層,外部 JS 程式碼是一個華麗的外衣(說起來有點像 CSS,不過確實是這樣,JS 功能很強大,但如果過分依賴於 JS 程式碼就顛倒了主次)

三。什麼是向後相容?

向後相容是指 JS 程式碼要能夠相容低版本的 DOM(有些瀏覽器可能不支援最新版本的 DOM,意味著某些 DOM API 將無法使用),例如:

最常用的 DOM API 可能是這些:

document.getElementById();
document.getElementsByTagName();
document.getElementsByClassName();//HTML5 DOM 中的新特性

但可能有的瀏覽器根本不支援這些方法,或者說只支援一部分,那麼頁面將因為 JS 程式碼出錯而無法訪問,或者頁面功能不再完整

之前有一種用來保證向後相容的方法是“瀏覽器嗅探”技術,也就是通過 BOM 去問瀏覽器:“你支不支援這個 DOM API?”,因為瀏覽器實在太多了,所以一句很簡單的 JS 程式碼都需要被很多層瀏覽器嗅探程式碼包裹起來,導致我們的程式碼變得非常臃腫

瀏覽器嗅探技術其實在 CSS 中依然存在,當然 CSS 無法通過 BOM 獲取瀏覽器特徵,所以採用了相對被動的一種方式:

/*設定透明度為 0.75*/
filter: alpha(opacity =   25); /\*支援 IE 瀏覽器\*/
-moz-opacity: 0.25; /\*支援 FireFox 瀏覽器\*/
opacity: 0.25; /\*支援 Chrome, Opera, Safari 等瀏覽器\*/

DOM 發展到現在已經不需要用瀏覽器嗅探技術來保證向後相容了,我們可以這樣做:

if(document.getElementById){
    document.getElementById();
}
if(document.getElementsByTagName){
    document.getElementsByTagName();
}
if(document.getElementsByClassName){
    document.getElementsByClassName();//HTML5 DOM 中的新特性
}

這種更好的方式叫做“物件檢測”技術,雖然還是不太完美(要想完美,除非瀏覽器市場被大一統了..),不過已經比瀏覽器嗅探要好很多了(至少不需要因為市場上出現一種新的瀏覽器而修改 JS 程式碼),物件檢測不再依賴 BOM,靠 DOM 自己檢測瀏覽器是否支援指定的 DOM API

四.JS 性能優化技巧

  1. 尽量少 JS 訪問 DOM
  2. 盡量減少 HTML 標記
  3. 合併 JS 腳本
  4. script 標籤的位置
  5. 壓縮 JS 程式碼

1. 優化前:

for(var i = 0;i < document.getElementsByTagName("a");i++){
    if(document.getElementsByTagName("a")[i].getAttribute("title") == "main"){
        //do something
    }
}

優化後:

var elems = document.getElementsByTagName("a");
for(var i = 0;i < elems.length;i++){
    if(elems[i].getAttribute("title") == "main"){
        //do something
    }
}

每次呼叫 DOM 方法獲取標籤物件內部都是對 DOM 樹做一次完全搜尋,這是非常昂貴的操作,盡量減少 DOM 訪問可以提高性能

2. 優化前:

<div>
    <div>
        <div>
            <div>
                <div>
                    <p>
                    正文
                    </p>
                </div>
            </div>
        </div>
    </div>
</div>

優化後:

<p>
正文
</p>

這個例子可能有些極端了,不過也足夠說明問題了,HTML 程式碼應該盡量簡潔(能夠達到預期的表現效果就好)

3. 優化前:

<scrpit src="./scripts/A.js" type="text/javascript"></script>
<scrpit src="./scripts/B.js" type="text/javascript"></script>
<scrpit src="./scripts/C.js" type="text/javascript"></script>

優化後:

<scrpit src="./scripts/All.js" type="text/javascript"></script>

瀏覽器在載入頁面時每遇到一個 script 標籤,如果標籤指向外部腳本檔案,都需要發送請求載入外部檔案,如果 script 標籤過多,這筆開銷將是無法忽視的,所以應該把 JS 程式碼全部放在一個外部檔案中,用一個 script 標籤來載入

4. 優化前:

<head>
    <script></script>
</head>

優化後:

<body>
    html code
    <script></script>
</body>

也就是說把 script 標籤放在 body 的末尾載入最快,而且放在這裡並不影響 window.onload 等事件的觸發,至於為什麼放在這個位置最快,可能和瀏覽器解釋 HTML 程式碼的順序有關(先載入 head 部分,如果 head 太大,會導致使用者等待了很久仍然看不到 body 內容)

5. 優化前:

var elems = document.getElementsByTagName("p");
for(var i = 0;i < elems.length;i++){
    //do something
}

優化後:

var elems=document.getElementsByTagName("p");for(var i=0;i<elems.length;i++){}

嗯,沒錯,優化後的程式碼不是給人讀的,不過雖然不易讀,但這樣的程式碼體積小,使得外部檔案體積縮小,當然能夠提高性能

P.S. 這個工作有專門的工具來幫我們做,比如 JSMin 等等

參考資料:《JavaScript DOM 變程式設計藝術》

評論

暫無評論,快來發表你的看法吧

提交評論