<font id="zqva1"></font>
<rt id="zqva1"></rt>
  • <tt id="zqva1"></tt>
    <cite id="zqva1"></cite>

    <cite id="zqva1"><noscript id="zqva1"></noscript></cite>
      <rp id="zqva1"><meter id="zqva1"></meter></rp>

        <cite id="zqva1"></cite>
          <b id="zqva1"></b>
          <rp id="zqva1"></rp>
          <cite id="zqva1"></cite>

          <rt id="zqva1"></rt>

        1. <rp id="zqva1"></rp>

          函數式 UI:Web開發終于擺脫了框架的束縛

          時間:?2019-08-27閱讀:?27標簽:?web

          本文要點

          • 用戶界面都是響應式系統,由用戶界面應用程序接收的事件與應用程序必須在接口系統上執行的動作之間的關系來定義
          • 流行的 UI 框架(如 React、Vue 或 Angular)通常具有很高的次生復雜性,它們的狀態和效果零散地分散在一個組件樹中,并且由 上帝組件 處理大量無關的問題
          • 函數式 UI 是用于用戶界面應用程序的一組實現技術,它強調了應用程序的效果(effectful)和純函數部分之間的明確界限
          • 函數式 UI 從概念上講是很簡單的,可以更直接地反映應用程序的規范(specification),將 UI 框架降級為一個單純的庫,允許開發人員對用戶場景進行單元測試,并減少應用程序的設計和實現錯誤。
          • 函數式 UI 會針對正確性進行優化,同時會為開發人員創建一些選項,以便在將來獲得更多信息時重新考慮諸如 UI 框架或遠程數據獲取機制之類的關鍵決策。


          為什么要使用函數式 UI?

          顧名思義,用戶界面允許用戶與其他系統 交互 ,其理念是:相比直接與其他系統互動,這種交互界面會提供一些用戶期望的好處。用戶通過某種輸入方式(例如按鍵或聲音輸入)表達意圖,然后用戶界面通過在接口系統上預定義的動作來做出響應。 用戶界面基本上是天然的響應式系統 。用戶界面的任何規范技術都必須詳細說明 用戶界面輸入和接口系統上的動作之間的對應關系 ,也就是應用程序的 行為 規范。這樣一來,就可以根據用戶發起或應用程序接受的一系列事件,以及系統對應的預期反應來定義一個用戶故事。

          許多用來實現用戶界面的框架(Angular2、Vue 和 React 等)都使用回調 過程 或事件處理程序,后者會作為事件的結果而 直接執行 相應的動作。決定要執行哪個動作(例如輸入驗證、本地狀態更新、錯誤處理或數據獲取等),通常意味著要訪問和更新某些狀態,而這些狀態并不總是在作用域內。因此框架會包含一些狀態管理或通信能力,以處理所需的相關狀態的傳遞,并在允許和要求時更新狀態。

          基于組件的用戶界面實現往往包含一些狀態,而動作以不明顯的方式沿著組件樹散布開來。例如,一個 待辦事項列表應用程序 可以寫為 。假設一個 TodoItem 管理其刪除操作,則必須將刪除操作與更新的項目列表沿著結構向上傳遞給要調用的父級 TodoList。假設是由父級的 TodoList 管理項目的刪除操作,它可能還是要將刪除操作傳遞給子級的 TodoItem(也許執行一些清理動作)。

          這里的底線是要將動作與給定的事件匹配,我們需要查看每個組件實現以了解事件及其處理的動作,以及它與組件樹中依賴它的組件所使用的消息傳遞協議,然后對依賴組件重復相同的過程,直到下面沒有依賴組件為止。只有這樣,我們才能生成一個事件觸發動作的完整列表。此外,組件通常是給定框架專屬的,其選項取決于這個框架中可用的內容。

          但是,我們選擇的的框架是與規范分離的實現細節。實現應用程序和組件間消息傳遞的組件樹,其特定形態(shape)在很大程度上也與規范緊密關聯。于是考慮這樣的問題:當用戶遵循某個用戶故事時,比如說當應用程序收到給定的事件序列 [X,Y,…] 時會發生什么情況?回答這類問題需要馴服來自于框架的特性、組件、狀態管理和通信機制的 次生復雜性 。

          但是如果不回答這個問題,我們就不能確定實現是否符合規范,而符合規范就是軟件的存在價值。隨著用戶故事的數量和大小繼續增長,這種信心只會愈加脆弱。

          而函數式 UI 技術試圖從事件 / 動作對應關系中導出函數等式,從而直接反映用戶界面的規范。由于等式是直接從規范中得出的,因此我們可以讓實現盡可能接近規范。一般來說,這會減少實現錯誤的生存空間,并且會在開發的早期階段就發現規范錯誤。由于函數式 UI 依賴于純函數,因此可以輕松、可靠和快速地對用戶故事進行單元測試。在某些情況下(狀態機建模),甚至可以高度自動化地生成實現和測試。因為函數式 UI 只是標準的函數式編程,所以它不依賴于任何框架魔術。函數式 UI 可以很好地對接任何 UI 框架,需要的話也可以不使用任何框架。

          本文將介紹函數式 UI 的意義,及其背后的基本函數等式,還會展示這種技術的具體用法示例,以及如何測試以這種風格編寫的應用程序。與此同時,本文將努力揭示在 Web 應用程序開發中使用函數式 UI 方法的優缺點。


          但什么是函數式 UI 呢?

          任何用戶界面應用程序都會隱式或顯式地實現以下內容:

          1. 一個接口,應用程序通過它來接收事件
          2. 事件和動作之間的一種關系(~),形如:event ~ action,其中
          • ?稱為響應關系
          • event 是通過用戶界面接收并觸發接口系統上一個 action 的事件。事件可以是
            • 用戶發起的(如按鈕點擊)
            • 系統發起的,即由環境或外部世界生成的(如 API 響應)
          1. 一個與外部系統對接的接口,必須通過該接口執行用戶預期的動作

          因為大多數響應式系統都是有狀態的,所以一般來說關系?不是一個 數學函數 (也就是 只將一個 輸出關聯到一個輸入)。切換按鈕就是一個簡單的有狀態 UI 應用程序。按下按鈕一次,應用程序將呈現一個切換后的按鈕。再按一次,應用程序將呈現一個切換前的按鈕。由于相同的用戶事件會在對接的輸出設備(屏幕)上執行不同的渲染動作,因此應用程序是有狀態的,無法定義一個數學函數使 action = f(event)。

          我們稱 函數 **** 式 UI 為用戶界面應用程序的一組實現技術,其重點在于以下內容:

          • 將事件表示與事件調度分離開來
          • 將動作表示與動作執行分離開來
          • 將應用程序執行的動作與應用程序接收到的事件關聯在一起的顯式純函數( 響應函數 )

          因此,函數式 UI 隔離了應用程序的效果部分(調度事件,運行效果),并將它們與純函數鏈接在一起。結果,函數式 UI 自然會產生分層的架構,其中每一層僅與相鄰層交互。最簡單的分層架構由三層組成,可以表示如下:

          命令處理程序(command handler)模塊負責執行通過每個接口系統定義的編程接口所接收的命令。接口系統(interfaced system)可以將針對之前 API 調用的響應作為事件,發送給命令處理程序。接口系統還可以通過一個調度程序(dispatcher)將事件發送給應用程序。DOM 通常就是這種情況,它是以渲染命令的結果來做更新的,并且包含事件處理程序,它們只會調度事件。

          這樣的概念框架建立起來后,我們來介紹實現函數式 UI 的基本等式。


          響應式系統的基本等式

          在大多數情況下,一個響應式系統的狀態可以表述為這樣的形式:(action, new state) = f(state,event),其中:

          • f 是一個純函數,
          • state 包含由環境和響應式系統的規范帶來的所有可變性,這樣 f 就是純粹的。

          這里的 f 被稱為 響應函數 。如果我們用自然整數按時間順序來索引,以使索引 n 對應于發生的第 n 個事件,則以下條件成立:

          • (action_n, state_n+1) = f(state_n, event_n) ,其中:
            • n 是響應式系統處理的第 n 個事件,
            • state_n 是 處理第 n 個事件時 響應式系統的狀態,
            • 因此,在事件的發生和用于計算(compute)系統響應的狀態之間存在一個隱式的 時間關系 。

          基于這些觀察結果而誕生的實現技術依賴于一個響應函數 f,該函數為每個事件 顯式 計算響應式系統的新狀態,以及要執行的動作。這方面知名的例子有:

          • Elm :其中 update :: Msg -> Model -> (Model, Cmd Msg) 函數嚴格對應響應函數 f,Msg 對應 events,Model 對應狀、states,Cmd Msg 對應 actions。
          • Pux(PureScript):其中 foldp :: Event -> State -> EffModel State Event 函數是 Pux 框架中的等效公式。在 Pux 中,EffModel State Event 是包含新狀態值和一組效果(動作)的一個記錄,這些效果可能會生成新的事件供應用程序處理。
          • Seed(Rust) :其更新函數 fn update(msg: Msg, model: &mut Model, _: &mut impl Orders ) 對應的是 Elm 更新函數(Cmd 變成了 Orders),同時利用了 Rust 帶來的可變性。

          下面我們來看一些具體示例。在純函數式語言中,函數式 UI 是使用這類語言編程的自然結果。在其他語言(例如 JavaScript)中,開發人員需要努力遵循函數式 UI 的原則。下文提供了分別使用純函數式語言 Elm 和香草 JavaScript 編寫函數式 UI 的示例。


          示例

          Elm

          下面展示一個 簡單的 Elm 應用程序 的示例,其在單擊一個按鈕時顯示隨機的小貓動圖:

          -- 按一個按鈕,發送一個 GET 請求來獲取隨機的小貓動圖。
          -- 工作機制介紹: https://guide.elm-lang.org/effects/json.html
          
          (some imports...)
          
          -- MAIN
          main =
            Browser.element
              { init = init
              , update = update
              , view = view
              }
          
          -- MODEL
          type Model
            = Failure
            | Loading
            | Success String
          
          -- Initial state
          init : () -> (Model, Cmd Msg)
          init _ =
            (Loading, getRandomCatGif)
          
          -- UPDATE
          type Msg
            = MorePlease
            | GotGif (Result Http.Error String)
          
          update : Msg -> Model -> (Model, Cmd Msg)
          update msg model =
            case msg of
              MorePlease ->
                (Loading, getRandomCatGif)
          
              GotGif result ->
                case result of
                  Ok url ->
                    (Success url, Cmd.none)
          
                  Err _ ->
                    (Failure, Cmd.none)
          
          -- VIEW
          view : Model -> Html Msg
          view model =
            div []
              [ h2 [] [ text "Random Cats" ]
              , viewGif model
              ]
          
          viewGif : Model -> Html Msg
          viewGif model =
            case model of
              Failure ->
                div []
                  [ text "I could not load a random cat for some reason. "
                  , button [ onClick MorePlease ] [ text "Try Again!" ]
                  ]
          
              Loading ->
                text "Loading..."
          
              Success url ->
                div []
                  [ button [ onClick MorePlease, style "display" "block" ] [ text "More Please!" ]
                  , img [ src url ] []
                  ]
          
          -- HTTP
          getRandomCatGif : Cmd Msg
          getRandomCatGif =
            Http.get
              { url = "https://api.giphy.com/v1/gifs/random?api_key=dc6zaTOxFJmzC&tag=cat"
              , expect = Http.expectJson GotGif gifDecoder
              }
          
          gifDecoder : Decoder String
          gifDecoder =
            field "data" (field "image_url" string)

          從代碼中可以推斷出:

          • 該應用程序始于某個初始狀態,并運行一個初始命令(init _ = (Loading, getRandomCatGif))
          • 該初始狀態會顯示一個由 view 函數生成的初始視圖
          • 點擊一個 view 按鈕會將 MorePlease 消息發送到 Elm 的運行時([ button [ onClick MorePlease, … ])
          • 其中 update 函數 update msg model = case msg of MorePlease -> (Loading, getRandomCatGif) 將確保有一個 MorePlease 消息來獲取一張隨機的小貓動圖,同時將應用程序的狀態(model)更新為 Loading(從而使用戶界面顯示一條加載消息)。
          • 如果獲取成功,它將返回一個 URL(GotGif Ok url 消息),使用戶界面顯示相應的圖像(img [ src url ])

          除了 update 函數外,Elm 還定義了一個運行時,負責接收事件,將事件傳遞給更新函數,并執行所計算的(computed)命令。因此,開發人員只需要定義應用程序狀態和更新函數的內容。有了一個 單獨的,中心化 的 update 函數來計算針對事件的響應,我們就能輕松回答 " 當事件 [X,Y,……] 發生時會出現什么情況 " 這樣的問題。


          香草 JavaScript

          在 JavaScript 世界中, Hyperapp 這個框架采用的架構深受 Elm 的影響,只是細節略有不同。Hyperapp 非常輕巧(2KB),其中大多數代碼(80%)專門用來處理它自己的虛擬 DOM 實現。但是,Hyperapp 不會公開一個純粹的響應函數,而是像 Elm 一樣使用一個 view 函數。與 Elm 不同,這里的 view 函數不僅將某個狀態作為其第一個參數來接收,還將包含應用程序可執行的所有動作的對象作為第二個參數來接收。

          因此 view 函數不是純函數,而是 Jessica Kerr 所描述的 隔離函數 。這意味著該函數僅有的依賴項是它的參數。純函數是隔離的,但是隔離函數不一定是純函數,因為它們的參數可能是生成效果的函數,或受外部世界控制的變量。但是如有必要,我們仍然可以通過 mocking 隔離函數的參數來對它們進行單元測試。于是乎,Hyperapp 無法遵循函數式 UI 的原則,但仍然保留了函數式 UI 的某些長處。

          想要了解如何使用 Hyperapp 構建相對復雜的應用程序,讀者可以參考 Hyperapp 的一個名為 Conduit 的( Medium 克隆版示例應用 )實現。這個應用程序也有一個 Elm 實現 ,以及其他十幾個框架中的實現版本。

          但在使用 JavaScript 實現用戶界面時,無需放棄任何函數式 UI 原則。在一個假想的實現中,應用程序外殼負責將事件源連接到更新函數,并用類似的方式將更新函數連接到執行所計算的動作的模塊,從而復制各種事件循環。update 函數可以采用以下形式(舉例),用單個{command, params}對象編碼其返回值(在 Elm 中為 Cmd Msg 類型)。

          這里我們考慮使用前面討論過的,顯示隨機小貓動圖的應用程序,做一個 JavaScript 的等效實現 。更新函數如下:

          // Update function
          function update(event, model) {
            // Event has shape `{[eventName]: eventData}`
            const eventName = Object.keys(event)[0];
            const eventData = event[eventName];
          
            if (eventName === MORE_PLEASE) {
              return {
                model: LOADING,
                commands: [
                  { command: GET_RANDOM_CAT_GIF, params: void 0 },
                  { command: RENDER, params: void 0 }
                ]
              };
            } else if (eventName === GOT_GIF) {
              if (eventData instanceof Error) {
                return {
                  model: FAILURE,
                  commands: [{ command: RENDER, params: void 0 }]
                };
              } else {
                const url = eventData;
                return {
                  model: SUCCESS,
                  commands: [{ command: RENDER, params: url }]
                };
              }
            }
          
            // 一些預期外的 event, 應該什么都不會做
            return {
              model: model,
              commands: []
            };

          這里有一個基本的事件發射器用來調度事件。盡管這里可以使用任何 UI 框架的渲染函數,但這個簡單演示中的渲染函數是通過直接 DOM 克隆來實現的。因此,命令執行如下:

           復制代碼

          [MORE_PLEASE, GOT_GIF].forEach(event => {
            eventEmitter.on(event, eventData => {
              const { model: updatedModel, commands } = update(
                { [event]: eventData },
                model
              );
              model = updatedModel;
          
              if (commands) {
                commands.filter(Boolean).forEach(({ command, params }) => {
                  if (command === GET_RANDOM_CAT_GIF) {
                    getRandomCatGif()
                      .then(response => {
                        if (!response.ok) {
                          console.warn(`Network request error`, response.status);
                          throw new Error(response);
                        } else return response.json();
                      })
                      .then(x => {
                        if (x instanceof Error) {
                          eventEmitter.emit(GOT_GIF, x);
                        }
                        if (x && x.data && x.data.image_url) {
                          eventEmitter.emit(GOT_GIF, x.data.image_url);
                        }
                      })
                      .catch(x => {
                        eventEmitter.emit(GOT_GIF, x);
                      });
                  }
                  if (command === RENDER) {
                    if (model === LOADING) {
                      setDOM(initViewEl.cloneNode(true), appEl);
                    } else if (model === FAILURE) {
                      setDOM(failureViewEl.cloneNode(true), appEl);
                    } else if (model === SUCCESS) {
                      const url = params;
                      setDOM(successViewEl(url).cloneNode(true), appEl);
                    }
                  }
                });
              }
            });

          如上所述,自己來實現函數式 UI 是非常簡單的。如果你想重用現有的解決方案,可以考慮 raj 或 ferp 項目這些很有用的庫,它們嚴格遵循函數式 UI 原則。你不必擔心它們會超出你的應用程序預算。整個 raj 庫非常小(33 行代碼),因此可以完整粘貼在這里:

          exports.runtime = function (program) {
            var update = program.update
            var view = program.view
            var done = program.done
            var state
            var isRunning = true
          
            function dispatch (message) {
              if (isRunning) {
                change(update(message, state))
              }
            }
          
            function change (change) {
              state = change[0]
              var effect = change[1]
              if (effect) {
                effect(dispatch)
              }
              view(state, dispatch)
            }
          
            change(program.init)
          
            return function end () {
              if (isRunning) {
                isRunning = false
                if (done) {
                  done(state)
                }
              }
            }
          }

          盡管類似 Elm 的實現從根本上講很簡單,但與基于組件的實現相比,用它通常可以更好地了解應用程序的行為。一般來說,基于組件的實現可以讓你很快搞明白用戶界面會長什么樣,但你可能不得不費力地從組件的實現細節中分辨出界面的行為(發生事件 X 時出現的情況)。換句話說,基于組件的實現可通過組件重用來優化生產力,而 函數 **** 式 UI 實現可將用例與實現匹配,從而提升正確性 。


          單元測試用戶場景

          響應式系統運行時會產生蹤跡(trace),也就是運行期間發生的(events, actions)序列。為了讓響應式系統的行為正確,應設置一組允許的蹤跡。相對應的,測試響應式系統時要驗證實際蹤跡與許可蹤跡的集合是否匹配。從我們的基本等式得出的另一個純函數可用于此用途:

          For all n: (action_n, state_n+1) = f(state_n, event_n)

          先前的等式意味著:

          (action_0, state_1) = f(state_0, event_0)
          (action_1, state_2) = f(state_1, event_1)
          (action_2, state_3) = f(state_2, event_2)
          ...
          (action_n, state_n+1) = f(state_n, event_n)

          如果我們將 h 定義為將事件序列映射到相應動作序列的函數:

          h([event_0]) = [action_0]
          h([event_0, event_1]) = [action_0, action_1]
          h([event_0, event_1, event_2]) = [action_0, action_1, action_2]
          h([event_0, event_1, event_2, ..., event_n]) = [action_0, action_1, action_2, ..., action_n]

          那么 h 就是一個 純函數 !這意味著 h 可以很容易地測試,只需向其提供輸入并檢查它是否產生了預期的輸出即可。請注意,在 h 中不會再提及應用程序的狀態。由此以來我們就有了以下結果:

          • 可以單獨測試用戶場景 ,也就是說可以對各個用戶場景進行單元測試,因為各個用戶場景都是具有各自期望動作的事件序列
          • 針對應用程序的指定行為進行測試,而不是針對實現細節(例如應用程序狀態的形狀,或者用來獲取數據的 HTTP 或套接字)進行測試
          • 對用戶場景進行單元測試使開發人員能夠遵循 測試金字塔 原則,并在他們的一大堆單元測試中添加少量針對性的集成和端到端測試
          • 因此,開發人員無需執行運行時間過長或不穩定的測試,他們的工作效率就會更高(集成和端到端測試編寫起來昂貴且難以維護)
          • 開發人員可以選擇任何測試框架(或哪個都不用)

          當用戶場景測試可以快速編寫和執行時,就可以在給定的時間內設想和測試更多的用戶場景。由于用戶場景是簡單的序列,因此更容易自動生成此類序列。在使用狀態機對用戶界面行為建模的情況下,實際上我們可以 自動生成數以千計的測試 ,這樣比起來手工且痛苦地編寫測試,我們就可以覆蓋更多用戶場景和邊緣案例。

          最終的成果是我們能較早發現設計和實現錯誤,從而帶來更快的迭代和更高的軟件質量。毫無疑問,這是函數式 UI 技術的主要賣點,也是在安全性優先的軟件開發項目中使用它們的關鍵因素所在。


          結論

          用戶界面都是響應式系統,因此可以使用一個純響應函數,將用戶界面接受的事件映射到接口系統上的動作來定義用戶界面。利用函數式編程的實現技術可以讓實現更接近規范,更易推理和測試。函數式 UI 可以讓開發人員擺脫不兼容的 UI 和測試框架帶來的麻煩,并將重點轉移到實現(how)上的規范(what)上。也許有人懷疑沒有 UI 框架就沒法開發嚴肅的應用程序,但我們要知道 GitHub 網站就不依賴任何 UI 框架 。

          使用函數式 UI(它強調隔離的,單關注點的動作)和 UI 組件時,大多數時候我們只關注視圖——一些框架將此類組件稱為  組件。此外,應用程序外殼程序會調用 UI 框架,而不是 UI 框架調用用戶提供的框架感知函數。簡而言之,UI 框架仍然可以使用,但它們現在只充當簡單的庫而已。

          另一面來說,使用函數式 UI 時很難重用非純組件,從而降低了框架組件生態系統的價值。此外,函數式 UI 需要前端開發人員在心態和方法上都做出轉變,以前大家相比應用程序行為要更重視渲染(在屏幕上生成內容),并且更在乎生產效率(編寫代碼) 而非正確性(需要編寫全面的測試)。

          但是,Elm 在其七年的發展歷程中已經驗證了函數式 UI 方法的可行性,并證明只要有適當的工具,開發人員就可以 快速學習并享受這種方法 。

          原文鏈接:Functional UI (Framework-Free at Last)


          吐血推薦

          1.站長廣告聯盟: 整理了目前主流的廣告聯盟平臺,如果你有流量,可以作為參考選擇適合你的平臺點擊進入...

          2.休閑娛樂: 直播/交友    優惠券領取   網頁游戲   H5游戲

          鏈接: http://www.modern-decoration.com.cn/article/detial/7793

          Web服務常用的幾種開發方法

          Web服務,即通過程序實現網頁服務,服務啟動后,一般用戶可通過訪問URL獲取到網站提供的網頁服務,如網頁瀏覽、留言、商品購買等。開發Web服務的技術有很多,有Java、Python、ASP.NET、腳本語言等

          5 張圖描繪Web3 堆棧全景

          Web3 堆棧最令人難以置信的一點是,它們不需要任何集中協調就可以組合在一起。開發本身是去中心化的。沒有主架構師。這與地球上幾乎所有其他的開發堆棧項目形成了鮮明的對比。在 Linux 基金會,少數人設定整個 Linux 的方向

          web開發新手應該知曉的20件事

          在我當初剛從事 web 開發的時候,有很多重要的事我并沒有事先了解。現在看來,我的很多期望都和現實有很大的差距。在這篇文章里,我會告訴你 20 件事情,這些都是在你準備開始或者剛開始 web 開發不久的時候就應該知曉的

          Web前端開發的應用和前景:web 1.0到web 3.0

          web3.0時代,前端做著前端的工作,盡自己可能去在多端的世界去為用戶體驗努力,后端去做著后端的工作,去更好的處理數據,利用人工智能?利用爬蟲?將數據充分的使用,為用戶分析數據,給予用戶最想要的數據。

          W3C是什么?IETF是什么?

          無規矩不成方圓,軟件開發當然不能例外。Web開發涉及的廠商和技術非常多,所以必須要有參考的標準,而且需要一系列的標準。Web程序都是通過瀏覽器來解析執行的,通過頁面的展示內容與用戶互動,所以Web標準不僅要求各個瀏覽器都要遵循

          如何遷移Flutter項目到Flutter Web?

          這篇簡單介紹下怎么將一個現有的 Flutter 項目轉成 Flutter Web 項目。開始之前先澆一盆冷水,我們理想中的一套代碼、多端運行的愿望是要破滅了,至少目前版本的 Flutter Web SDK 是沒法做到的

          Gavin Wood:創造一個web3.0的加密世界

          我最早是以太坊的聯合創始人,也是CTO,黃皮書的作者。當開啟以太坊時,我們是局外人,關注的焦點更多的是BTC。當時,人們將投身以太坊視為浪費時間和精力。但現在以太坊已經成長起來,進入了完整循環。但與此同時

          web頁面的回流和重繪

          什么是回流? 回流也叫重排(reflow),當頁面中的元素發生影響布局的變化,比如:改變寬高,修改顯示影藏。頁面需要重新布局,就會觸發重排。 簡單的說就是,頁面布局改變,就會觸發重排。

          Web實現前后端分離,前后端解耦

          前后端分離“已經成為互聯網項目開發的業界標桿,通過Tomcat+Ngnix(也可以中間有個Node.js),有效地進行解耦。并且前后端分離會為以后的大型分布式架構、彈性計算架構、微服務架構、多端化服務

          為什么說 Web 開發的未來在于組件?

          預測未來并非易事。在預測社會現象的未來趨勢時,我們不能認為未來就是當下現狀的簡單線性延伸——而 Web 開發就是一種社會現象

          fly63.com版權所有,內容以共享、參考、研究為目的,不存在任何商業目的。其版權屬原作者所有,如有侵權,請與小編聯系!情況屬實本人將予以刪除!

          文章投稿關于web前端網站點搜索站長推薦網站地圖站長QQ:522607023

          小程序專欄: 土味情話心理測試腦筋急轉彎幽默笑話段子句子語錄成語大全

          国产精品高清视频免费 - 视频 - 在线观看 - 影视资讯 - 唯爱网