一。什麼是平穩退化?
如果含有 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 性能優化技巧
- 尽量少 JS 訪問 DOM
- 盡量減少 HTML 標記
- 合併 JS 腳本
- script 標籤的位置
- 壓縮 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 等等
暫無評論,快來發表你的看法吧