UI工程的元素
在我之前的文章中,我討論了關於我們存在知識漏洞問題。你們也許會總結為我提倡平庸,並不是,這是很寬的領域。
我堅信你能從任何地方開始學習,並且不需要遵從特定的順序。但是獲取足夠的經驗還是有很大的價值的。我個人已經對建立使用者介面非常感興趣了。
我一直在思考我真正瞭解和認為有價值的是什麼。當然,我熟悉一些技術(比如JavaScript
和React
)。但更重要的經驗教訓是難以捉摸的。我從未試圖用語言表達出來。這是我第一次嘗試將它們羅列出來並且對它們進行描述。
市面上有很多關於技術或庫的學習路線。哪個庫將在2019流行?2020又會是什麼?你應該學習Vue
或者React
嗎?Angular
?Redux
或者Rx
嗎?你需要學習Apollo
?REST
或者GraphQL
嗎?這是很容易迷茫的。如果作者錯了呢?
我學習的最大突破不是學習一門固定的技術。而是,當我在解決一個特定的UI問題時學到了很多。有時,我會在之後發現一些庫或者同伴幫助了我。在其他情況下,我會想到自己的解決方案(好的或者壞的)。
理解問題、嘗試使用解決方案、應用不同的策略,這些組合使得我獲取了最具價值的學習經驗。這篇文章主要就是探討這些問題的。
如果你主要工作於使用者頁面,你可能處理了不少這樣的挑戰——直接的或使用庫。無論如何,我鼓勵你建立一個不依賴庫的小應用,然後進行復現和解決這些問題。它們都沒有一個正確的解。學習來自於探索問題領域和嘗試不同可能的權衡。
列舉出頁面開發中的一些問題,自己思考解決
- 一致性(Consistency)。 你點選了“like”按鈕後,文字變成了:“你和你另外的三個朋友喜歡了這篇文章。”你再此點選,文字又變回去了。聽起來很簡單吧。但是在螢幕上好幾個地方都存在這樣的標籤。也許有一些其他的提示需要改變(例如按鈕的背景色)。‘likers’列表已經提前從服務端獲取到了,並且當滑鼠移上去的時候也應該能夠看到你的名字了。如果你導航到另一個螢幕並返回,部落格不應該“忘記”它被喜歡過。即使是區域性一致性本身,也會帶來一些挑戰。但是其它的使用者可能也會改變我們展示的一些資料(例如喜歡我們正在看的帖子)。我們怎樣保證螢幕上不同部分同步相同的資料呢?我們如何以及何時使本地資料與伺服器一致,反之亦然?
- 響應性(Responsiveness)。 人們只能在有限的時間內忍受他們的行為缺乏反饋。對於手勢和滾動等連續性操作,這個限制很低。(即便是跳過一個16ms的幀也會讓人感覺很“不爽”。)對於像點選這樣的離散操作,有研究表明,使用者認為任何小於100ms的延遲都很快。如果一個動作需要更長的時間,我們需要顯示一個視覺指示器。但也有一些違反直覺。導致頁面佈局的“跳躍”或經歷幾個載入階段的指示器會讓動作感覺比以前更慢。類似地,在20ms內處理互動(以丟幀為代價)比在30ms內處理互動要慢,而且沒有刪除幀。大腦並不是基準。我們如何保證我們的應用響應不同的輸入呢?
- 延遲(Latency)。 計算和網路連結都需要時間。有時,如果不影響目標裝置的響應能力,我們可以忽略計算成本(確保在低配的裝置上測試過你的應用)。但是處理網路延遲是無可避免的——它將消耗幾秒鐘!我們的應用不能靜止等待資料或程式碼載入。但是那有可能發生在每一個螢幕中。如何在不顯示“loading”載入或空白情況下優雅地處理延遲呢?如何避免“跳躍”佈局呢?以及如何在每次不“重新連線”程式碼的情況下更改非同步載入項呢?
-
導航(Navigation)。
當我們與頁面互動時,我們期望UI能夠保持“穩定”。事物不應該就在我們眼前消失。導航,無論是在應用程式內部啟動(如單機連結),還是由於外部事件(如單擊“後退”按鈕),都應該遵從這一原則。例如,在配置檔案螢幕上的
/profile/likes
和/profile/following
選項卡之間切換不應該清除選項卡檢視之外的搜尋輸入。儘管導航到另一個螢幕中就像走進了一間房間一樣。人們期望能夠走回去並能找到他們留下的東西。如果你在導航中,單擊一個連結,然後返回,你失去了在導航中的位置,這是令人沮喪的——或者等待它再次載入。我們如何在不丟失重要上下文的情況下設計應用程式來處理任意導航。 - 陳舊(Staleness)。 通過引入本地快取,我們可以使“後退”按鈕導航立即生效。在快取中,我們可以“記住”一些資料,以便快捷訪問,即使理論上我們可以重新獲取它。但是快取自身也存在著一些問題。快取可能會過期。如何處理當我改變了一個頭像,快取也應該會更新的問題。如果我建立了一篇新的文章,也應該立即出現在快取中,否則快取將是無效的。這將變得困難且容易出錯。如果釋出失敗了呢?快取在記憶體中停留多長時間?當我們重新獲取提要時,是將新獲取的提要與快取的提要“整合”,還是將快取丟棄?如何在快取中表示分頁或排序?
- 熵(Entropy)。 熱力學第二定律是這樣說的,隨著時間的推移,物質會變得一團糟(嗯,不完全是)。這也同樣適用於使用者介面。我們不能準確地預測使用者互動及其順序。在任何時間點,我們的應用程式可能處於數量驚人的狀態下。我們盡最大努力使結果可預測並且限制我們的設計。我們不想看到一個bug截圖,然後疑惑“這是怎樣發生的?”。對於N個可能的狀態,它們之間有N*(N - 1)個可能的躍遷。例如,如果一個按鈕可以處於5種不同的狀態之一(正常,啟用,懸停,危險,禁用),對於5×4=20個可能的轉換,更新按鈕的程式碼必須是正確的——或者禁止其中一些。我們如何控制可能狀態的組合爆炸,並使視覺輸出可預測?
- 優先順序(Priority)。 有些事情比其它事情更重要。對話方塊可能出現在產生它的按鈕的“上方”,並“跳出”其內容的剪輯邊界。新排程的任務(例如響應單擊)可能比已經啟動的長時間執行的任務(例如在螢幕摺疊下方呈現下一篇文章)更重要。隨著我們應用程式的成長,它的部分程式碼是由不同的人和團隊編寫的,它們爭奪有限的資源,如處理器、網路、螢幕空間和包大小預算。有時您可以根據“重要性”的共享級別對競爭者進行排序,比如CSS z-index屬性。但是它很少有好的結局 每個開發人員都偏頗地認為他們的程式碼很重要。如果一切都很重要,那麼什麼都不重要!我們如何讓獨立的小部件合作,而不是爭奪資源?
- 可訪問性(Accessibility)。 無法訪問的網站不是一個小眾問題。例如,在英國,每5個人中就有1人患有殘疾。(這是一張不錯的資訊圖表 )我也有這種感覺。雖然我只有26歲,但我還是很難閱讀字型細、對比度低的網站。我試著減少使用觸控板的次數,我擔心有一天我將不得不通過鍵盤來瀏覽功能不佳的網站。我們需要讓我們的應用程式對於有困難的人來說不那麼可怕——好訊息是有很多唾手可得的成果。首先是教育和工具。但我們也需要讓產品開發人員做正確的事情。我們可以做些什麼來使易訪問性成為預設而不是事後考慮?
- 國際化(Internationalization)。 我們的應用程式需要在全世界各地執行。人們不僅會說不同的語言,而且我們還需要用產品工程師最少的工作量來支援從右到左的佈局。我們如何在不犧牲延遲和響應性的情況下支援不同的語言?
- 交付(Delivery)。 我們需要將應用程式程式碼傳送到使用者的計算機。我們使用什麼傳輸和格式?這聽起來很簡單,但是這裡有很多權衡。例如,本機應用程式傾向於提前載入所有程式碼,代價就是使得應用程式變得更大。Web應用程式的初始負載往往較小,但在使用過程中會有更多的延遲。我們如何選擇在哪個點引入延遲?我們如何基於使用模式優化我們的交付?最優解需要什麼樣的資料?
- 伸縮性(Resilience)。 如果你是昆蟲學者你可能會喜歡bugs,但你可能不喜歡看到它們出現在你的程式中。然而,你的一些bug將不可避免地進入生產環境。然後會發生什麼?一些bug會導致錯誤但定義良好的行為。例如,你的程式碼可能在某些條件下顯示不正確的輸出。但是如果渲染程式碼崩潰了呢?那麼我們就不能有意義地繼續,因為視覺輸出會不一致。一個帖子的崩潰不應該“拉下”整個feed,也不應該讓它進入一個導致更多崩潰的半中斷狀態。我們如何編寫程式碼來隔離渲染和獲取失敗,並保持應用程式的其餘部分執行?容錯對於使用者介面意味著什麼?
- 抽象(Abstraction)。 在一個小的應用程式中,我們可以硬編碼許多特殊的情況來解決上述問題。但是應用程式往往會增長。我們希望能夠重用、分叉和聯接程式碼的各個部分,使它們能夠一起工作。我們想在不同的人熟悉的片段之間定義清晰的界限,避免使經常變化的邏輯過於僵化。我們如何建立隱藏特定UI部分實現細節的抽象?我們如何避免在我們的應用增長過程中再次引入我們剛剛解決的問題?
當然,還有很多我沒有提到的問題。這個列表絕不是詳盡的!例如,我沒有談到設計人員和工程協作,或者除錯和測試。也許下一次我會寫的更詳盡。閱讀關於這些問題的文章時,很容易想到使用特定的檢視庫或資料獲取庫作為解決方案。但是我鼓勵你假裝這些庫不存在,從這個角度再讀一遍。您將如何解決這些問題?去試試構建一個小的應用程式吧!(我很樂意看到你在GitHub上做的實驗——你可以發推特(Twitter)回覆我。)
這些問題的有趣之處在於,它們中的大多數都能以任何規模出現。你可以在諸如typeahead或工具提示這樣的小工具中看到它們,也可以在諸如Twitter和Facebook這樣的大型應用程式中看到它們。
想想你喜歡使用的應用程式中的一個非試驗性的UI元素,仔細檢查一下這個問題列表。您能描述一下它的開發人員所選擇的一些折衷方案嗎?嘗試從頭建立一個類似的行為!
通過在不使用庫的小型應用程式中試驗這些問題,我學到了很多關於UI工程的知識。我向任何想對UI工程中權衡利弊的人推薦同樣的方法。
說明:bulb::翻譯:point_right:Dan Abramov的文章是一件很愉悅的事情,樂在其中並樂此不疲。但由於個人能力有限,一些翻譯的不好的地方或者理解不對的地方,希望發現問題的同學能指出,共同學習!