摘要:引言本周精讀的文章是,看看作者是如何解釋這個多態性含義的。讀完文章才發現,文章標題改為的多態性更妥當,因為整篇文章都在說,而使用場景不局限于。更多討論討論地址是精讀的多態性如果你想參與討論,請點擊這里,每周都有新的主題,周末或周一發布。
1 引言
本周精讀的文章是:surprising-polymorphism-in-react-applications,看看作者是如何解釋這個多態性含義的。
讀完文章才發現,文章標題改為 Redux 的多態性更妥當,因為整篇文章都在說 Redux,而 Redux 使用場景不局限于 React。
2 概述Redux immutable 特性可能產生瀏覽器無法優化的性能問題,也就是瀏覽器無法做 shapes 優化,也就是上一篇精讀《JS 引擎基礎之 Shapes and Inline Caches》 里提到的。
先看看普通的 redux 的 reducer:
const todo = (state = {}, action) => { switch (action.type) { case "ADD_TODO": return { id: action.id, text: action.text, completed: false }; case "TOGGLE_TODO": if (state.id !== action.id) { return state; } return Object.assign({}, state, { completed: !state.completed }); default: return state; } };
我們簡化一下使用場景,假設基于這個 reducer todo,生成了兩個新 store s1 s2:
const s1 = todo( {}, { type: "ADD_TODO", id: 1, text: "Finish blog post" } ); const s2 = todo(s1, { type: "TOGGLE_TODO", id: 1 });
看上去很常見,也的確如此,我們每次 dispatch 都會根據 reducer 生成新的 store 樹,而且是一個新的對象。然而對 js 引擎而言,這樣的代碼可能做不了 Shapes 優化(關于 Shapes 優化建議閱讀上一期精讀 Shapes 優化),也就是最需要做優化的全局 store,在生成新 store 時無法被瀏覽器優化,這個問題很容易被忽視,但的確影響不小。
至于為什么會阻止 js 引擎的 shapes 優化,看下面的代碼:
// transition-trees.js let a = {x:1, y:2, z:3}; let b = {}; b.x = 1; b.y = 2; b.z = 3; console.log("a is", a); console.log("b is", b); console.log("a and b have same map:", %HaveSameMap(a, b));
通過 node --allow-natives-syntax test.js 執行,通過調用 node 原生函數 %HaveSameMap 判斷這種情況下 a 與 b 是否共享一個 shape(v8 引擎的 Shape 實現稱為 Map)。
結果是 false,也就是 js 引擎無法對 a b 做 Shapes 優化,這是因為 a 與 b 對象初始化的方式不同。
同樣,在 Redux 代碼中常用的 Object.assign 也有這個問題:
因為新的對象以 {} 空對象作為最初狀態,js 引擎會為新對象創建 Empty Shape,這與原對象的 Shape 一定不同。
順帶一提 es6 的解構語法也存在同樣的問題,因為 babel 將解構最終解析為 Object.assign:
對這種尷尬的情況,作者的建議是對所有對象賦值時都是用 Object.assign 以保證 js 引擎可以做 Shapes 優化:
let a = Object.assign({}, {x:1, y:2, z:3}); let b = Object.assign({}, a); console.log("a is", a); console.log("b is", b); console.log("a and b have same map:", %HaveSameMap(a, b)); // true3 精讀
這篇文章需要與上一篇 精讀《JS 引擎基礎之 Shapes and Inline Caches》 連起來看容易理解。
作者描述的性能問題是引擎級別的 Shapes 優化問題,讀過上篇精讀就很容易知道,只有相同初始化方式的對象才被 js 引擎做優化,而 Redux 頻繁生成的 immutable 全局 store 是否能被優化呢?答案是“往往不能”,因為 immutable 賦值問題,我們往往采用 Object.assign 或者解構方式賦值,這種方式產生的新對象與原對象的 Shape 不同,導致 Shape 無法復用。
這里解釋一下疑惑,為什么說 immutable 對象之間也要優化呢?這不是兩個不同的引用嗎?這是因為 js 引擎級別的 Shapes 優化就是針對不同引用的對象,將對象的結構:Shape 與數據分離開,這樣可以大幅優化存儲效率,對數組也一樣,上一篇精讀有詳細介紹。
所以筆者更推薦使用比如 immutable-js 這種庫操作 immutable 對象,而不是 Object.assign,因為封裝庫內部是可能通過統一對象初始化方式利用 js 引擎進行優化的。
4 總結原文提到的多態是指多個相同結構對象,被拆分成了多個 Shape;而單態是指這些對象可以被一個 Shape 復用。
筆者以前也經歷過從 Object.assign 到 Immutablejs 庫,最后又回到解構新語法的經歷,覺得在層級不深情況下解構語法可以代替 Immutablejs 庫。
通過最近兩篇精讀的分析,我們需要重新思考這樣做帶來的優缺點,因為在 js 環境中,Object.assign 的優化效率比 Immutablejs 庫更低。
最后,也完全沒必要現在就開始重構,因為這只是 js 運行環境中很小一部分影響因素,比如為了引入 Immutablejs 讓你的網絡延時增加了 100%?所以僅在有必要的時候優化它。
5 更多討論討論地址是:精讀《React 的多態性》 · Issue #92 · dt-fe/weekly
如果你想參與討論,請點擊這里,每周都有新的主題,周末或周一發布。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/95875.html
摘要:今天我們就來解讀一下的源碼。比較有意思,將定時器以方式提供出來,并且提供了方法。實現方式是,在組件內部維護一個定時器,實現了組件更新銷毀時的計時器更新銷毀操作,可以認為這種定時器的生命周期綁定了組件的生命周期,不用擔心銷毀和更新的問題。 1. 引言 React PowerPlug 是利用 render props 進行更好狀態管理的工具庫。 React 項目中,一般一個文件就是一個類,...
摘要:會自動觸發函數內回調函數的執行。因此利用并將依賴置為使代碼在所有渲染周期內,只在初始化執行一次。同時代碼里還對等公共方法進行了包裝,讓這些回調函數中自帶效果。前端精讀幫你篩選靠譜的內容。 1. 引言 react-easy-state 是個比較有趣的庫,利用 Proxy 創建了一個非常易用的全局數據流管理方式。 import React from react; import { stor...
摘要:未來可能成為官方之一。討論地址是精讀組件如果你想參與討論,請點擊這里,每周都有新的主題,周末或周一發布。前端精讀幫你篩選靠譜的內容。 1. 引言 為什么要了解 Function 寫法的組件呢?因為它正在變得越來越重要。 那么 React 中 Function Component 與 Class Component 有何不同? how-are-function-components-di...
摘要:拿到的都是而不是原始值,且這個值會動態變化。精讀對于的與,筆者做一些對比。因此采取了作為優化方案只有當第二個依賴參數變化時才返回新引用。不需要使用等進行性能優化,所有性能優化都是自動的。前端精讀幫你篩選靠譜的內容。 1. 引言 Vue 3.0 的發布引起了軒然大波,讓我們解讀下它的 function api RFC 詳細了解一下 Vue 團隊是怎么想的吧! 首先官方回答了幾個最受關注的...
閱讀 1243·2021-09-26 09:46
閱讀 1595·2021-09-06 15:00
閱讀 728·2019-08-30 15:52
閱讀 1128·2019-08-29 13:10
閱讀 1291·2019-08-26 13:47
閱讀 1487·2019-08-26 13:35
閱讀 2036·2019-08-23 18:38
閱讀 735·2019-08-23 17:59