原生 JavaScript 網頁程式設計:為什麼用或不用原生 JavaScript?

【分享本文】
Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

    前言

    由於瀏覽器相容性的因素,jQuery 曾經一度被視為是網頁程式設計必備的函式庫。

    其實 jQuery 不若先前那麼重要,但台灣本地的網頁程式設計教材仍然會繼續介紹 jQuery。一部分的原因是程式設計師得維護一些現存的專案,而這些專案剛好有用到 jQuery;當專案運行良好時,通常不會用其他方式改寫專案程式碼。

    如果當下要開個新專案,應該認真考慮不要再用 jQuery 了,不論是用原生 JavaScript 或前端框架都可以,只要符合專案需求即可。

    前端框架的興起主要是因應單頁式網頁程式 (single page application) 的需求,像是現在 (西元 2019 年) 很紅的 React 和 Vue 就算是網頁前端框架的實例。但其實用原生 JavaScript 也可以寫網頁程式,我們會在後文討論這個議題。

    jQuery 不再那麼重要

    jQuery 的興起是因為當時 Internet Explorer (IE) 和 Netscape Navigator 在 JavaScript API 上是不相容的,網頁程式設計師勢必得寫許多條件敘述去處理這些差異。jQuery 把這些差異性封裝起來,網頁程式設計師就不用再手動處理這些議題。

    但 IE 已經是陳舊的軟體 (legacy software) 了。真正依賴 IE 的使用情境大概只剩少數還依賴著 IE 的網路銀行之類的。

    相對來說,現代瀏覽器 (modern browsers) 在實作上大扺符合 JavaScript 標準,在 JavaScript 網頁 API 的歧異沒有像以前那麼大,所以封裝 JavaScript API 的必要性也隨之減少。

    除了要支援 IE 等舊有軟體外,使用 jQuery 的必要性已經沒有先前那麼強烈了。

    附帶一提,如果要考慮相容性,可以用 Babel 將 ES6+ 的新式 JavaScript 代碼轉回 ES5 的 JavaScript 代碼。如此一來,就不需要再繼續用 jQuery 了。筆者先前在這裡介紹過 Babel 的使用方式,有需要的讀者可以前往參考。

    前端框架所要解決的議題

    網頁前端框架的出現,是因應單頁式網頁程式的需求。像 GMail 這類網頁程式,在頁面第一次載入後,就不會再重刷頁面,之後頁面上的更動都是藉由 JavaScript 程式動態修改頁面而成的。這類網頁程式必要時會用 Ajax 和後端主機交換資料,所以也不需要藉由重刷頁面來更新資料。

    其實這類網頁程式用原生 JavaScript 寫就可以了。但是還是有不少開發團隊開發前端框架出來。主要是著眼於以下的議題:

    • 使用原生 JavaScript 寫程式碼比較長
    • 原生 JavaScript 沒有自動處理資料一致性 (data consistency) 的方式
    • 原生 JavaScript 沒有網頁模板 (HTML template) 或網頁元件 (web component)
    • 原生 JavaScript 需手動處理路徑 (route) 的議題

    筆者在這裡其實稍微吃書,因原生的網頁元件 (web component) 已經問世了。然而目前瀏覽器對網頁元件的支援還不夠完整 (參考這裡)。如果當下想用網頁元件的話,最好還是當成瀏覽器尚未支援這項特性,暫且先用 Vue 等第三方方案比較安全。

    使用前端框架的問題在於前端框架本身不夠穩定。從 Backbone 到 Angular 到 React 和 Vue,前端框架的版本和 API 不斷地在更迭;也就是說,我們一直在學習用不同的方式處理同一個問題領域。

    不論某個框架在當時是當紅炸子雞,單一框架的技術生命都不是那麼長久,但原生 JavaScript 的 API 大體上很穩定,因為 ECMAScript 委員會在更新 JavaScript 時會慎重地把 JavaScript 的相容性考慮進去。

    此外,過度強調前端框架,會讓網頁程式學習者誤以為前端框架是必備的。但現在我們沒有 JavaScript API 不相容這類的剛性需求,前端框架只是在輔助我們寫網頁程式,不應該取代我們對於 JavaScript 本質上的了解。

    當函式庫在使用上出了問題

    現在的 JavaScript 函式庫或框架,為了要推廣自家的技術,通常都會有很漂亮的官方網站。在官網上,也會讓程式設計師入門該技術的範例專案。由於這些範例是設計過的,照官網的指示跑通常不會有問題。

    問題會發生的時間點都是把這些技術用在自己的專案時,那時候專案程式碼已經寫一段時間了,也不可能輕易就放棄現有的代碼或重寫專案,勢必要在繼續使用該項技術的前提下解決問題。

    有一些相對冷門的情境,官網上可能也沒有直接的說明,這時候只得到 Stackoverflow 等程式論壇上,找找看有沒有某位高手已經解決這個問題並提供解答。我們用網頁框架的目的是解決我們的問題,但消耗在搜尋特定問題的心力卻抵消了原本使用網頁框架所帶來的便利性。

    當網頁框架在使用上出現問題時,還是得回到我們對原生 JavaScript 的理解上來處理問題。不論是要看懂網路上對這個議題的討論,還是要追蹤 JavaScript 原始碼,我們還是要利用對 JavaScript 的知識來理解和解決問題。

    由於 JavaScript 函式庫是以原始碼的方式來發佈,而不是二進位檔。當我們碰到問題時,終極的解決方式就是去追蹤該函式庫或框架的原始碼,看當時這個問題是如何發生的。透過對框架本身的深入了解,才能解決困難或罕見的問題。

    在少數極端情境下,有可能是函式庫或框架本身的問題所造成的。如果我們對於 JavaScript 的理解夠好,我們不僅可以解決問題,甚至可以發 PR (pull request) 來主動幫助其他程式人。

    函式庫對程式效能的影響

    當我們使用越多 JavaScript 函式庫時,網頁程式花在傳輸資料、解析 JavaScript 代碼、載入程式等過程就越久,網站使用者能夠開始使用網頁的時間就往後延遲。在練習階段時,我們不會強調網頁的大小,但對實際上線的網頁程式來說,應儘量用最精簡的代碼達成所需的效果。

    比起使用網頁函式庫和框架,直接使用瀏覽器提供的原生網頁 API 是最精簡的,因為少掉函式庫層層呼叫網頁 API 所帶來的開銷和傳輸函式庫的頻寬。

    我們應該只在需要完成特定複雜任務時才使用 JavaScript 函式庫。例如,繪製圖表 (diagram) 是相對複雜的任務,無法用短短幾行 JavaScript 就做出很漂亮的圖表,這時候就可以使用 D3.js 或 Chart.js 等函式庫來滿足我們的需求。

    本系列文章的方向

    我們假定讀者已經學完 JavaScript 的基本語法,在這裡的文章不會重講這個部分。如果讀者還沒開始學 JavaScript,可到這裡學習一下,或是自行閱讀其他的資料。

    【分享本文】
    Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email
    【追蹤新文章】
    Facebook Twitter Plurk