国产av一二三区|日本不卡动作网站|黄色天天久久影片|99草成人免费在线视频|AV三级片成人电影在线|成年人aV不卡免费播放|日韩无码成人一级片视频|人人看人人玩开心色AV|人妻系列在线观看|亚洲av无码一区二区三区在线播放

網(wǎng)易首頁(yè) > 網(wǎng)易號(hào) > 正文 申請(qǐng)入駐

React程序員做小游戲,60幀下setState直接崩了

0
分享至


一個(gè)前端工程師用React寫游戲,幀率掉到個(gè)位數(shù)時(shí),他意識(shí)到問(wèn)題不在代碼,而在框架的「肌肉記憶」。

這是@nyaomaru的真實(shí)經(jīng)歷。他拿到了NVIDIA送的《生化危機(jī)9》,到現(xiàn)在還沒見到第一只僵尸——但他在瀏覽器里做的小游戲《Run Away From Work》,卻讓他對(duì)React有了完全不同的理解。

游戲看起來(lái)很簡(jiǎn)單:一個(gè)打工魚逃跑,老板追,路上撿魚幣躲障礙。但當(dāng)他試圖用setState驅(qū)動(dòng)每一幀動(dòng)畫時(shí),瀏覽器風(fēng)扇開始狂轉(zhuǎn)。

setState → 重渲染 → diff → DOM更新,這套流程在60fps下就是性能自殺。

他沒有換框架,而是換了一套架構(gòu)思路。React還在,但游戲循環(huán)(Game Loop)被徹底剝離出去。

React的渲染模型,和游戲循環(huán)是兩種生物

React的核心假設(shè)是:狀態(tài)變了,UI重新計(jì)算。這對(duì)表單、列表、儀表盤是完美的。

但游戲不一樣。游戲需要每16.6毫秒更新一次畫面,而且更新的往往不是整棵樹,是幾十個(gè)實(shí)體的坐標(biāo)。用React的diff算法處理這個(gè),就像用Excel公式做實(shí)時(shí)渲染——能跑,但何必。

@nyaomaru的解法很直接:React只負(fù)責(zé)靜態(tài)結(jié)構(gòu),動(dòng)態(tài)實(shí)體直接操作DOM。

看這段代碼。游戲區(qū)域由React渲染,但玩家、老板、障礙物這些「活物」,全是原生DOM節(jié)點(diǎn)。

他用document.createElement生成障礙物,用appendChild塞進(jìn)游戲區(qū)域,用requestAnimationFrame驅(qū)動(dòng)位置更新。React完全不知道這些節(jié)點(diǎn)存在。

這聽起來(lái)像「反模式」,但性能數(shù)據(jù)不會(huì)騙人。瀏覽器主線程從「喘不過(guò)氣」變成「游刃有余」,幀率穩(wěn)在60fps。

三層架構(gòu):React當(dāng)骨架,原生DOM當(dāng)肌肉

具體實(shí)現(xiàn)分三層。最外層是React的領(lǐng)地:游戲容器、UI覆蓋層、分?jǐn)?shù)顯示。這些很少變動(dòng),React處理得干凈利落。

中間層是實(shí)體管理層。@nyaomaru用useRef保存所有動(dòng)態(tài)元素的引用,但絕不把它們?nèi)M(jìn)state。障礙物數(shù)組存在ref里,React渲染周期永遠(yuǎn)看不到它們。

最內(nèi)層是動(dòng)畫循環(huán)。requestAnimationFrame每幀直接修改DOM節(jié)點(diǎn)的style.transform,跳過(guò)React的調(diào)和(Reconciliation)全過(guò)程。

這種「混合模式」的關(guān)鍵是隔離。React管它的,原生DOM管它的,兩者通過(guò)ref建立單向聯(lián)系。React知道游戲區(qū)域在哪里,但不知道里面有多少個(gè)障礙物在飛。

一個(gè)細(xì)節(jié):玩家和老板的精靈圖也是SVG,但位置更新不走React。sprite的transform屬性被直接賦值,瀏覽器合成層(Compositor)接手后續(xù)工作,主線程零負(fù)擔(dān)。

為什么不用Canvas?

讀到這你可能會(huì)問(wèn):都操作原生DOM了,為什么不直接用Canvas 2D或WebGL?

@nyaomaru考慮過(guò),但拒絕了。他的理由是工具鏈和審美:所有視覺素材都是Adobe Illustrator手繪的SVG,保留DOM結(jié)構(gòu)意味著可以用CSS做響應(yīng)式、用瀏覽器開發(fā)者工具直接調(diào)試、用現(xiàn)成的無(wú)障礙支持。

更重要的是,這個(gè)游戲的復(fù)雜度還沒到Canvas的甜點(diǎn)區(qū)。幾十個(gè)移動(dòng)元素,DOM+CSS transform完全吃得消。Canvas的優(yōu)勢(shì)在成千上萬(wàn)個(gè)粒子,這里用不上。

這選擇里有產(chǎn)品經(jīng)理的權(quán)衡思維。技術(shù)選型不是選「最強(qiáng)」的,是選「剛剛好」的。為了10%的性能提升,犧牲50%的開發(fā)體驗(yàn)和可維護(hù)性,這筆賬不劃算。

從游戲循環(huán)看框架邊界

這個(gè)案例的真正價(jià)值,是展示了如何在一個(gè)React應(yīng)用里「開天窗」。

框架的渲染模型是契約。React的契約是「聲明式UI,我?guī)湍阃綘顟B(tài)和視圖」。但游戲循環(huán)的契約是「每幀直接寫屏,延遲必須低于16ms」。兩份契約沖突時(shí),強(qiáng)行套用一方就是災(zāi)難。

@nyaomaru的做法是承認(rèn)邊界:React負(fù)責(zé)「結(jié)構(gòu)穩(wěn)定但數(shù)據(jù)多變」的部分,原生DOM負(fù)責(zé)「結(jié)構(gòu)多變但數(shù)據(jù)簡(jiǎn)單」的部分。這不是對(duì)React的否定,是對(duì)其適用域的清醒認(rèn)知。

他甚至在GitHub上開源了完整代碼。評(píng)論區(qū)最熱的反饋是:「原來(lái)useRef還能這么用」——很多人把ref當(dāng)成「避免重渲染的逃生艙」,卻忘了它本身就是通往DOM的合法通道。

另一個(gè)有趣的點(diǎn)是狀態(tài)管理。分?jǐn)?shù)、游戲階段這些「業(yè)務(wù)狀態(tài)」仍在React里,用useState完全沒問(wèn)題。但實(shí)體的位置、速度、碰撞箱這些「物理狀態(tài)」,被隔離在React之外,用純JavaScript對(duì)象管理。

這種分層讓調(diào)試變得直觀。游戲邏輯bug看控制臺(tái),UI bug看React DevTools,互不干擾。

性能數(shù)字背后的真相

沒有公開的benchmark,但@nyaomaru描述了一個(gè)典型場(chǎng)景:30個(gè)障礙物同時(shí)移動(dòng),純React方案幀率掉到15fps,混合方案穩(wěn)60fps。

差距來(lái)自哪里?React的調(diào)和算法在每次setState時(shí)要遍歷組件樹,計(jì)算最小更新。30個(gè)障礙物意味著30次狀態(tài)變更,或者1次批量變更但涉及30個(gè)組件。無(wú)論哪種,開銷都遠(yuǎn)高于直接修改30個(gè)DOM節(jié)點(diǎn)的transform。

更隱蔽的成本是垃圾回收。頻繁創(chuàng)建和銷毀React元素會(huì)產(chǎn)生大量臨時(shí)對(duì)象,觸發(fā)GC時(shí)幀率波動(dòng)。原生DOM方案的對(duì)象生命周期簡(jiǎn)單得多。

這些細(xì)節(jié)在普通應(yīng)用里無(wú)關(guān)緊要,但在幀時(shí)間預(yù)算只有16ms的游戲里,每一毫秒都是戰(zhàn)場(chǎng)。

給前端工程師的啟示

這個(gè)案例最實(shí)用的 takeaway 是:學(xué)會(huì)在React應(yīng)用里「作弊」。

useRef、createPortal、甚至直接操作DOM,這些「逃生艙」不是bug,是框架設(shè)計(jì)者預(yù)留的應(yīng)急通道。當(dāng)你確定某個(gè)場(chǎng)景不在React的甜點(diǎn)區(qū)時(shí),果斷繞路比強(qiáng)行優(yōu)化更聰明。

另一個(gè)啟示是關(guān)于技術(shù)寫作的。@nyaomaru的文章結(jié)構(gòu)很典型:先展示問(wèn)題(幀率崩潰),再展示解法(架構(gòu)分層),最后給可運(yùn)行的代碼。沒有抽象的理論,全是具體的決策點(diǎn)和權(quán)衡。

這種寫法對(duì)25-40歲的技術(shù)讀者特別有效——他們經(jīng)歷過(guò)足夠多的項(xiàng)目,知道「最佳實(shí)踐」往往在邊界處失效,想看到的是別人怎么在真實(shí)約束下做取舍。

最后提一個(gè)產(chǎn)品細(xì)節(jié)。游戲里的「老板」角色有一個(gè)手臂動(dòng)畫,用CSS關(guān)鍵幀實(shí)現(xiàn)。這個(gè)動(dòng)畫完全獨(dú)立于游戲循環(huán),由瀏覽器合成層處理,不占用主線程。

@nyaomaru在文章結(jié)尾說(shuō),他還沒通關(guān)《生化危機(jī)9》,因?yàn)椤缚吹降谝粋€(gè)僵尸就關(guān)了游戲」。但他的小游戲已經(jīng)讓幾百人摸魚時(shí)多了一種選擇——如果React的渲染模型沒有把他逼到墻角,這個(gè)解法可能永遠(yuǎn)不會(huì)被寫出來(lái)。

你現(xiàn)在手上有多少個(gè)「本該用React做」的場(chǎng)景,其實(shí)更適合直接操作DOM?

特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相關(guān)推薦
熱點(diǎn)推薦
網(wǎng)友吐槽:國(guó)產(chǎn)手機(jī)銷量暴跌,都在罵蘋果,沒想到蘋果依然堅(jiān)挺!

網(wǎng)友吐槽:國(guó)產(chǎn)手機(jī)銷量暴跌,都在罵蘋果,沒想到蘋果依然堅(jiān)挺!

眼光很亮
2026-03-23 16:29:14
44歲于明加身材刷屏,前凸后翹,結(jié)婚16年沒下過(guò)廚,她憑什么?

44歲于明加身材刷屏,前凸后翹,結(jié)婚16年沒下過(guò)廚,她憑什么?

一盅情懷
2026-03-25 17:51:03
什么事情讓你相信萬(wàn)物皆有靈?網(wǎng)友:這個(gè)媽媽是迪士尼公主吧

什么事情讓你相信萬(wàn)物皆有靈?網(wǎng)友:這個(gè)媽媽是迪士尼公主吧

夜深愛雜談
2026-03-23 20:12:54
午后,突然拉漲停!603933,重要收購(gòu)!明起停牌

午后,突然拉漲停!603933,重要收購(gòu)!明起停牌

中國(guó)基金報(bào)
2026-03-25 20:43:13
61歲大爺每天吃西洋參,堅(jiān)持1年沒間斷,體檢結(jié)果連醫(yī)生都羨慕

61歲大爺每天吃西洋參,堅(jiān)持1年沒間斷,體檢結(jié)果連醫(yī)生都羨慕

吃青菜長(zhǎng)高
2026-02-14 08:26:54
手握10個(gè)CBA總冠軍,娶游泳女神為妻,如今已是廣東籃球領(lǐng)頭人

手握10個(gè)CBA總冠軍,娶游泳女神為妻,如今已是廣東籃球領(lǐng)頭人

一娛三分地
2026-03-20 17:11:09
強(qiáng)行換主演的10部劇,賠了夫人又折兵,哪幾部讓你至今都意難平?

強(qiáng)行換主演的10部劇,賠了夫人又折兵,哪幾部讓你至今都意難平?

小Q侃電影
2026-03-25 19:27:04
詹姆斯:我落選?我絕對(duì)會(huì)記住他們每一個(gè)人,每次交手都撕碎他們

詹姆斯:我落選?我絕對(duì)會(huì)記住他們每一個(gè)人,每次交手都撕碎他們

桃葉渡春
2026-03-26 00:49:19
美軍地面部隊(duì)27日抵達(dá)中東 伊朗革命衛(wèi)隊(duì)亮劍!

美軍地面部隊(duì)27日抵達(dá)中東 伊朗革命衛(wèi)隊(duì)亮劍!

看看新聞Knews
2026-03-25 20:09:31
理想汽車發(fā)布全新自研增程器 明確適配L系列SUV車型

理想汽車發(fā)布全新自研增程器 明確適配L系列SUV車型

牛馬科技
2026-03-25 17:58:04
英媒:阿森納在研究簽KK7的可能性,球員有意但大巴黎不放人

英媒:阿森納在研究簽KK7的可能性,球員有意但大巴黎不放人

懂球帝
2026-03-26 01:28:07
TVB開拍今年首部新劇,金牌監(jiān)制回歸,男女主角三搭引爆期待

TVB開拍今年首部新劇,金牌監(jiān)制回歸,男女主角三搭引爆期待

TVB劇評(píng)社
2026-03-25 21:01:24
女生長(zhǎng)的太漂亮是什么體驗(yàn)?網(wǎng)友:母以子貴,父以女榮

女生長(zhǎng)的太漂亮是什么體驗(yàn)?網(wǎng)友:母以子貴,父以女榮

另子維愛讀史
2026-03-10 22:56:08
善惡到頭終有報(bào),如今73歲的唐國(guó)強(qiáng),已經(jīng)走上了一條不歸路!

善惡到頭終有報(bào),如今73歲的唐國(guó)強(qiáng),已經(jīng)走上了一條不歸路!

吳蒂旅行ing
2026-03-20 05:20:46
生育大局已定:不出意外的話,2026年起中國(guó)人口將迎來(lái)3大變化

生育大局已定:不出意外的話,2026年起中國(guó)人口將迎來(lái)3大變化

丞丞故事匯
2026-03-13 13:54:48
賴昌星前妻近狀曝光:拒絕政府安置,獨(dú)居3000平老宅,只做一件事

賴昌星前妻近狀曝光:拒絕政府安置,獨(dú)居3000平老宅,只做一件事

芳芳?xì)v史燴
2026-03-23 03:53:23
40年后才揭開謎底對(duì)越真相:越南真正的潰敗始于許世友的3道軍令

40年后才揭開謎底對(duì)越真相:越南真正的潰敗始于許世友的3道軍令

鑒史錄
2026-03-22 10:01:56
朱時(shí)茂陳佩斯現(xiàn)狀曝光差距大,一人家財(cái)萬(wàn)貫,一人真被倪萍說(shuō)中了

朱時(shí)茂陳佩斯現(xiàn)狀曝光差距大,一人家財(cái)萬(wàn)貫,一人真被倪萍說(shuō)中了

奇怪的鯊魚們
2026-03-23 18:16:37
戰(zhàn)局失控,美方竟詭辯“以升級(jí)求降級(jí)”

戰(zhàn)局失控,美方竟詭辯“以升級(jí)求降級(jí)”

觀察者網(wǎng)
2026-03-23 09:37:13
上半年,熬過(guò)了最難的日子,否極泰來(lái)、行大運(yùn)的三個(gè)星座

上半年,熬過(guò)了最難的日子,否極泰來(lái)、行大運(yùn)的三個(gè)星座

小晴星座說(shuō)
2026-03-23 22:11:55
2026-03-26 03:48:49
碳基打工人
碳基打工人
坐標(biāo)北京,靠咖啡續(xù)命,靠小紅書下飯的普通人類。
97文章數(shù) 0關(guān)注度
往期回顧 全部

科技要聞

紅極一時(shí)卻草草收?qǐng)觯琒ora宣布正式關(guān)停

頭條要聞

伊朗:正在搜捕逃亡美軍

頭條要聞

伊朗:正在搜捕逃亡美軍

體育要聞

35歲替補(bǔ)門將,憑什么入選英格蘭隊(duì)?

娛樂(lè)要聞

張雪峰遺產(chǎn)分割復(fù)雜!是否立遺囑成關(guān)鍵

財(cái)經(jīng)要聞

管濤:中東局勢(shì)如何影響人民幣匯率走勢(shì)?

汽車要聞

智己LS8放大招 30萬(wàn)內(nèi)8系旗艦+全線控底盤秀實(shí)力

態(tài)度原創(chuàng)

藝術(shù)
房產(chǎn)
本地
健康
公開課

藝術(shù)要聞

張雪峰走了,他公司所在的這棟樓高177.8米,耗資超10億!

房產(chǎn)要聞

41億!259畝!建學(xué)校…三亞這個(gè)大城更,最新方案曝光!

本地新聞

來(lái)永泰同安 赴一場(chǎng)春天的約會(huì)

轉(zhuǎn)頭就暈的耳石癥,能開車上班嗎?

公開課

李玫瑾:為什么性格比能力更重要?

無(wú)障礙瀏覽 進(jìn)入關(guān)懷版