文章

強韌網頁設計—第四章:語言

喬恩·波斯特爾(Jon Postel)是在互聯網的前身 APRANET 工作的其中一位工程師,他想確保每個封包─或曰「資料包」─在網絡中是以最有效率的方式穿梭,以至了解到這種對錯誤寬鬆的方法,對封包交換至關重要。

喬恩·波斯特爾(Jon Postel) Photograph by Irene Fertik, USC News Service. Copyright 1994, USC.

一個網絡節點接收到的資料包有錯誤,但仍然能讀的話,就應處理。相對上來說,每個網絡節點亦應發出包裝完整的封包。此想法被奉為「強健性原則」,也就是「波斯特爾律」:

嚴以發送,寬以接收

這聽起來很耳熟,因為這也是瀏覽器處理 HTMLCSS 之法,就算 HTMLCSS 當中有錯,瀏覽器仍然會嘗試處理資料,跳過不能解析的部份。

宣告

HTMLCSS 都是宣告式語言的例子,當中作者只需描述想得到的結果,不需給電腦一步一步的指示。使用 HTML 你可以描述內容的本質─段落、標題、表單欄等等,而不需向瀏覽器解釋該如何處理這些資訊。使用 CSS 你可以描述你想要的內容外觀─顏色、框線等等─而不需為寫程式去表現這些樣式。

大部份的程式語言都不是宣告式,而是命令式。Perl、Java、C++ 等都是命令式語言的例子,以這些語言編寫之時,你要提供清晰指示給解析你程式碼的電腦。

命令式語言比起宣告式更有力和更精確,但亦有其代價,指令式通常都比宣告式難學懂,也較難應用波斯特爾律,你一犯錯─寫錯或漏掉一個逗號,則整個程式會當掉。串錯的 HTML 標籤或漏了 CSS 括號也使人頭痛,但命令式程式就必需有完美構成,否則根本走不動。

命令式語言如 PHP、Ruby 和 Python 等,可見於萬維網的伺服器上,用來讀寫資料庫,處理輸入,運行複雜演算。在伺服器端你基本上可選擇任何程式語言來寫,不同於瀏覽器的未知,你可全權控制伺服器的能力。

在瀏覽器裏可運行的命令式語言只有一個選擇:JavaScript。

腳本

在網頁運行程式的想法就如網頁本身一樣久遠,這是一封在 www-talk 的電郵列表上的早期電郵:

我想知道有沒有人延伸了 WWW 令到在瀏覽器可以按一按鈕然後運行程式?

萬維網的創造者添.伯納斯-李回覆:

好問題,難處在於程式語言,要既有能力又夠普及,記著網絡要面向所有讀者,而我們沒有通用的直譯式程式語言(interpreted progamming language)。

那是在1992年,而這通用直譯式程式語言在1996年出現,由網景的程式員布蘭登·艾克(Brendan Eich)在十日寫成。

此語言改過幾個不同名字,首先叫 Mocha,正式出時叫 LiveScript,然後市場部插手改之叫 JavaScript,企圖乘著當時新潮的 Java 語言炒作。事實上兩者只有很少相似之處,JavaScript 之於 Java 就如狗之於熱狗 [1]。

進步的模式

JavaScript 給設計師有能力去在網頁載入後更新網頁,兩個常見用途出現:滑鼠圖像變換與表單驗証。

當鼠標經過一個連結時變換圖像,聽起來不像一個全新語言的明智用法,但在九十年代的確沒有辦法做出懸停(hover)效果。

在有 JavaScript 前,表單提交到伺服器之前,你不能先檢查必填的欄位是否已埴,或者所入資料格式是否正確。

至今這仍然需要此兩用,但已不需使用 JavaScript,你可以用 CSS 的偽類(pseudo-class) :hover 來達成圖像變換,也可以使用 HTMLREQUIREDTYPE 屬性來驗證表單欄。

模式不停再現:在命令式語言做的一個解方,若夠流行,就會隨時間被移殖到宣告式語言。當新功能出現在宣告式語言,不單更易編寫,也更強健。

HTMLCSS 對錯誤的寬鬆處理意味著編寫出錯或瀏覽器支援的問題,均會優雅地給應付好,這通常都足夠好了。相對地,如果你給瀏覽器錯誤的 JavaScript 或試用未能支援的 JavaScript 功能,瀏覽器不單會拋出錯誤,也會停下解析腳本,不再運行。

責任

JavaScript 給設計師能力,建造更靈巧、更流暢、更具反應的網站,也給他們能力去令網站變得遲鈍、笨重和難以使用。

其中一個期濫用 JavaScript 的方式(不驚訝地)來自廣告業,其存在總是與想快快完成手上工作的人為敵。JavaScript 容許你建立新的瀏覽視窗,之前本來只得用戶有這個權。一位年輕的開發者伊凡·佐克曼(Ethan Zuckerman)發現他可以生成新視窗來放廣告,讓廣告啇將訊息顯示在網站訪客面前。不單如止,JavaScript 還可生成多個視窗,有些可見,有些躲在現有視窗下,這是邪惡的用法。

二十年後,佐克曼寫道:

我曾編寫過開視窗放廣告的程式,很對不起

彈出(及彈底)視窗令人難以忍受到一個地部,瀏覽器得容許人們可以擋下它們。

廣告業然後找到其他濫用 JavaScript 的方式,廣告贊助的網上出版在其網頁上注入又腫又慢的 JavaScript,使整頁載入得很慢,也用 JavaScript 來追蹤人們在網站間的蹤跡,因此人們使用廣告攔截軟件對付,結果瀏覽器和作業系統內建廣告攔截功能,給我們對抗過量的 JavaScript。

網頁設計師會謹記廣告業所無視的事實:在網絡,用戶有最終話語權。

2.0

JavaScript 的掘在2005年再提升,始於一篇傑西·詹姆士·賈瑞特(Jesse James Garrett)的文章《Ajax: A New Approach to Web Applications》(Ajax:網絡應用程式之新法),文章將一個越來越流行的技巧給了一個名字,使用特定部份的 JavaScript,瀏覽器可以在不重新截入整頁的情況下收發資料,帶來更暢順的用戶體驗。

在提出 Ajax 這用的同時期有另一個新現象,提姆·奧萊理(Tim O’Reilly)將新一波的網絡產品與服務形容為Web 2.0。有別於 Ajax,我們很難為 Web 2.0 下定義,對於商業人員來說這代表新的商業模式,對於圖象設計師這代表圓角與漸變色,對於開發者這代表 JavaScript 與 Ajax。

不論其明確定義,Web 2.0 這字眼抓到了當時的心情與感覺,所有東西都不同了,我們可以放棄建立網頁的舊思維,將網絡視為一個無限的超連結文件集合已過時,網絡應用的年代來了。

應用快樂

在1994年雅克別利斯對俄亥俄州(Jacobellis v. Ohio)一案中,法官波特·斯圖爾特(Potter Stewart)提出對「淫穢」的定義:

我看到時就會知道

同樣說法可應用在 Web 2.0 或網絡應用(Web App)之上,我們可以指出網絡應用的例子,但要為這詞給一個定義卻很棘手。網絡應用讓人們可以建造、編輯和刪除內容,但這些工作其實在網絡應用出現前也已可行,人們可以填寫表單,提交給伺服器處,Ajax 則移除了與伺服器的一些往返。

或許網絡應用的定義需要一點循環論證:

  • JavaScript 是網絡應用所必要的條件
  • 網絡應用是一種網站,它需要 JavaScript 來運作

此情況下,建立網絡應用建基於此假設:JavaScript 必需可靠可用,而基於其命令式本質,JavaScript 比起宣告式語言如 HTML 比較脆弱,依靠 JavaScript 畢竟未必是一個安全的假設。

無可饒恕

HTML 對錯誤的寬鬆處理,令其可以隨時間而成長,也確保語言易學,就算你出錯,瀏覽器所實作的波斯特爾定律會確保你仍然會得出結果。但出人意表地,有人想去除這 HTML 的超能力。

在 1999 年標準化了 HTML 版本 4 之後,萬維網協會(World Wide Web Consortium)出版 XHTML 1.0,重新依 XML 資料格式的規則來制定 HTMLHTML 標籤名與屬性是大小階皆可,XML 則必需是小階,其他的分別有:所有屬性必需以引號包圍,單獨元素如 IMG 或 BR 必需有關閉斜線(slash)。

XHTML 1.0 沒有為語言加入新的功能,只是一個更嚴格的寫法。XHTML 2.0 有不同主張,不僅會移除如 IMG 這些元素,還會實作 XML 的嚴厲錯誤處理模型,XML 文件上的一個錯誤-沒有引號的屬性或漏掉關係斜線,解析器應要立即停止工作,不再渲染下去。

XHTML 2.0 胎死腹中,其理論上的純淨被真正建立網頁維生的人圓滑地拒絕,網頁設計師嚴正地拒絕一個會完全當掉,而不是嘗試由錯誤回復的格式。

但奇怪地,多年後,網頁設計師卻快樂地以 JavaScript 創造網站,一隻跟 XML 一樣不饒錯的語言,他們不稱之為網站,而叫網絡應用,似乎這樣叫給一些未能完成工作的人一些安慰,因為有服務的核心功能必需依靠 Javascript 運作。

除了 JavaScript 的脆弱錯誤處理模型,網頁設計師也變得越依賴 JavaScript。2015 年 NASA 將其網站重新啟動為網絡應用,如果你要讀取最新有關太空探索的消息,你得先下載並執行 3 MB 的 JavaScript,這些內容-文字與圖像-本可以用 HTML 來傳送,但開發者決定使用 Ajax 去接收此資料。在所有的 JavaScript 被載入、解析、執行之前,訪客只得面對一個黑色背景,或許這是為了表示太空的巨大虛空。

2015年版的 nasa.gov 在缺 JavaScript 下的模樣

這點出 JavaScript 與 HTML 的另一點不同,HTML 可被邊下載邊逐部渲染,而 JavaScript 則必需整個下載後才可以開始被解析。只有少部份沒有 JavaScript 的訪客會錯過網站,這想法很誘人,但真相是所有人都是非 JavaScript 用戶,直至 JavaScript 載入完成... 如果載入完得了的話。容易斷掉的連線、網絡營運商的扞擾、不可預測的廣告欄截軟件皆可打擊所謂 JavaScript 是隨時可用的假設。

問題不是人們故意關掉瀏覽器的 JavaScript,雖然說這情況也值得考慮,但這不是最常見的 JavaScript 錯誤成因。史都華‧蘭格里奇(Stuart Langridge)在其文章《Everyone has JavaScript, right?》(每個人都有 JavaScript,對不對?)寫了一長串的可能故障:

用戶端發請求到你的網絡應用,那頁已截入了嗎?那發給 JavaScript 的 HTTP 請求成功嗎?有沒有完成?有沒有企業防火牆來擋住?他們的 ISP 或流動供應商有沒有干擾已下載的 JavaScript?有沒有關掉 JavaScript?有沒有安裝了一些插件或擴展,以你沒想到方式注入腳本或更改 DOM?內容傳遞網絡(Content Delivery Network)已上線?他們的瀏覽器支持你寫的 JavaScript 嗎?

上述很多問題本身都會影響到 HTMLCSS 檔,但因為斯圖爾特定律,他們可以優雅地復原。

這不是說網頁設計師不該使用 JavaScript,只是說當有更簡單的解決方法之時,他們不該依靠 JavaScript。

平台

忽視了約翰‧阿爾索普的《網頁設計之道》,網頁設計師誤將網頁當成印刷頁。印刷史上有很多有用的東西-階層結構、排字、顏色理論-但網絡基本上是不同的媒介。軟件開發史也提很多有用的東西-架構學、測試、過程-但網絡仍是自成一家的媒介。

將其他媒介所學所知帶到網絡的確很吸引人,但發掘網絡自身的強項弱項,更能忠於其結構。

我們所用的語言可以巧妙地改變我們的想法,在喬治·萊考夫(George Lakoff)的著作《Metaphors We Live By》(我們所活在的比喻)點出政治語言的危險,顯例如「友善開火」(Friendly Fire)和「附帶損傷」(Collateral Damage),更陰險的有「稅收減免」(tax relief)-在討論展開之前,已將稅收限定為一些得減免的東西。

表面上,「網絡平台」(web platform)一詞看似無害,但其實將之類比成軟件平台,Flash 是一個平台,Android 是一個平台,ios 是一個平台,但網絡不是一個平台,網絡的重點在於它是平台。

平台為軟件提供一個被控制住的運行環境,只要用戶有這運行環境,你有自信能保證他們得到的正正是你所設計的。如果你建立一個 ios 應用程式而有人有一個 ios 裝置,你會知道他們能夠百分之百得到你的軟件。如果建立一個一個 ios 應用程式而有人有的卻是 Andriod 裝置,他們能得到百分之零的軟件。你不能在 Andriod 裝置上安裝 ios 應用,是全有或全無。

網絡卻不是這般二元,如果你用網頁技術建立一些東西,而有人用瀏覽器探訪,你不能確保他能支援幾多網頁技術,大可能不是百分之百,也不大可能是百分之零,有些人使用 ios 裝置探訪,有些人使用 Android 裝置探訪,有些人會得到你所設計的八九成,有些可能得二三成,或五成。網絡並非平台,而是一個連續體。

將網絡想成一個平台是分類錯誤,平台如 Flash、ios 或 Android 提供確定性和穩定性,但必需滿足一組特定情況-必需以正確的平台專有運行環境接駁。網絡沒有此確定性,但亦不限可能的運行環境。

平台是控制和可預測的,萬維網則混亂而不可測。

網絡既性感,又一塌糊塗。

參考資料

註1:原句是 Ham(火腿) 之於 Hamster (倉鼠)。


本文是《Resilient Web Design》繁體中文翻譯的其中一部份,以該書的相同的姓名標示-相同方式分享 CC 4.0 國際授權

*