為網站相容性最佳化做好準備

現在要開發網站應用程式,隨著網頁新技術不斷演進、瀏覽器功能不斷強化,網站開發人員開發網站用的技術也愈來愈多元,大多數經營較久的網站可能就會累積許多「歷史陳跡」——有些程式是多年前寫的,有些是採用最新技術塞入的(還有一些是從網路上找來的片段複製貼上),所幸目前的現代化的瀏覽器行為及標準逐漸一致,所以現在正是一個簡化網站程式碼、優化網站相容性的時刻,以下針對幾個簡單的方法說明提升網頁相容性其實是非常容易的。

TechDays 2015 UWP302 演講

1. 使用新的 HTML 標準標籤

<!DOCTYPE> 文件標準宣告

時至今日,還是許多網站沒有在頁面的開頭宣告頁面所使用的 HTML 標準,因為在 W3C 的 HTML 4.01 標準(已經是西元 1999 年的事了)出來之前,沒有特別定義網頁元素繪製的方式,各家瀏覽器自行定義及實作,後來為了統一所有瀏覽器的行為,W3C 的標準中建議在網頁開頭以 <!DOCTYPE ...> 的語法宣告這份網頁用到的 HTML/XHTML 的標準版本,所以各家瀏覽器看到這樣的宣告字樣,就會以一致的行為來繪製網頁元素,同樣地,如果發現網頁沒有標示這樣的宣告,就會視為這個網頁是用標準出來前的模式(Quirks 模式)來繪製網頁。(TODO: 看比較)

依照現在的瀏覽器市佔情形,網頁標準的宣告只需要使用這個語法(大小寫字母皆可):

 <!DOCTYPE html>

這樣就好了,比起過去在 HTML4.01 還是 XHTML 1.0 時都簡化了非常多,只要網頁的第一行有這段宣告,就可以確保網頁瀏覽器是以(HTML5 的)標準模式來繪製頁面。

避免使用相容性模式

許多網頁開發人員會在網頁中加入一個 <meta> 標籤設定 X-UA-Compatible 的標頭,強制要求瀏覽器以某個版本的瀏覽器(以 Internet Explorer 居多)的行為來呈現,像下面這個例子是強迫(IE)瀏覽器以 IE7 的行為來呈現:

 <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" >

這樣的作法,會導致即使用戶是使用了較新版本的 IE(如:IE9, 10, 11),明明已經新增較多的網頁標準,而且也改良了繪製引擎提升網頁速度,但被強制使用 IE7 的模式來運作,不但用不到這些新標準的功能,還會降低網頁操作的效能,所以建議不要使用設定 X-UA-Compatible 的語法,拿掉您頁面中使用到類似語法的部份,讓瀏覽器以最新最好的瀏覽器引擎來呈現網頁內容,也會讓用戶有更好的效能及操作體驗。

 

2. 使用較新版本的 JavaScript 函式

為了效能及穩定考量而升級

現代化網頁開發,或多或少都會使用各式各樣的 JavaScript 函式庫,像是 jQueryAngularJSReact 等等,尤其是 jQuery 在大多數網站上都看得到使用的狀況,而若要善用這些方便的 JavaScript 函式庫,也應該要關注這些函式庫的版本更新是否修正了一些 bugs、提升了一些函式的執行效能。以 jQuery 為例由於 jQuery 竄紅得早,所以許多網站可能還使用較舊的 jQuery 版本( 所謂的舊,是比相容 HTML5 的 jQuery 1.6 還舊的版本,這還已經是 4 年前的函式庫了 ),這些舊的 jQuery 版本因為時代背景,不可能對於 HTML5 或是現在眾多的行動裝置瀏覽器做了最佳化(因為這些 JavaScript 函式庫也是讓瀏覽器來執行啊),以目前最新的 jQuery 1.11.3 及 2.1.4 為例,都有針對像是 iOS 的環境做了修正。所以,同樣為了讓新時代的瀏覽器得以有更好的效能,建議升級至較新版本的 JavaScript 函式庫,以 jQuery 為例就建議升級至少 1.6.4 以上的版本。


jQuery 1.7 發佈時所宣稱的效能提升示意圖

以 jQuery 正在計劃推出的 jQuery 3.0 為例,就做了不少提升效能的改變,像是優化 $.show()$.hide() 的程式碼提高元素顯示或隱藏的效能、使用新的 requestAnimationFrame API 來減少動畫操作對頻繁佔用 CPU、還有提高選擇器的效能最高可達 17 倍等等,所以升上新版本的 JavaScript 函式庫,其實可以得到更多更好的效能,甚至是大神們的最佳作法!

確保相容性及最新修正版

當然,在升級 JavaScript 函式庫時,除了要注意函式庫的瀏覽器相容性策略(比方說 jQuery 2.x 就不相容 IE6/7/8,不過還是會保有 jQuery 1.x 的發展來支援)之外,就是不論用了哪一個主要版本,一定要升到最新的次要版本以確保 bug 降到最少,舉例來說,若 jQuery 要用 1.6,就用 1.6.4 的版本、要用 jQuery 1.7 就用 1.7.2 版本,以此類推,可以在這一頁看到所有版本的 jQuery 以方便挑選。

推薦作法

如果有使用 bower 這類工具來做前端開發套件的管理,可以在 bower.json 中使用下列的設定以確保 jQuery 會使用到最新版本:

 {
  "name": "myweb",
  "dependencies": {
    "jquery": "latest"
  }
}

 

3. 避免依據瀏覽器版本來開發

在幾年前,瀏覽器版本更新的速度並不快,而同一版本下的瀏覽器功能也較為固定,比方說較舊的 Internet Explorer 在處理事件時是使用 attachEvent 這個函式,而在 IE9 之後已經支援標準的 addEventListener 的語法,不過很多網頁開發人員喜歡使用下列的語法來決定要不要使用某個 API,或是特別為某個版本的瀏覽器做特殊的操作:

 // 不推薦的作法
var btn = document.getElementById('my-button');
if (navigator.userAgent.indexOf('MSIE') > -1) {
  btn.attachEvent('onclick', onClick);
} else {
  btn.addEventListener('click', onClick, false);
}

上面這段程式碼就是用判斷瀏覽器的方法來決定要用哪個 API,但如果這段程式跑到 IE9 以上就會發生問題,因為現在各家瀏覽器更新版本的速度都非常快,開發人員如果一直盯著某個版本才支援某個功能的話,在程式碼的撰寫上會變得冗長難以維護,而且可能有些功能在某個瀏覽器版本就已經實作,結果開發人員沒有追蹤到,就採用了過時或者是效能較差的寫法。所以應該要執行某一段程式碼時,應該要以瀏覽器是否有該物件的測試方式來判斷是否要執行,而不是用瀏覽器的版本來進行判斷。如果還是要支援舊 IE 的話,應該要調整為:

 // 比較好的作法
var btn = document.getElementById('my-button');
if (!btn.addEventListener) {
  btn.attachEvent('onclick', onClick);
} else {
  btn.addEventListener('click', onClick, false);
}

或是判斷能不能使用新 HTML5 API,比方說 LocalStorage API:

 if ('localStorage' in window) {
  // 執行 localStorage 的相關 APIs
}

這樣的程式寫法就能讓程式碼自己去適應(adaptive)瀏覽器是否支援各種 API。

 

4. 減少使用特定前置詞的 CSS 語法

因為 CSS 3 中有很多新的樣式語法,但各家瀏覽器的實作不一,所以有一些的 CSS 語法會帶有瀏覽器前置詞,像是 -webkit-linear-gradient-moz-transition-ms-animation 等等,目前常見的前置詞有:

前置詞 瀏覽器
-webkit-* WebKit, Safari, Chrome, Opera (version 15 之後)
-moz-* Mozilla Firefox
-ms-* Internet Explorer
-o-* Opera (version 14 以前)

如果使用前置詞的方式像是這樣:

 .my-background {
  background: -webkit-linear-gradient(red, blue);
}

這樣的 CSS 語法只會讓 Safari 及 Chrome 瀏覽器的使用者看到漸層色彩的效果,對於 Firefox、Internet Explorer 等其它瀏覽器就會因為不認得這樣的語法而看不到漸層效果,事實上它們是支援用 CSS 做漸層色彩的,所以一個習慣良好的寫法應該要是:

 .my-background {
  background: -webkit-linear-gradient(red, blue);
  background: -o-linear-gradient(red, blue);
  background: -moz-linear-gradient(red, blue);
  background: -ms-linear-gradient(red, blue);
  background: linear-gradient(red, blue);
}

改成上面這樣之後,各個瀏覽器就會看到自己認得的語法而做正確的顯示,事實上新版本的瀏覽器們已經支援許多 CSS 3 的標準語法(上面的 background: linear-gradient(red, blue); 這段)而不需要加上前置詞,如果不需要支援太舊的瀏覽器,也可以只要留下標準語法即可,像是這樣:

 .my-background {
  background: linear-gradient(red, blue);
}

講結論,要讓 CSS 3 的語法順利運行:要加前置詞時就不要忘掉要把其它瀏覽器家族加上,不然就是只使用標準語法來寫 CSS 樣式。另外順帶一提的是,就要記得第一點提過的:使用正確的 doctype 宣告、並且拿掉 X-UA-Compatible 的設定

 

5. 減少對外掛程式的依賴

過去會需要在網頁上另外靠外掛程式如:Java、Flash 或是 Silverlight,多半是因為想要進行一些原本在 HTML 4.01 時代無法完成的動作,像是播放多媒體影音檔案、同時上傳多個檔案、2D/3D 繪圖等等,但隨著瀏覽器對於新的網頁技術(如:HTML5)支援度逐漸成熟,這些原本要靠著外掛程式才能完成的,現在幾乎都可以靠著新的網頁技術以 HTML/CSS/JavaScript 來實現,像是用 <video><audio> 標籤來播放影音檔案、<canvas> 做繪圖等等都已經不是新技術了,所以現在還需要使用外掛程式才能讓網頁運作的必要性也降低了,更何況多數的行動裝置瀏覽器根本就不支援外掛程式,所以也是可以再次檢視網頁是不是真的要用外掛程式來處理。

結論

過去幾年,網頁標準技術處於一個混亂的狀況——除了網頁瀏覽器對於新舊標準技術的支援各自爬山,不過在進入行動化時代、甚至未來的多裝置的世界,網頁瀏覽器對於網頁技術的支援會漸漸一致,所以這樣要修改程式的狀況應當會愈來愈少,而且網頁開發人員的最佳做法也會減少上述這些相容性的問題,這也是為什麼現在是最好提升網頁相容性的時機,做完就更向新時代的網頁瀏覽器們一起前進。

關於檢測網頁相容性,Microsoft Edge 也提供了免費的線上的工具協助您分析網頁的相容性問題,而且如果不想被這個工具掃瞄,也可以使用它開放出來的程式碼 https://github.com/MicrosoftEdge/static-code-scan 來進行檢測,希望能幫助網頁開發人員提升相容性並優化網頁效能!

原始文章發佈於「開發者之魂」部落格