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