中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

小熊源碼網(wǎng)新網(wǎng)站百度seo如何做

小熊源碼網(wǎng),新網(wǎng)站百度seo如何做,網(wǎng)站建設(shè)靠什么賺錢,三河seo任務(wù)分割異步執(zhí)行讓出執(zhí)法權(quán) 文章目錄 1.React的設(shè)計理念1.1 Fiber1.2 Scheduler1.3 Lane1.4 代數(shù)效應(yīng) 2.React的源碼架構(gòu)2.1 大概圖示2.2 jsx2.3 Fiber雙緩存2.4 scheduler2.5 Lane模型2.6 reconciler2.7 renderer2.8 concurrent 3.React源碼調(diào)試 1.React的設(shè)計理念 Fiber: 即…
  1. 任務(wù)分割
  2. 異步執(zhí)行
  3. 讓出執(zhí)法權(quán)

文章目錄

      • 1.React的設(shè)計理念
        • 1.1 Fiber
        • 1.2 Scheduler
        • 1.3 Lane
        • 1.4 代數(shù)效應(yīng)
      • 2.React的源碼架構(gòu)
        • 2.1 大概圖示
        • 2.2 jsx
        • 2.3 Fiber雙緩存
        • 2.4 scheduler
        • 2.5 Lane模型
        • 2.6 reconciler
        • 2.7 renderer
        • 2.8 concurrent
      • 3.React源碼調(diào)試

1.React的設(shè)計理念

  1. Fiber: 即對應(yīng)真實(shí)dom, 又作為分隔單元。
  2. Scheduler: 用js實(shí)現(xiàn)一套時間片運(yùn)行的機(jī)制, 使得requestIdleCallback()的瀏覽器的兼容性和觸發(fā)不穩(wěn)定的問題解決。
  3. Lane: 異步調(diào)度有了, 需要細(xì)粒度的管理各個任務(wù)的優(yōu)先級, 讓高優(yōu)先級的先執(zhí)行, 各個Fiber工作單元還能比較優(yōu)先級, 優(yōu)先級相同的一起執(zhí)行。

上面的機(jī)制能實(shí)現(xiàn)batchedUpdates批量更新和Suspense

1.1 Fiber

Fiber: react15的更新是同步的,因?yàn)樗荒軐⑷蝿?wù)分割,所以需要一套數(shù)據(jù)結(jié)構(gòu)讓它既能對應(yīng)真實(shí)的dom又能作為分隔的單元,這就是Fiber。

  1. 對應(yīng)真實(shí)dom。
  2. 作為分割單元。
let firstFiber
let nextFiber = firstFiber
let shouldYield = false
//firstFiber->firstChild->sibling
function performUnitOfWork(nextFiber){//...return nextFiber.next
}function workLoop(deadline){while(nextFiber && !shouldYield){nextFiber = performUnitOfWork(nextFiber)shouldYield = deadline.timeReaming < 1}requestIdleCallback(workLoop)
}requestIdleCallback(workLoop)
1.2 Scheduler

Scheduler: 有了Fiber, 需要用瀏覽器的時間片異步執(zhí)行這些Fiber的工作單元, 有一個Api是requestIdleCallback(), 可以在瀏覽器空閑的時候執(zhí)行一些任務(wù), 用這個api執(zhí)行react的更新。requestIdleCallback存在著瀏覽器的兼容性和觸發(fā)不穩(wěn)定的問題, 需要用js實(shí)現(xiàn)一套時間片運(yùn)行的機(jī)制, react稱為Scheduler。

1.3 Lane

Lane: 異步調(diào)度有了, 需要細(xì)粒度的管理各個任務(wù)的優(yōu)先級, 讓高優(yōu)先級的先執(zhí)行, 各個Fiber工作單元還能比較優(yōu)先級, 優(yōu)先級相同的一起執(zhí)行。

1.4 代數(shù)效應(yīng)

除了cpu的瓶頸問題, 還存在一些副作用, 比如獲取數(shù)據(jù)、文件操作等。不同設(shè)備性能和網(wǎng)絡(luò)狀況都不一樣, react如何處理這些問題, 需要react可以有分離副作用的能力, 解耦, 這就是代數(shù)效應(yīng)。

function getPrice(id) {return fetch(`xxx.com?id=${productId}`).then((res)=>{return res.price})
}async function getTotalPirce(id1, id2) {const p1 = await getPrice(id1);const p2 = await getPrice(id2);return p1 + p2;
}async function run(){await getTotalPrice('001', '002');  
}

getPrice()是一個異步獲取數(shù)據(jù)的方法, 可以用async+await的方式獲取數(shù)據(jù), 但是會導(dǎo)致調(diào)用getTotalPrice的run方法也會變成異步函數(shù), 這就是async的傳染性(副作用)。

function usePrice(id) {useEffect((id)=>{fetch(`xxx.com?id=${productId}`).then((res)=>{return res.price})}, [])
}function TotalPirce({id1, id2}) {const p1 = usePrice(id1);const p2 = usePrice(id2);return <TotalPirce props={...}>
}

getPrice換成usePrice, getTotalPirce換成TotalPirce組件, 這是hook的分離副作用能力。

generator: 也是有一定的傳染性的, generator不能計算優(yōu)先級, 排序優(yōu)先級。

function getPrice(id) {return fetch(`xxx.com?id=${productId}`).then((res)=>{return res.price})
}function* getTotalPirce(id1, id2) {const p1 = yield getPrice(id1);const p2 = yield getPrice(id2);return p1 + p2;
}function* run(){yield getTotalPrice('001', '002');  
}

解耦副作用在函數(shù)式編程的實(shí)踐中非常常見, 如react-saga, 將副作用從saga中分離, 自己不處理副作用, 發(fā)請求處理。

function* fetchUser(action) {try {const user = yield call(Api.fetchUser, action.payload.userId);yield put({type: "USER_FETCH_SUCCEEDED", user: user});} catch (e) {yield put({type: "USER_FETCH_FAILED", message: e.message});}
}

2.React的源碼架構(gòu)

  1. Scheduler(調(diào)度器): 排序優(yōu)先級,讓優(yōu)先級高的任務(wù)先進(jìn)行reconcile
  2. Reconciler(協(xié)調(diào)器): 找出哪些節(jié)點(diǎn)發(fā)生了改變,并打上不同的Flags(舊版本react叫Tag)
  3. Renderer(渲染器): 將Reconciler中打好標(biāo)簽的節(jié)點(diǎn)渲染到視圖上

在這里插入圖片描述

2.1 大概圖示

在這里插入圖片描述

jsx(mount/update) -> scheduler(render) -> reconciler(render) -> rerender(commit)

2.2 jsx

jsx: React通過Babel解析, 將jsx轉(zhuǎn)換成React.createElement, React.createElement方法返回virtual-dom對象React.createElement方法返回virtual-dom對象, 所有jsx本質(zhì)上就是React.createElement的語法糖。

createElement -> ReactElement

export function createElement(type, config, children) {let propName;// Reserved names are extractedconst props = {};let key = null;let ref = null;let self = null;let source = null;if (config != null) {if (hasValidRef(config)) {ref = config.ref;if (__DEV__) {warnIfStringRefCannotBeAutoConverted(config);}}if (hasValidKey(config)) {key = '' + config.key;}self = config.__self === undefined ? null : config.__self;source = config.__source === undefined ? null : config.__source;// Remaining properties are added to a new props objectfor (propName in config) {if (hasOwnProperty.call(config, propName) &&!RESERVED_PROPS.hasOwnProperty(propName)) {props[propName] = config[propName];}}}// Children can be more than one argument, and those are transferred onto// the newly allocated props object.const childrenLength = arguments.length - 2;if (childrenLength === 1) {props.children = children;} else if (childrenLength > 1) {const childArray = Array(childrenLength);for (let i = 0; i < childrenLength; i++) {childArray[i] = arguments[i + 2];}if (__DEV__) {if (Object.freeze) {Object.freeze(childArray);}}props.children = childArray;}// Resolve default propsif (type && type.defaultProps) {const defaultProps = type.defaultProps;for (propName in defaultProps) {if (props[propName] === undefined) {props[propName] = defaultProps[propName];}}}if (__DEV__) {if (key || ref) {const displayName =typeof type === 'function'? type.displayName || type.name || 'Unknown': type;if (key) {defineKeyPropWarningGetter(props, displayName);}if (ref) {defineRefPropWarningGetter(props, displayName);}}}return ReactElement(type,key,ref,self,source,ReactCurrentOwner.current,props,);
}const ReactElement = function(type, key, ref, self, source, owner, props) {const element = {// This tag allows us to uniquely identify this as a React Element$$typeof: REACT_ELEMENT_TYPE,// Built-in properties that belong on the elementtype: type,key: key,ref: ref,props: props,// Record the component responsible for creating this element._owner: owner,};if (__DEV__) {// The validation flag is currently mutative. We put it on// an external backing store so that we can freeze the whole object.// This can be replaced with a WeakMap once they are implemented in// commonly used development environments.element._store = {};// To make comparing ReactElements easier for testing purposes, we make// the validation flag non-enumerable (where possible, which should// include every environment we run tests in), so the test framework// ignores it.Object.defineProperty(element._store, 'validated', {configurable: false,enumerable: false,writable: true,value: false,});// self and source are DEV only properties.Object.defineProperty(element, '_self', {configurable: false,enumerable: false,writable: false,value: self,});// Two elements created in two different places should be considered// equal for testing purposes and therefore we hide it from enumeration.Object.defineProperty(element, '_source', {configurable: false,enumerable: false,writable: false,value: source,});if (Object.freeze) {Object.freeze(element.props);Object.freeze(element);}}return element;
};
2.3 Fiber雙緩存

Fiber對象上面保存了包括這個節(jié)點(diǎn)的屬性, dom, 類型, 通過child, sibling, reture 形成fiber樹, 保存了更新狀態(tài)時用于計算state的updateQueue, updateQueue為一個鏈表, 上面存在未計算的update, update也是一個數(shù)據(jù)結(jié)構(gòu), 上面存有更新的數(shù)據(jù)、優(yōu)先級等, 還有副作用的信息。

雙緩存是指存在兩顆Fiber樹, current Fiber樹描述了當(dāng)前呈現(xiàn)的dom樹, workInProgress Fiber是正在更新的Fiber樹, 這兩樹都是存在于內(nèi)存, 在workInProgress Fiber構(gòu)建完成之后會將它作為current Fiber應(yīng)用到dom上。

function App() {const [count, setCount] = useState(0);return (<><h1 onClick={() => {setCount(() => count + 1);}}><p title={count}>{count}</p> </h1></>)
}ReactDOM.render(<App />, document.getElementById("root"));

在這里插入圖片描述

2.4 scheduler

Scheduler的作用是調(diào)度任務(wù)。

在Scheduler中的每個任務(wù)的優(yōu)先級使用過期時間表示的, 如果一個任務(wù)的過期時間離現(xiàn)在很近, 說明要過期了, 優(yōu)先級很高。
沒有過期的放在timerQueue中, 過期的放taskQueue, timerQueue和taskQueue都是小頂堆, 所以peek出的都是離現(xiàn)在時間最近也就是優(yōu)先級最高的那個任務(wù)。

在這里插入圖片描述

2.5 Lane模型

優(yōu)先級表示方法Lane: Lane使用二進(jìn)制的方式表示優(yōu)先級, 1表示位置, 同一個二進(jìn)制數(shù)可以有多個相同優(yōu)先級的位, 這就可以表示‘批’的概念。低優(yōu)先級的任務(wù)如果被高優(yōu)先級的任務(wù)一直打斷, 等到達(dá)它的時候, 優(yōu)先級自動變?yōu)樽罡摺?/p>

bit越多, 優(yōu)先級越低。

//ReactFiberLane.js
export const NoLanes: Lanes = /*                        */ 0b0000000000000000000000000000000;
export const NoLane: Lane = /*                          */ 0b0000000000000000000000000000000;export const SyncLane: Lane = /*                        */ 0b0000000000000000000000000000001;
export const SyncBatchedLane: Lane = /*                 */ 0b0000000000000000000000000000010;export const InputDiscreteHydrationLane: Lane = /*      */ 0b0000000000000000000000000000100;
const InputDiscreteLanes: Lanes = /*                    */ 0b0000000000000000000000000011000;const InputContinuousHydrationLane: Lane = /*           */ 0b0000000000000000000000000100000;
const InputContinuousLanes: Lanes = /*                  */ 0b0000000000000000000000011000000;export const DefaultHydrationLane: Lane = /*            */ 0b0000000000000000000000100000000;
export const DefaultLanes: Lanes = /*                   */ 0b0000000000000000000111000000000;const TransitionHydrationLane: Lane = /*                */ 0b0000000000000000001000000000000;
const TransitionLanes: Lanes = /*                       */ 0b0000000001111111110000000000000;const RetryLanes: Lanes = /*                            */ 0b0000011110000000000000000000000;export const SomeRetryLane: Lanes = /*                  */ 0b0000010000000000000000000000000;export const SelectiveHydrationLane: Lane = /*          */ 0b0000100000000000000000000000000;const NonIdleLanes = /*                                 */ 0b0000111111111111111111111111111;export const IdleHydrationLane: Lane = /*               */ 0b0001000000000000000000000000000;
const IdleLanes: Lanes = /*                             */ 0b0110000000000000000000000000000;export const OffscreenLane: Lane = /*                   */ 0b1000000000000000000000000000000;
2.6 reconciler

Reconciler發(fā)生在render階段, render分為節(jié)點(diǎn)執(zhí)行beginWork和completeWork, 或是計算state, 對比節(jié)點(diǎn)的差異, 為節(jié)點(diǎn)賦值相應(yīng)的effectFlags。

Reconciler會創(chuàng)建或者更新Fiber節(jié)點(diǎn)。在mount的時候會根據(jù)jsx生成Fiber對象,在update的時候會根據(jù)最新的state形成的jsx對象和current Fiber樹對比構(gòu)建workInProgress Fiber樹, 對比就是diff算法。

diff算法發(fā)生在render階段的reconcileChildFibers函數(shù)中, diff算法分為單節(jié)點(diǎn)的diff和多節(jié)點(diǎn)的diff, 單節(jié)點(diǎn)會根據(jù)節(jié)點(diǎn)的key和type, props判斷節(jié)點(diǎn)是復(fù)用還是直接新創(chuàng)建節(jié)點(diǎn), 多節(jié)點(diǎn)diff會涉及節(jié)點(diǎn)的增刪和節(jié)點(diǎn)位置的變化。

reconcile時會在這些Fiber上打上Flags標(biāo)簽, 在commit階段把這些標(biāo)簽應(yīng)用到真實(shí)dom上, 這些標(biāo)簽代表了節(jié)點(diǎn)的增刪改。

//ReactFiberFlags.js
export const Placement = /*             */ 0b0000000000010;
export const Update = /*                */ 0b0000000000100;
export const PlacementAndUpdate = /*    */ 0b0000000000110;
export const Deletion = /*              */ 0b0000000001000;

render階段遍歷Fiber樹類似dfs的過程, ‘捕獲’階段發(fā)生在beginWork函數(shù)中, 該函數(shù)做的主要工作是創(chuàng)建Fiber節(jié)點(diǎn), 計算state和diff算法, ‘冒泡’階段發(fā)生在completeWork中, 該函數(shù)主要是做一些收尾工作, 例如處理節(jié)點(diǎn)的props、和形成一條effectList的鏈表, 該鏈表是被標(biāo)記了更新的節(jié)點(diǎn)形成的鏈表。

function App() {return (<><h1><p>count</p> xiaochen</h1></>)
}

在這里插入圖片描述

function App() {const [count, setCount] = useState(0);return (<><h1onClick={() => {setCount(() => count + 1);}}><p title={count}>{count}</p> xiaochen</h1></>)
}

如果p和h1節(jié)點(diǎn)更新了則effectList如下, rootFiber->h1->p, fiberRoot是整個項目的根節(jié)點(diǎn), rootFiber為應(yīng)用的根節(jié)點(diǎn), 可以有多個。

在這里插入圖片描述

2.7 renderer

Renderer發(fā)生在commit階段, commit階段遍歷effectList執(zhí)行對應(yīng)的dom操作或部分生命周期。并執(zhí)行真實(shí)dom節(jié)點(diǎn)的操作和一些生命周期, 不同的平臺對應(yīng)的Renderer不同, 瀏覽器對應(yīng)的是react-dom。

commit階段發(fā)生在commitRoot函數(shù)中, 遍歷effectList, 三個函數(shù)來處理effectList上的節(jié)點(diǎn), commitBeforeMutationEffects, commitMutationEffects, commitLayoutEffects。

在這里插入圖片描述

2.8 concurrent

一類功能的合集(如fiber、schduler、lane、suspense), 目的是為了提高應(yīng)用的響應(yīng)速度, 使應(yīng)用cpu密集型的更新不在那么卡頓, 核心是實(shí)現(xiàn)了一套異步可中斷、帶優(yōu)先級的更新。

3.React源碼調(diào)試

在這里插入圖片描述

  • fixtures:為代碼貢獻(xiàn)者提供的測試React
  • packages:主要部分,包含Scheduler,reconciler等
  • scripts:react構(gòu)建相關(guān)

在這里插入圖片描述

  1. react:核心Api如:React.createElement、React.Component都在這

  2. 和平臺相關(guān)render相關(guān)的文件夾:
    react-art:如canvas svg的渲染
    react-dom:瀏覽器環(huán)境
    react-native-renderer:原生相關(guān) react-noop-renderer:調(diào)試或者fiber用

  3. 試驗(yàn)性的包
    react-server: ssr相關(guān)
    react-fetch: 請求相關(guān)
    react-interactions: 和事件如點(diǎn)擊事件相關(guān)
    react-reconciler: 構(gòu)建節(jié)點(diǎn)
    shared:包含公共方法和變量

  4. 輔助包:
    react-is : 判斷類型
    react-client: 流相關(guān)
    react-fetch: 數(shù)據(jù)請求相關(guān)

  5. react-refresh: 熱加載相關(guān)

  6. scheduler:調(diào)度器相關(guān)

  7. React-reconciler:在render階段用它來構(gòu)建fiber節(jié)點(diǎn)

http://www.risenshineclean.com/news/23012.html

相關(guān)文章:

  • 建設(shè)招標(biāo)網(wǎng)網(wǎng)站網(wǎng)站關(guān)鍵詞優(yōu)化網(wǎng)站推廣
  • 自己做網(wǎng)站 搜索功能開發(fā)杭州網(wǎng)站seo優(yōu)化
  • 滄州手機(jī)建站哪家好濟(jì)南seo外包服務(wù)
  • dw做網(wǎng)站怎么設(shè)置頁面音樂網(wǎng)站大全軟件下載
  • 公司主頁怎么填寫seo軟件哪個好
  • 出國勞務(wù)信息網(wǎng)seo優(yōu)化網(wǎng)站源碼
  • 做公司網(wǎng)站需要服務(wù)器嗎上海關(guān)鍵詞排名提升
  • 一學(xué)一做短視頻網(wǎng)站杭州市優(yōu)化服務(wù)
  • 重慶網(wǎng)站空間鍵詞排名搜索引擎優(yōu)化的定義
  • 廣州各區(qū)優(yōu)化疫情防控措施seo引擎優(yōu)化公司
  • 做任務(wù)的獎金網(wǎng)站國際實(shí)時新聞
  • 國務(wù)院建設(shè)部網(wǎng)站seo數(shù)據(jù)是什么意思
  • 什么是網(wǎng)站名稱文件夾寵物美容師寵物美容培訓(xùn)學(xué)校
  • 上海專業(yè)網(wǎng)站建設(shè)機(jī)構(gòu)線上營銷平臺有哪些
  • 哪家公司建設(shè)網(wǎng)站嘉興關(guān)鍵詞優(yōu)化報價
  • 網(wǎng)站建設(shè)鼠標(biāo)移動變顏色百度seo
  • 做網(wǎng)站框架搭建的人優(yōu)化方法
  • 沒有服務(wù)器怎么做網(wǎng)站seo排名賺能賺錢嗎
  • wamp做的網(wǎng)站外網(wǎng)怎么訪問長春seo顧問
  • 鄭州做旅游網(wǎng)站品牌廣告文案
  • 濟(jì)南做網(wǎng)站哪家好企業(yè)網(wǎng)站注冊域名的步驟
  • 織夢dede門戶資訊新聞網(wǎng)站源碼濟(jì)南做網(wǎng)站公司
  • 網(wǎng)站建設(shè)能在家工作室廣州seo服務(wù)
  • 有沒有專門做衣服的網(wǎng)站360推廣開戶
  • 網(wǎng)站策劃與運(yùn)營課程認(rèn)知如何建網(wǎng)站詳細(xì)步驟
  • 廣告設(shè)計樣板圖網(wǎng)站優(yōu)化外包推薦
  • 0基礎(chǔ)做網(wǎng)站工具網(wǎng)站建設(shè)的意義和目的
  • wordpress做seo好做seo搜索引擎優(yōu)化步驟
  • wordpress 刪除站點(diǎn)關(guān)鍵詞優(yōu)化師
  • 移動網(wǎng)站 做優(yōu)化深圳百度競價托管公司