مرحبا يا هابر! في تلك السنوات غير البعيدة ، في السنة الأولى من كلية "المبرمج" ، أحببت أن أسأل زملائي الطلاب السؤال: "لماذا ذهبت هنا للدراسة؟" بالطبع ، لم أحتفظ بإحصاءات دقيقة للإجابات ، لكنني أتذكر على وجه اليقين: أكثر من النصف أرادوا صنع الألعاب. معظم أولئك الذين أجابوا بهذه الطريقة لم يكونوا مستعدين لوفرة أنواع مختلفة من "علماء الرياضيات" و "الفيزيائيين" الذين غمرنا معهم في أول عامين من دراستنا. لم ينج جميع - بحلول نهاية السنة الثانية من المجموعات الخمس المكتظة كان هناك ثلاثة غير مكتملة.
منذ وقت ليس ببعيد ، أتيحت الفرصة لفريقنا الأمامي لتجربة أنفسهم في دور غامديف. باختصار شديد ، المهمة هي: إنشاء لعبة ثلاثية الأبعاد حقيقية ، بحيث يمكنك اللعب فقط عن طريق فتح المتصفح. حتى المحمول. حتى في عرض الويب.

, , , — React + Redux, « », , , .
RnD , : « CodeFest — . — ». , , , . Gods in the sky.

CodeFest .
MMO TPS , , . , , , . CodeFest. , .
2 , , 2 . , , .
: -, — , . , N , — 1 . , — 15 . , , 16-. , , :
- 30 . CodeFest, — , «». , .
 - «» . , :
- 90 CPU;
 - 120 ;
 - 270 /c — , 675 /c — .
 
 - 4,2 /c. , . — UDP WebRTC, . .
 - . 2 , , , . , - Node.js , .
 
, , ( ?), , , , . .
, . , «». — .
:
, , , . , , 5 , , 40 .
-. , , — . React Redux. c 3D-, , Gods in the sky, three.js.
, .
:

, Node.js. :
- , - ( , IE11);
 - access-;
 - html- .
 
SSR . kubernetes , . , . , , , , ( ). . Nginx.
. TS, AppState, :
interface AppState {
    gameState: GameState;
    gameObjects: GameObjects;
    data: Data;
    requests: RequestsState;
}
requests — , — . , — . .
data — , , , , «». .
GameState :
stage: 'factoids' | 'citySelect' | 'flyShow' | 'game' | 'results'; — . :
elapsedTime: number; — , , .
, factoids flyShow, , — elapsedTime. 0, . , . , , , . , . … - , .
, , :
interface GameObjects {
    user: UserInGame;
    gifts: { [id: string]: GiftInGame; };
    boosts: { [id: string]: Boost; };
    bombs: { [id: string]: Bomb; };
}
, : , , . — .
GameObjects — . , FPS . GPU 100 . Redmi Note 7 40 FPS ( ). MI 5S 30 FPS, 20 , .
, . .
- Redux, — . Redux , . ? Redux, .
, . , . «» ( . behavior — ). , .
. — tick, . , . tick . :
- , , , . , , , .
 - ( Redux-), .
, «» . - , gameObjects, . , «», .
 
25 ( ).
. ( ), React, . - , «- » ( , , ).

. pixabay.com
, FPS- 13. , , - MI 5S, FPS- — 5-6, . .
: performance — , . , , .
FPS=30 , :
- Redux 
FPS * ~[ ] ~= 750 , , . - React’ 
FPS * ~2 * ~[ ] . - three.js , , WebGL . , .
 - (.. 150 ) 4-6 , .. .
 - CSS- .
 - , FPS 2-4 ( , «» ).
 - React.memo, - , .
 
React :
* ~2 , connect. connect — - HOC, , .- , React – (render pass), CPU, GPU.
 
: React.memo , , «», , DOM-, .
, React + Redux, .
Redux
Redux — . ~1 , . ~1, - — . -, , GameObjects , :
export function setNextGameObjects(payload: GameObjects) {
    return {
        type: 'SET_NEXT_GAME_OBJECTS' as const,
        payload,
    };
}
GameObjects :
- , . 
SET_NEXT_GAME_OBJECTS. - , , GameObjects. Redux , - . 
SET_NEXT_GAME_OBJECTS. 
:
let state = store.getState().gameObjects;
for (const action of this.collectedActions) {
    state = gameObjectsFakeStateReducer(state, action);
}
store.dispatch(setNextGameObjects(state));
collectedActions — , . — , .
— ~25 10 : ~2 . , gameObjectsFakeStateReducer . 25 . , .
? , perf-. 3 :
- ES2018, ~50 < ES2018 (, Firefox — ). , spread.
 - Object.assign 300 .
 - 500 , « » .
 
, , , — ES2018, . Firefox.
№3 , … . .
Object.assign. gameObjectsFakeStateReducer gameObjectsFastStateReducer, - :
switch (action.type) {
    case 'PARTIAL_GIFT_STATE_PATCH':
        if (!state.gifts[action.payload.id]) {
            return state;
        }
        Object.assign(state.gifts[action.payload.id], action.payload);
        break;
    
}
? , . , . 25 1 2-4 ( CPU). :

«» , , Redux 10 . , - , , connect gameObjects. , .
React
React . — DOM. , , — reselect, React.memo/React.PureComponent, shouldComponentUpdate . .
, , ~2, — 5. , React , .. DOM .
batch React + Redux. , — . , ?
, , connect . , .
. , <ScoreBoard />,
- ;
 - , .

 
React.PureComponent, connect mapStateToProps. elapsedTime score. Score , elapsedTime — . elapsedTime - render. , FPS, shouldComponentUpdate. HOC’a connect — shouldComponentUpdate .
, «» , :
- shouldComponentUpdate, 
elapsedTime ( ). , HOC’a connect. - mapStateToProps . , , . connect’a.
 - useSelector. , .. . , , , .
 - — connect, — . , . ScoreBoard .
 
— ! ScoreBoard’a connect, , . mapStateToProps , .
, connect. , — - - canvas-, three.js (, , .). render , :
return <div id="map" className={s.map} ref={mapRef} />;
return <canvas id="scene" className={s.scene} ref={sceneRef} />;
, DOM — . , React . , componentDidUpdate, . , componentDidUpdate :
public componentDidUpdate() {
    const { geoPos, orientedRotationQuanternion } = this.props;
    const { map } = this.state;
    map.setQuat(orientedRotationQuanternion);
    map.setCenter([geoPos[0], geoPos[1]], { animate: false });
    map.setZoom(getMapZoomFromHeight(geoPos[2]), { animate: false });
}
, componentDidUpdate . :
- connect. , mapStateToProps;
 public shouldComponentUpdate() { return false; } — «» «»;- Redux ( ) useStore ;
 - (
store.subscribe(() => { /* … */})); - ;
 - !
 
:
store.subscribe(() => {
    const state = store.getState();
    const { map } = this.state;
    const { geoPos, orientedRotationQuanternion } = state.gameObjects.user;
    map.setQuat(orientedRotationQuanternion);
    map.setCenter([geoPos[0], geoPos[1]], { animate: false });
    map.setZoom(getMapZoomFromHeight(geoPos[2]), { animate: false });
}); 
, , .
, - , .

. — React Tree Reconcilation + Commit

React Tree Reconcilation + Commit
React + Redux , :
- , , , «» React , ;
 - ;
 - « », , ;
 - , .
 
, . , . , . ? .
:
- , , , , . , .
 - , React’ 30 . : .
 - , .
 - . . , .
 - .
 - Performance — . CPU — , Intel i9.
 - - : 12–20 – . , .
 - , . , , . , .
 - , , . IE11 , . 70- Edge 18- ( ).
 - WebGL . - , , -, Firefox linux, . . — . -, . , , « », .
 
, :
- Firefox. . , WebGL, — spread. FPS Firefox , Chrome. , , .
 - IPhone. Safari IE6 220 . , , . , , . . — - .
 - . . . , , (, , ). .
 - . , , . , , , «» .
 - ( ), – , . .
 
, , . iOS, Android Web .