天天看點

Redux作者從“UI工程要素”談如何成為領域專家

原文作者:Dan Abramov

譯者:UC 國際研發 Jothy

在之前的文章中,我提到要承認我們的知識缺口。 你可能會認為我建議你們去解決平庸的問題,但這并不是我本意! 這是個廣闊的領域。

我堅信你可以“随時随地開始”,不需要按照任何特定的順序學習技術。 但我也認為獲得專業知識很重要。 就個人而言,我最感興趣的是創作使用者界面。

我一直在思考我所熟知且有價值的東西是什麼,誠然,我熟悉某些技術(例如 JavaScript 和 React),但從經驗中習得的收獲更為重要且難得,我從來沒試過把它們說出來,這是我第一次嘗試進行歸類描述。

網絡上有很多關于技術和庫的“學習路線圖”。 2019 年流行哪個庫?2020 年呢?你應該學習 Vue 還是 React 還是 Angular?Redux 或 Rx 怎麼樣?你必須學習 Apollo 嗎?REST 還是 GraphQL?實在太容易迷失其中了,而且如果作者錯了怎麼辦呢?

我最大的學習突破不在于某個特定的技術。相反,當我努力解決特定的 UI 問題時,我學到的最多。 有時候,我會找到有幫助的庫或模式。 其他時候,我會自己想出解決方案(有好有壞)。

這涵蓋了了解問題,實踐解決方案以及應用不同政策,它們為我帶來了最有價值的學習體驗。 這篇文章隻關注問題部分。

如果你開發過使用者界面,那麼你可能直接或使用庫來處理以下這些挑戰。 無論是哪種情況,我都鼓勵你嘗試不使用任何庫的情況下,獨立建立一個小應用,并不斷重構,解決問題。 任何一個問題都沒有通用的解決方案,在探索問題和不同的權衡嘗試之中才能學到東西。

  • 一緻性。 你點選️“like”按鈕後,文字更新:“你和其他 3 個朋友 like 了這篇文章。”你再次點選,文本變回原樣。 聽起來很容易,但也許螢幕上好幾個地方都有這樣的标簽,也許還有其它需要改變的視覺辨別(例如按鈕背景)。之前從伺服器擷取并在滑鼠懸停時可見的“likers”清單,現在應包含你的姓名。 如果你導航到另一個螢幕并傳回,文章不應該“忘記”它被 like 了。 即使是實作局部的一緻性也頗具挑戰,但是其他使用者也可能修改我們顯示的資料(例如,他 like 了我們正在檢視的文章)。 我們如何在螢幕的不同部分保持資料同步? 我們如何以及何時使本地資料與伺服器保持一緻,反之亦然?
  • 響應性(Responsiveness)。 人們能容忍的螢幕對動作的視覺回報時間是有限的,對于手勢和滾動等連續動作,這個時間會很低(即使跳過一個 16ms 的幀也感覺“很笨拙”)。對于像點選這樣的離線行為,研究表明使用者認為任何 <100ms 的延遲都還算快。 如果操作需要更長時間,我們就需要顯示一個訓示符。 但是也存在一些反直覺的挑戰,導緻頁面布局“跳轉”或經過多個加載“階段”的訓示符會使操作感覺比以前更長。 同理,以丢棄動畫幀為代價,在 20ms 内處理互動可能比在 30ms 内處理它并且沒有丢幀感覺更慢。大腦是非基準的,該如何讓我們的應用響應不同類型的輸入?
  • 延遲。 計算和網絡通路都需要時間。有時我們可以忽略計算成本,前提是它不會損害目标裝置的響應能力(確定在低端裝置頻譜上測試應用)。 但處理網絡延遲是不可避免的 - 它可能要花上幾秒鐘! 我們的應用不能隻是當機等待資料或代碼加載。這意味着任何依賴于新資料,代碼或資源的操作都可能是異步的,需要處理“加載”情況,但幾乎每個螢幕都會發生這種情況。 我們該如何優雅地處理延遲,不給使用者顯示層層的旋轉圖示或者空頁面? 我們如何避免布局“跳躍”? 我們如何在不用每次都“重新布局”代碼的情況下更改異步依賴關系?
  • 頁面跳轉(Navigation)。 我們希望與 UI 互動時它能保持“穩定”,頁面上的東西不會憑空消失。 無論是在應用内發出(例如點選連結)還是由外部事件觸發(例如點選“後退”按鈕),頁面跳轉都應該遵循這一原則。 例如,在配置區域上切換 /profile/likes 和 /profile/follows 标簽卡時,不應該清除标簽視圖之外的搜尋框内容。跳轉到另一個頁面就像走進另一個房間。人們會希望當他們傳回時,東西仍與離開時保持一緻(也許還能出現一些新東西)。 如果你在一個資料流中,點選個人資料,然後傳回,你可以會丢失你在資料流中的位置 - 或者等待它再次加載。該如何建構我們的應用來處理任意頁面跳轉,并保證不丢失重要的上下文?
  • 過期。 我們可以通過引入本地緩存使“後退”按鈕即時跳轉,在緩存中“記住”一些資料以便快速通路,即使理論上也可以重新擷取它。但緩存也有自己的問題,它可能會過期。 如果我更改了頭像,它也應該在緩存中更新。如果我釋出新文章,則需要立即顯示在緩存中,否則緩存應失效。這會比較困難且容易出錯。 如果釋出失敗怎麼辦? 緩存在記憶體中保留多長時間?當我們重新擷取資訊流,我們是該使用緩存的“stitch”新提取的資訊流,還是丢棄緩存? 分頁或排序如何在緩存中表示?
  • Entropy(熵,熱力學函數)。 熱力學第二定律說“随着時間的推移,事情變得一團糟”(好吧,不完全是這樣),這也适用于使用者界面。 我們無法準确預測使用者互動及其順序。無論何時,我們的應用都可能處于難以置信的可能狀态。 我們盡最大努力使結果可預測并受制于我們的設計。我們不想通過錯誤截圖去思考“為什麼會這樣”。 對于 N 種可能狀态,它們之間存在 N×(N-1) 個可能的轉換。 例如,如果一個按鈕可以處于 5 種不同狀态(正常,激活,懸停,危險,禁用)中的一種狀态,則更新按鈕的代碼必須正确,以便進行 5×4=20 次可能的轉換 - 或禁止其中一些轉換。 我們如何控制可能狀态的組合爆炸并使視覺輸出可預測?
  • 優先級。事情總有輕重緩急之分。 對話框可能得“出現”在産生它的按鈕上方,并“突破”其容器的邊界。 新計劃的任務(例如,響應點選)可能比已經開始的長期任務(例如,在折疊的螢幕下方渲染下一個文章)更重要。 随着應用的增長,由不同的人和團隊編寫的部分代碼将競争有限的資源,如處理器,網絡,螢幕區域和包體積預算。 有時你可以在共同的“重要性”範圍内對競争者進行排名,比如 CSS 的 z-index 屬性。 但它的效果通常比較差。 每個開發人員都偏向于認為他們的代碼很重要。 但如果一切都很重要,那就什麼都不重要了! 我們如何讓獨立的小元件進行合作而不是争奪資源?
  • 無障礙(Accessibility)。 不支援無障礙通路的網站不是一個小問題。 例如,在英國,每五個人就有一個人身患殘疾(從這裡可以更直覺看出: https://www.abrightclearweb.com/web-accessibility-in-the-uk/ ),我也親身感受到了這一點。 雖然我才 26 歲,但我很難閱讀細體字和低對比度的網站。 我盡量少用觸控闆,而且我害怕有一天我必須通過鍵盤來浏覽品質低下的網站。 我們需要讓有殘疾的人也可以順暢的使用我們的 App - 而且好消息是現在有很多現成的方法。首先,對于這個群體的教育和幫助他們閱讀的工具可以緩解這一點,但我們還需要讓産品開發者們可以輕松地從軟體層面做到這一點。 我們可以做些什麼,來讓開發無障礙的網站變成大家的常識和一個預設就要做的事情,而不是事後才想去做呢?
  • 國際化。 我們的應用程需要運作于世界各地。人們不僅會講不同的語言,而且還需要用産品工程師的最少努力支援從右到左的布局。我們如何在不犧牲延遲和響應能力的情況下支援不同的語言?
  • 傳輸。 我們需要将應用代碼提供給使用者電腦。 我們使用什麼樣的傳輸和格式? 這可能聽起來很簡單,但其中有許多權衡。 例如,原生應用傾向于以巨大的應用體積為代價加載所有代碼。Web 應用往往具有較小的初始負荷,但代價是使用期間的延遲會更長。我們如何确定何時引入延遲? 如何根據使用模式優化傳輸? 需要什麼樣的資料才能獲得最佳解決方案?
  • 彈性。 如果你是昆蟲學家,你可能會喜歡 bug(蟲子),但你估計不會喜歡在程式中看到它們。但是,你的一些 bug 将不可避免地進入生産階段。那會引發什麼? 有些錯誤會導緻錯誤但定義明确的行為。 例如,在某些情況下,你的代碼可能會顯示錯誤的輸出。但是如果渲染代碼崩潰了怎麼辦?因為視覺輸出會不一緻,我們無法繼續進行。渲染單個文章的崩潰不應該“搞垮”整個資訊流或使其進入半破壞狀态,進而導緻進一步崩潰。我們如何以隔離渲染和擷取失敗的方式編寫代碼并保持應用的其餘部分運作? 容錯對使用者界面意味着什麼?
  • 抽象。 在一個小應用中,我們可以對許多特殊情況進行寫死以解決上述問題,但往往應用會增長。 我們希望能夠重用,fork 及連接配接部分代碼,并集體處理它們。 我們希望在不同人熟悉的部分之間定義明确的界限,并避免過分僵化經常變化的邏輯。 我們如何建立隐藏特定 UI 實作細節的抽象? 随着應用的增長,我們如何避免重新引入我們剛剛解決的問題?

當然,還有很多問題我沒有提到。這份清單并非詳盡無遺!例如,我沒有談到設計師和工程協作,或調試和測試。也許下次再說吧。

将特定視圖庫或資料提取庫作為解決方案解決問題很誘人。但我希望你假裝這些庫不存在,并從那個角度再次思考。你将如何解決這些問題?使用個小應用試一試! (我很想在 GitHub 上看到你的實踐 - 随時給我發推文回複。)

這些問題的有趣之處在于它們大部分都以任意規模出現。你可以在小型元件中看到它們,比如typeahead或工具提示,也能在 Twitter 和 Facebook 等大型應用中看見。

想想你喜歡使用的應用中的那些不平凡的 UI 元素,并檢視此問題清單。你能描述一下開發者進行選擇的權衡嗎?試試從頭開始重新建立類似的行為!

通過在小型應用中試驗這些問題而不使用庫,我學到了很多關于 UI 工程的知識。建議任何想要深入了解 UI 工程權衡的人都試一試。️

英文原文:

https://overreacted.io/the-elements-of-ui-engineering/

繼續閱讀