摘要:引言本周精讀的文章是,看看作者是如何解釋這個多態(tài)性含義的。讀完文章才發(fā)現(xiàn),文章標(biāo)題改為的多態(tài)性更妥當(dāng),因為整篇文章都在說,而使用場景不局限于。更多討論討論地址是精讀的多態(tài)性如果你想?yún)⑴c討論,請點擊這里,每周都有新的主題,周末或周一發(fā)布。
1 引言
本周精讀的文章是:surprising-polymorphism-in-react-applications,看看作者是如何解釋這個多態(tài)性含義的。
讀完文章才發(fā)現(xiàn),文章標(biāo)題改為 Redux 的多態(tài)性更妥當(dāng),因為整篇文章都在說 Redux,而 Redux 使用場景不局限于 React。
2 概述Redux immutable 特性可能產(chǎn)生瀏覽器無法優(yōu)化的性能問題,也就是瀏覽器無法做 shapes 優(yōu)化,也就是上一篇精讀《JS 引擎基礎(chǔ)之 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; } };
我們簡化一下使用場景,假設(shè)基于這個 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 都會根據(jù) reducer 生成新的 store 樹,而且是一個新的對象。然而對 js 引擎而言,這樣的代碼可能做不了 Shapes 優(yōu)化(關(guān)于 Shapes 優(yōu)化建議閱讀上一期精讀 Shapes 優(yōu)化),也就是最需要做優(yōu)化的全局 store,在生成新 store 時無法被瀏覽器優(yōu)化,這個問題很容易被忽視,但的確影響不小。
至于為什么會阻止 js 引擎的 shapes 優(yōu)化,看下面的代碼:
// 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 執(zhí)行,通過調(diào)用 node 原生函數(shù) %HaveSameMap 判斷這種情況下 a 與 b 是否共享一個 shape(v8 引擎的 Shape 實現(xiàn)稱為 Map)。
結(jié)果是 false,也就是 js 引擎無法對 a b 做 Shapes 優(yōu)化,這是因為 a 與 b 對象初始化的方式不同。
同樣,在 Redux 代碼中常用的 Object.assign 也有這個問題:
因為新的對象以 {} 空對象作為最初狀態(tài),js 引擎會為新對象創(chuàng)建 Empty Shape,這與原對象的 Shape 一定不同。
順帶一提 es6 的解構(gòu)語法也存在同樣的問題,因為 babel 將解構(gòu)最終解析為 Object.assign:
對這種尷尬的情況,作者的建議是對所有對象賦值時都是用 Object.assign 以保證 js 引擎可以做 Shapes 優(yōu)化:
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 引擎基礎(chǔ)之 Shapes and Inline Caches》 連起來看容易理解。
作者描述的性能問題是引擎級別的 Shapes 優(yōu)化問題,讀過上篇精讀就很容易知道,只有相同初始化方式的對象才被 js 引擎做優(yōu)化,而 Redux 頻繁生成的 immutable 全局 store 是否能被優(yōu)化呢?答案是“往往不能”,因為 immutable 賦值問題,我們往往采用 Object.assign 或者解構(gòu)方式賦值,這種方式產(chǎn)生的新對象與原對象的 Shape 不同,導(dǎo)致 Shape 無法復(fù)用。
這里解釋一下疑惑,為什么說 immutable 對象之間也要優(yōu)化呢?這不是兩個不同的引用嗎?這是因為 js 引擎級別的 Shapes 優(yōu)化就是針對不同引用的對象,將對象的結(jié)構(gòu):Shape 與數(shù)據(jù)分離開,這樣可以大幅優(yōu)化存儲效率,對數(shù)組也一樣,上一篇精讀有詳細(xì)介紹。
所以筆者更推薦使用比如 immutable-js 這種庫操作 immutable 對象,而不是 Object.assign,因為封裝庫內(nèi)部是可能通過統(tǒng)一對象初始化方式利用 js 引擎進(jìn)行優(yōu)化的。
4 總結(jié)原文提到的多態(tài)是指多個相同結(jié)構(gòu)對象,被拆分成了多個 Shape;而單態(tài)是指這些對象可以被一個 Shape 復(fù)用。
筆者以前也經(jīng)歷過從 Object.assign 到 Immutablejs 庫,最后又回到解構(gòu)新語法的經(jīng)歷,覺得在層級不深情況下解構(gòu)語法可以代替 Immutablejs 庫。
通過最近兩篇精讀的分析,我們需要重新思考這樣做帶來的優(yōu)缺點,因為在 js 環(huán)境中,Object.assign 的優(yōu)化效率比 Immutablejs 庫更低。
最后,也完全沒必要現(xiàn)在就開始重構(gòu),因為這只是 js 運行環(huán)境中很小一部分影響因素,比如為了引入 Immutablejs 讓你的網(wǎng)絡(luò)延時增加了 100%?所以僅在有必要的時候優(yōu)化它。
5 更多討論討論地址是:精讀《React 的多態(tài)性》 · Issue #92 · dt-fe/weekly
如果你想?yún)⑴c討論,請點擊這里,每周都有新的主題,周末或周一發(fā)布。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/95875.html
摘要:前端進(jìn)階進(jìn)階構(gòu)建項目一配置最佳實踐狀態(tài)管理之痛點分析與改良開發(fā)中所謂狀態(tài)淺析從時間旅行的烏托邦,看狀態(tài)管理的設(shè)計誤區(qū)使用更好地處理數(shù)據(jù)愛彼迎房源詳情頁中的性能優(yōu)化從零開始,在中構(gòu)建時間旅行式調(diào)試用輕松管理復(fù)雜狀態(tài)如何把業(yè)務(wù)邏輯這個故事講好和 前端進(jìn)階 webpack webpack進(jìn)階構(gòu)建項目(一) Webpack 4 配置最佳實踐 react Redux狀態(tài)管理之痛點、分析與...
摘要:今天我們就來解讀一下的源碼。比較有意思,將定時器以方式提供出來,并且提供了方法。實現(xiàn)方式是,在組件內(nèi)部維護(hù)一個定時器,實現(xiàn)了組件更新銷毀時的計時器更新銷毀操作,可以認(rèn)為這種定時器的生命周期綁定了組件的生命周期,不用擔(dān)心銷毀和更新的問題。 1. 引言 React PowerPlug 是利用 render props 進(jìn)行更好狀態(tài)管理的工具庫。 React 項目中,一般一個文件就是一個類,...
摘要:會自動觸發(fā)函數(shù)內(nèi)回調(diào)函數(shù)的執(zhí)行。因此利用并將依賴置為使代碼在所有渲染周期內(nèi),只在初始化執(zhí)行一次。同時代碼里還對等公共方法進(jìn)行了包裝,讓這些回調(diào)函數(shù)中自帶效果。前端精讀幫你篩選靠譜的內(nèi)容。 1. 引言 react-easy-state 是個比較有趣的庫,利用 Proxy 創(chuàng)建了一個非常易用的全局?jǐn)?shù)據(jù)流管理方式。 import React from react; import { stor...
摘要:未來可能成為官方之一。討論地址是精讀組件如果你想?yún)⑴c討論,請點擊這里,每周都有新的主題,周末或周一發(fā)布。前端精讀幫你篩選靠譜的內(nèi)容。 1. 引言 為什么要了解 Function 寫法的組件呢?因為它正在變得越來越重要。 那么 React 中 Function Component 與 Class Component 有何不同? how-are-function-components-di...
摘要:拿到的都是而不是原始值,且這個值會動態(tài)變化。精讀對于的與,筆者做一些對比。因此采取了作為優(yōu)化方案只有當(dāng)?shù)诙€依賴參數(shù)變化時才返回新引用。不需要使用等進(jìn)行性能優(yōu)化,所有性能優(yōu)化都是自動的。前端精讀幫你篩選靠譜的內(nèi)容。 1. 引言 Vue 3.0 的發(fā)布引起了軒然大波,讓我們解讀下它的 function api RFC 詳細(xì)了解一下 Vue 團(tuán)隊是怎么想的吧! 首先官方回答了幾個最受關(guān)注的...
閱讀 1272·2021-09-26 09:46
閱讀 1616·2021-09-06 15:00
閱讀 747·2019-08-30 15:52
閱讀 1145·2019-08-29 13:10
閱讀 1303·2019-08-26 13:47
閱讀 1499·2019-08-26 13:35
閱讀 2050·2019-08-23 18:38
閱讀 751·2019-08-23 17:59