成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

React Redux 中間件思想遇見(jiàn) Web Worker 的靈感(附demo)

whatsns / 798人閱讀

摘要:寫在最前原文首發(fā)于作者的知乎專欄中間件思想遇見(jiàn)的靈感附,感興趣的同學(xué)可以知乎關(guān)注,進(jìn)行交流。其中,最重要的一個(gè)便是對(duì)多線程的支持。在中提出了工作線程的概念,并且規(guī)范出的三大主要特征能夠長(zhǎng)時(shí)間運(yùn)行響應(yīng)理想的啟動(dòng)性能以及理想的內(nèi)存消耗。

寫在最前

原文首發(fā)于作者的知乎專欄:React Redux 中間件思想遇見(jiàn) Web Worker 的靈感(附demo),感興趣的同學(xué)可以知乎關(guān)注,進(jìn)行交流。

熟悉 React 技術(shù)棧的同學(xué),想必對(duì) Redux 數(shù)據(jù)流框架并不陌生。其倡導(dǎo)的單向數(shù)據(jù)流等思想獨(dú)樹(shù)一幟,雖然樣板代碼會(huì)有一定程度上的增多,但是對(duì)于開(kāi)發(fā)效率和調(diào)試效率的提高是顯著的。同時(shí)還帶來(lái)了很多諸如 “時(shí)間旅行”,“ undo/redo ” 等黑魔法。

其實(shí)這還只是表象。如果你深入去了解 Redux 的設(shè)計(jì)理念,探索中間件奧秘,玩轉(zhuǎn)高階 reducer 等等,迎接你的就會(huì)是另一扇門。透過(guò)它,函數(shù)式編程思想之光傾斜如注。

思想背景

但是隨著這個(gè) web app 復(fù)雜度的提升,數(shù)據(jù)計(jì)算量壓力徒增,你所設(shè)計(jì)的 Reducer 變得臃腫不堪。好吧,我們可以拆分 Reducer 使得代碼看上去更加舒服。可是計(jì)算量呢?也許有一些“夢(mèng)魘”,瓶頸般永遠(yuǎn)無(wú)法消除。

冥冥之中,“各種處理計(jì)算既然注定在同一時(shí)空,那么能否永遠(yuǎn)平行?”

曾幾何時(shí),你是否聽(tīng)說(shuō)過(guò) JS 單線程異步?聽(tīng)說(shuō)過(guò)瀏覽器卡頓或卡死?聽(tīng)說(shuō)過(guò) 60 fps?

其實(shí)一個(gè)很嚴(yán)峻的事實(shí)是:根據(jù) 60 fps 計(jì)算,每一幀留給我們 JS 執(zhí)行的時(shí)間為 16ms(甚至更少)。那么一旦當(dāng) Reducer 計(jì)算時(shí)間過(guò)長(zhǎng),必然會(huì)影響瀏覽器渲染。

多線程思路

關(guān)于瀏覽器主線程、render queue、event loop、call stack 等內(nèi)容,本文不再?gòu)?fù)述,因?yàn)槔锩娴闹R(shí)完全都?jí)驅(qū)懸槐緯恕<俣ㄗx者對(duì)其有一二認(rèn)知,那么你也不難理解我們即將登場(chǎng)的救星—— Web Worker!

我們先來(lái)簡(jiǎn)單認(rèn)識(shí)一下 web worker:

2008 年 W3C 制定出第一個(gè) HTML5 草案開(kāi)始,HTML5 承載了越來(lái)越多嶄新的特性和功能。其中,最重要的一個(gè)便是對(duì)多線程的支持。在 HTML5 中提出了工作線程(Web Worker)的概念,并且規(guī)范出 Web Worker 的三大主要特征:

能夠長(zhǎng)時(shí)間運(yùn)行(響應(yīng));

理想的啟動(dòng)性能;

以及理想的內(nèi)存消耗。

Work 線程可以執(zhí)行任務(wù)而不干擾用戶界面。

于是,腦洞大開(kāi),能否將我們的 Redux Reducer 計(jì)算狀態(tài)部分放進(jìn) Worker 線程中處理呢?

答案是肯定的。
那么要如何實(shí)施呢?

我們先來(lái)看一下經(jīng)典的 Redux workflow,如下圖:

如果要接入 Web Work,那么我們改動(dòng)流程圖如下:

具體實(shí)現(xiàn)和一個(gè)demo

當(dāng)然,有了思路,還需要在實(shí)戰(zhàn)中演練。

我使用 “N-皇后問(wèn)題” 模擬大型計(jì)算,并且實(shí)現(xiàn)的 demo 中可以任意設(shè)置 n 值,增加計(jì)算耗時(shí)。
如果你不理解此算法也沒(méi)有關(guān)系,只需要知道N-皇后問(wèn)題這個(gè)算法的計(jì)算耗時(shí)很長(zhǎng),且和 n 值相關(guān):n 越大,計(jì)算成本越大。

除了一個(gè)極其耗時(shí)的計(jì)算,頁(yè)面中還運(yùn)行這么幾個(gè)模塊,來(lái)實(shí)現(xiàn)復(fù)雜的渲染邏輯操作:

一個(gè)實(shí)時(shí)每16毫秒,顯示計(jì)數(shù)(每秒增加1)的 blinker 模塊;

一個(gè)定時(shí)每500毫秒,更新背景顏色的 counter 模塊;

一個(gè)永久往復(fù)運(yùn)動(dòng)的 slider 模塊;

一個(gè)每16毫秒翻轉(zhuǎn)5度的 spinner 模塊

這些模塊都定時(shí)頻繁地更新 dom 樣式,進(jìn)行大量復(fù)雜的渲染計(jì)算。正常情況下,由于 JS 主線程進(jìn)行N-皇后計(jì)算,這些渲染過(guò)程都將被卡頓。

同時(shí),我設(shè)置“N-皇后問(wèn)題”的 n 值,來(lái)觀察在計(jì)算時(shí)這些模塊的表現(xiàn)(是否卡頓)。在不開(kāi)啟 Work 線程的情況下,n 設(shè)置為13時(shí),有 gif 圖,左半部分:

我們非常清晰地看到:由于瀏覽器 call stack 進(jìn)行 n=13 的皇后問(wèn)題計(jì)算,而無(wú)法“按時(shí)”渲染,所以造成了這幾個(gè)模塊的卡頓,這些模塊都無(wú)法更新?tīng)顟B(tài)。在這個(gè)卡頓過(guò)程中,用戶的任何事件(如點(diǎn)擊,敲鍵盤等)都無(wú)法被瀏覽器響應(yīng)。這就是用戶體會(huì)到的“慢”!

如果我把 n 值設(shè)置的大與13呢,比如24?
千萬(wàn)不要這么做!因?yàn)槟愕臑g覽器會(huì)被卡死!我使用 Mac Pro 8G 內(nèi)存情況下,設(shè)置到14,瀏覽器就無(wú)法響應(yīng)了。

在開(kāi)啟 Work 線程時(shí),請(qǐng)參考上 gif 圖右半部分,幾個(gè)模塊的渲染絲毫不受影響。完美達(dá)到了我們的目的。

因?yàn)?Reducer 的超級(jí)耗時(shí)計(jì)算被放入 Worker 線程當(dāng)中,所以絲毫沒(méi)有影響瀏覽器的渲染和響應(yīng)。完全解決了用戶覺(jué)得“電腦慢”的問(wèn)題。

看到了如此完美的對(duì)比,也許你想問(wèn) Web Worker 的兼容性如何呢?

總結(jié)

其實(shí),這篇文章的意義并不在于這個(gè) demo 和應(yīng)用。而是在啟發(fā)一種新的想法的同時(shí),review 了很多 JS 當(dāng)中關(guān)鍵概念和基本知識(shí)。比如:?jiǎn)尉€程異步、宿主環(huán)境、60 fps、一個(gè)算法等等。

更值得一提的是,如果你去深入 demo 代碼,你更會(huì)發(fā)現(xiàn) Redux 設(shè)計(jì)精妙的思想,比如我們將 Web Worker 的應(yīng)用抽象出一個(gè)公共庫(kù):Redux-Worker,并包裝為 Redux 的中間件(middleware),所有 React Redux 都可以無(wú)侵入,采用中間件的思想使用:

import { applyWorker } from "redux-worker";
const enhancerWithWorker = compose(
    applyMiddleware(thunk, logger),
    applyWorker(worker)
);

const store = createStore(rootReducer, {}, enhancerWithWorker);

當(dāng)然,Redux-Worker 這個(gè)中間件的實(shí)現(xiàn)原理更是巧妙,這里不再展開(kāi)。感興趣的同學(xué)可以參考我的此項(xiàng)目 Github 倉(cāng)庫(kù)。我 fork 了此庫(kù)源碼,并在核心邏輯加入了中文注釋,感興趣的同學(xué)可以關(guān)注。

我的其他關(guān)于 React 文章:

通過(guò)實(shí)例,學(xué)習(xí)編寫 React 組件的“最佳實(shí)踐”

React 組件設(shè)計(jì)和分解思考

[從 React 綁定 this,看 JS 語(yǔ)言發(fā)展和框架設(shè)計(jì)]()

React 服務(wù)端渲染如此輕松 從零開(kāi)始構(gòu)建前后端應(yīng)用

做出Uber移動(dòng)網(wǎng)頁(yè)版還不夠 極致性能打造才見(jiàn)真章

解析Twitter前端架構(gòu) 學(xué)習(xí)復(fù)雜場(chǎng)景數(shù)據(jù)設(shè)計(jì)

React Conf 2017 干貨總結(jié)1: React + ES next = ?

React+Redux打造“NEWS EARLY”單頁(yè)應(yīng)用 一個(gè)項(xiàng)目理解最前沿技術(shù)棧真諦

一個(gè)react+redux工程實(shí)例

Happy Coding!

PS:
作者Github倉(cāng)庫(kù) 和 知乎問(wèn)答鏈接
歡迎各種形式交流。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/91385.html

相關(guān)文章

  • React Render Array 性能大亂斗

    摘要:現(xiàn)在關(guān)于最新版本新特性的宣傳講解已經(jīng)鋪天蓋地了。測(cè)試場(chǎng)景是反復(fù)操作數(shù)組,這個(gè)反復(fù)操作有所講究,我們計(jì)劃持續(xù)不斷地改變數(shù)組的某一項(xiàng)而不是整個(gè)數(shù)組的大范圍變動(dòng)。代碼和性能測(cè)試在使用開(kāi)發(fā)時(shí),相信很多開(kāi)發(fā)者在搭配函數(shù)式的狀態(tài)管理框架使用。 現(xiàn)在關(guān)于 React 最新 v16 版本新特性的宣傳、講解已經(jīng)鋪天蓋地了。你最喜歡哪一個(gè) new feature?截至目前,組件構(gòu)建方式已經(jīng)琳瑯滿目。那么,...

    wenshi11019 評(píng)論0 收藏0
  • 2017-08-16 前端日?qǐng)?bào)

    摘要:前端日?qǐng)?bào)精選理解的專題之偏函數(shù)譯理解事件驅(qū)動(dòng)機(jī)制游戲開(kāi)發(fā)前端面試中的常見(jiàn)的算法問(wèn)題發(fā)布中文前端頁(yè)面?zhèn)鲄⑸袏y產(chǎn)品技術(shù)刊讀基礎(chǔ)系列二之實(shí)現(xiàn)大轉(zhuǎn)盤抽獎(jiǎng)掘金指南眾成翻譯編程插入排序眾成翻譯源碼講解函數(shù)技術(shù)風(fēng)暴初體驗(yàn)個(gè)人文 2017-08-16 前端日?qǐng)?bào) 精選 理解 JavaScript 的 async/awaitJavaScript專題之偏函數(shù)[譯]理解 Node.js 事件驅(qū)動(dòng)機(jī)制Pokem...

    graf 評(píng)論0 收藏0
  • 從 setState promise 化探討 體會(huì) React 團(tuán)隊(duì)設(shè)計(jì)思想

    摘要:我們來(lái)從設(shè)計(jì)思想上,和官方團(tuán)隊(duì)的回應(yīng)上,了解一下否決理由。此外,還有一個(gè)方法新的接口設(shè)計(jì)支持接收一個(gè)回調(diào)函數(shù),當(dāng)其子組件掛載時(shí),這個(gè)回調(diào)函數(shù)就會(huì)相應(yīng)觸發(fā)。 從 setState 那個(gè)眾所周知的小秘密說(shuō)起... 在 React 組件中,調(diào)用 this.setState() 是最基本的場(chǎng)景。這個(gè)方法描述了 state 的變化、觸發(fā)了組件 re-rendering。但是,也許看似平常的 th...

    caiyongji 評(píng)論0 收藏0
  • 從 setState promise 化探討 體會(huì) React 團(tuán)隊(duì)設(shè)計(jì)思想

    摘要:我們來(lái)從設(shè)計(jì)思想上,和官方團(tuán)隊(duì)的回應(yīng)上,了解一下否決理由。此外,還有一個(gè)方法新的接口設(shè)計(jì)支持接收一個(gè)回調(diào)函數(shù),當(dāng)其子組件掛載時(shí),這個(gè)回調(diào)函數(shù)就會(huì)相應(yīng)觸發(fā)。 從 setState 那個(gè)眾所周知的小秘密說(shuō)起... 在 React 組件中,調(diào)用 this.setState() 是最基本的場(chǎng)景。這個(gè)方法描述了 state 的變化、觸發(fā)了組件 re-rendering。但是,也許看似平常的 th...

    forrest23 評(píng)論0 收藏0
  • 漫談前端性能 突破 React 應(yīng)用瓶頸

    摘要:表示調(diào)用棧在下一將要執(zhí)行的任務(wù)。兩方性能解藥我們一般有兩種方案突破上文提到的瓶頸將耗時(shí)高成本高易阻塞的長(zhǎng)任務(wù)切片,分成子任務(wù),并異步執(zhí)行這樣一來(lái),這些子任務(wù)會(huì)在不同的周期執(zhí)行,進(jìn)而主線程就可以在子任務(wù)間隙當(dāng)中執(zhí)行更新操作。 showImg(https://segmentfault.com/img/remote/1460000016008111); 性能一直以來(lái)是前端開(kāi)發(fā)中非常重要的話題...

    whlong 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<