階Top2:工程化體系與性能優(yōu)化的實(shí)戰(zhàn)路線)
“前端進(jìn)階之路Top2”往深里看它并不是一個(gè)排行榜而是一條進(jìn)階路線圖。如果你已經(jīng)會(huì)寫頁面、會(huì)用一個(gè)主流框架但總覺得離“高級(jí)前端”還差一口氣那缺的往往不是新框架而是兩道必過的坎橫向的工程化能力和縱向的性能優(yōu)化能力。我在一線寫了十年前端帶過不同梯度的開發(fā)者發(fā)現(xiàn)大多數(shù)人卡在中級(jí)不動(dòng)的真正原因就落在這兩條路上。這篇文章就把Top2徹底拆透核心邏輯是什么、關(guān)鍵細(xì)節(jié)怎么做、實(shí)操鏈路怎么走以及那些常規(guī)文檔里不會(huì)寫的踩坑記錄一次性講清楚。1. 重新定義進(jìn)階為什么我把這兩條路定為Top21.1 進(jìn)階的本質(zhì)從“能干活”到“可靠交付”先潑一盆冷水想在前端這條路往上走不是多背幾個(gè)API也不是把框架文檔從頭翻到尾。API會(huì)隨著版本迭代貶值框架每隔幾年換一輪熱潮只有底層能力和工程素養(yǎng)能長(zhǎng)期握在手里。我這些年帶團(tuán)隊(duì)有個(gè)很強(qiáng)烈的感受初級(jí)工程師的衡量標(biāo)準(zhǔn)是“能不能寫出來”高級(jí)工程師的衡量標(biāo)準(zhǔn)是“能不能扛得住”。同樣是做一個(gè)后臺(tái)管理系統(tǒng)新手寫完功能就認(rèn)為交付了真正進(jìn)階的人會(huì)開始追問這個(gè)項(xiàng)目交到別人手里三個(gè)月之后還能不能改加一個(gè)新模塊會(huì)不會(huì)牽一發(fā)動(dòng)全身線上訪問量翻十倍頁面會(huì)不會(huì)卡到用戶直接關(guān)掉這就是“可靠交付”。它包含四層意思功能正確、代碼可維護(hù)、性能可接受、團(tuán)隊(duì)可持續(xù)協(xié)作。后三層恰恰分別落在工程化和性能優(yōu)化上。打個(gè)比方。初級(jí)的寫法像在自己家廚房炒菜鍋在哪、鹽在哪全憑記憶一個(gè)人怎么方便怎么來。工程化體系相當(dāng)于把廚房改造成中央廚房食材分區(qū)、調(diào)料定量、出餐有標(biāo)準(zhǔn)流程誰來都能把菜做到一個(gè)穩(wěn)定水平。性能優(yōu)化則是前廳的體驗(yàn)管理后廚再忙也要保證客人從點(diǎn)單到吃上嘴的時(shí)間在可接受范圍不能因?yàn)椴俗龅煤镁妥層脩粢恢备傻取?.2 Top2的選定邏輯為什么不是框架也不是算法你可能會(huì)問前端進(jìn)階方向那么多微前端、跨端、可視化、WebAssembly哪個(gè)聽起來不比工程化和性能優(yōu)化厲害為什么我一定把這兩個(gè)定為Top2先說框架??蚣苁枪ぞ邔拥臇|西解決的是特定場(chǎng)景下的開發(fā)效率問題。但工具會(huì)迭代今天的熱門方案三五年后可能就是歷史包袱。把整個(gè)職業(yè)周期押在一個(gè)具體工具上風(fēng)險(xiǎn)太高。工程化和性能優(yōu)化是能力層它們不綁定框架你用React也好Vue也好甚至直接寫原生JavaScript這兩項(xiàng)能力都成立。再說算法。對(duì)大多數(shù)業(yè)務(wù)前端來說日常碰到的復(fù)雜度根本到不了要手撕紅黑樹的級(jí)別。前端算法的價(jià)值更多體現(xiàn)在數(shù)據(jù)結(jié)構(gòu)理解、遞歸思想、狀態(tài)流轉(zhuǎn)這些軟技能上而不是真的讓你去實(shí)現(xiàn)一個(gè)編譯器。相比之下工程化和性能優(yōu)化是每天都在發(fā)生的問題依賴亂到安裝一次要十分鐘、首屏白屏三秒、滾動(dòng)列表掉幀。這些問題不解決別說高級(jí)連中級(jí)都懸。所以我把它們定為Top2不是因?yàn)樗鼈冏睢办拧倍且驗(yàn)樗鼈冏钅軟Q定一個(gè)前端開發(fā)者在真實(shí)業(yè)務(wù)里能不能扛事。這兩個(gè)方向會(huì)伴隨整個(gè)職業(yè)生涯越往后越值錢。2. 工程化進(jìn)階把“能寫頁面”升級(jí)成“能建體系”工程化這個(gè)詞被說爛了但真把它講透的人不多。我理解的工程化是一整套讓“多人、多模塊、長(zhǎng)周期”的代碼協(xié)作變得穩(wěn)定可控的方法和工具。它不單指某個(gè)構(gòu)建工具也不單指某條規(guī)范而是貫穿項(xiàng)目從創(chuàng)建到維護(hù)全生命周期的系統(tǒng)能力。2.1 模塊化與組件化依賴清晰比想象中更重要工程化的第一步不是上構(gòu)建工具而是建立模塊意識(shí)。我見過太多“能跑就行”的項(xiàng)目全局變量滿天飛、單個(gè)文件幾千行、組件之間互相拿內(nèi)部狀態(tài)。這種代碼寫的時(shí)候很爽改的時(shí)候只想離職。模塊化的價(jià)值有三個(gè)隔離作用域避免變量互相污染明確依賴關(guān)系讓人一眼看出誰依賴誰支持按需加載不需要把所有代碼在一開始全部下載。ES Modules如今已經(jīng)是瀏覽器原生能力配合import和export做依賴管理比早年各種全局命名空間方案靠譜了一個(gè)時(shí)代。組件化的本質(zhì)是接口設(shè)計(jì)。一個(gè)合格的組件要有清晰的輸入輸出邊界props是輸入事件是輸出內(nèi)部狀態(tài)不允許外部直接碰。很多項(xiàng)目組件拆得不好問題不在數(shù)量而在邊界。一個(gè)可復(fù)用的彈窗組件如果內(nèi)部接收了二十個(gè)props、還偷偷調(diào)用全局store改數(shù)據(jù)那它就不是組件是一顆定時(shí)炸彈。我給自己定的規(guī)矩是每次抽組件前先問三個(gè)問題這個(gè)部分是不是真的高頻復(fù)用它的輸入輸出邊界是否清晰拆出去之后父組件代碼是變簡(jiǎn)單了還是更繞了三個(gè)問題里有兩個(gè)不滿足就先別拆。強(qiáng)行拆組件只會(huì)讓代碼結(jié)構(gòu)變得更碎并不會(huì)讓它變得更干凈。2.2 構(gòu)建工具鏈npm run build背后的完整流水線工程化的第二個(gè)核心是構(gòu)建。很多人天天跑npm run build卻不知道背后到底發(fā)生了什么。我認(rèn)為一個(gè)進(jìn)階前端至少要理解這樣一條鏈路入口文件 - 依賴圖 - 代碼轉(zhuǎn)換 - 資源處理 - 產(chǎn)物優(yōu)化 - 輸出文件。以Webpack為例它的工作模式很像一條裝配流水線。入口告訴它從哪里開始拆零件loader負(fù)責(zé)把各種文件轉(zhuǎn)成JavaScript模塊能理解的形態(tài)比如babel-loader把ES6語法轉(zhuǎn)成兼容舊瀏覽器的ES5css-loader和style-loader把樣式接進(jìn)頁面plugin則負(fù)責(zé)流水線上的全局工序比如打包前清空目錄、對(duì)產(chǎn)物做壓縮、生成HTML模板。理解這條鏈路之后很多報(bào)錯(cuò)就不再神秘。出現(xiàn)“Module not found”本質(zhì)是依賴圖上斷了一條邊報(bào)“Unexpected token”通常是loader沒接住某種語法。我建議進(jìn)階階段不要只停留在會(huì)用腳手架而是自己用Webpack從零搭一個(gè)小項(xiàng)目把入口、loader、plugin、splitChunks全部手動(dòng)過一遍。這個(gè)過程雖然廢時(shí)間但對(duì)構(gòu)建體系的理解是質(zhì)的提升。Vite出現(xiàn)之后開發(fā)體驗(yàn)確實(shí)好很多依賴預(yù)構(gòu)建和按需編譯把冷啟動(dòng)時(shí)間大幅縮短。但它的生產(chǎn)構(gòu)建底層仍然依賴打包器而且部分場(chǎng)景的注意事項(xiàng)和Webpack不完全一樣。所以工程化學(xué)習(xí)不能只認(rèn)準(zhǔn)某一個(gè)工具而是要把“模塊-依賴-轉(zhuǎn)換-優(yōu)化”這套心智模型建立起來工具只是模型的具體實(shí)現(xiàn)。2.3 質(zhì)量與規(guī)范工程讓機(jī)器守規(guī)矩人只做review如果說模塊化和構(gòu)建解決的是“能不能跑起來”規(guī)范和自動(dòng)化解決的是“跑起來之后還亂不亂”。我強(qiáng)烈建議團(tuán)隊(duì)至少配置三樣?xùn)|西ESLint管代碼規(guī)范Prettier管格式統(tǒng)一Husky配合lint-staged在提交前自動(dòng)檢查。這不僅是減少Review時(shí)的口水仗更是把低級(jí)問題擋在提交之前。機(jī)器能攔住的錯(cuò)誤不要消耗人的注意力。還有一個(gè)容易被忽略的層面提交信息與代碼評(píng)審。約定式提交feat、fix、refactor這類前綴不只是一套格式它讓git log變成可讀的變更歷史之后做版本發(fā)布和問題回溯都方便得多。Code Review的核心也不是“挑錯(cuò)”而是“達(dá)成共識(shí)”讓新代碼在風(fēng)格、實(shí)現(xiàn)方式和系統(tǒng)方向上與既有代碼保持一致。這里我有一個(gè)踩過的大坑早期團(tuán)隊(duì)沒有約束API調(diào)用層接口請(qǐng)求散落在各個(gè)組件里后來后端接口統(tǒng)一加了鑒權(quán)和錯(cuò)誤碼我足足改了兩天。如果從一開始就把所有請(qǐng)求收斂到一個(gè)獨(dú)立的api層那天的改動(dòng)量其實(shí)只有幾行。這個(gè)教訓(xùn)讓我意識(shí)到工程化里最值錢的往往不是某個(gè)工具而是提前劃好的邊界。3. 性能優(yōu)化進(jìn)階從“能跑就行”到“極致體驗(yàn)”性能優(yōu)化是另一條大腿。它同樣不是臨時(shí)抱佛腳而是要建立對(duì)整個(gè)瀏覽器運(yùn)行機(jī)制的系統(tǒng)理解。很多人一上來就學(xué)各種優(yōu)化技巧但不知道技巧背后的原理遇到?jīng)]見過的性能問題就抓瞎。3.1 瀏覽器渲染鏈路性能問題的根都在這所有前端性能問題最后都能追到瀏覽器處理網(wǎng)頁的那條鏈路上。大致過程是這樣的HTML進(jìn)來后先解析成DOM樹CSS解析成CSSOM樹兩者合并成渲染樹然后依次做布局計(jì)算、繪制和合成。任何一個(gè)環(huán)節(jié)慢用戶都能感知到。這里最容易被忽略的是“布局”這一環(huán)。修改某個(gè)節(jié)點(diǎn)的寬高、位置瀏覽器可能要把后面一片節(jié)點(diǎn)的布局全部重算這叫重排。只改顏色、陰影這些不影響布局的屬性開銷會(huì)低很多這叫重繪。如果你一邊頻繁改樣式、一邊頻繁讀布局屬性還會(huì)觸發(fā)強(qiáng)制同步布局性能直接雪崩。我把這條鏈路類比成餐廳上菜HTML和CSS是菜譜瀏覽器是后廚渲染樹是配菜清單布局是切菜備菜繪制是炒菜出鍋合成是傳菜上臺(tái)。用戶點(diǎn)單之后整條流水線跑得越快體驗(yàn)越好。做性能優(yōu)化本質(zhì)上就是給這條流水線找瓶頸。3.2 加載性能把浪費(fèi)的幾百毫秒一點(diǎn)點(diǎn)摳回來加載性能是用戶對(duì)網(wǎng)站的第一印象。按業(yè)界公認(rèn)的核心指標(biāo)LCP最大內(nèi)容繪制最好在2.5秒以內(nèi)CLS累積布局偏移控制在0.1以內(nèi)INP交互到下一次繪制的響應(yīng)時(shí)間控制在200毫秒以內(nèi)。這些數(shù)字不是拍腦袋定的它們直接對(duì)應(yīng)用戶對(duì)“快”和“穩(wěn)”的體感。實(shí)操層面我會(huì)按順序做這幾件事。第一縮短關(guān)鍵渲染路徑。首屏用到的CSS直接以關(guān)鍵CSS形式內(nèi)聯(lián)減少CSS文件的阻塞給主資源加preload給需要用到的第三方資源地址加preconnect把DNS解析和握手的時(shí)間提前。第二減少資源體積。圖片是首屏體積的大頭能壓就壓能上WebP或AVIF就上字體文件做子集化并調(diào)整字體加載策略別讓看不見的字體拖住首屏。第三用好緩存。強(qiáng)緩存可以減少重復(fù)請(qǐng)求協(xié)商緩存應(yīng)對(duì)文件更新CDN把資源推到離用戶更近的地方。這里有個(gè)細(xì)節(jié)特別容易踩坑緩存不是配置越久越好如果入口HTML被強(qiáng)緩存用戶看到的更新會(huì)嚴(yán)重滯后。所以入口文件一般用no-cache帶hash的靜態(tài)資源才用長(zhǎng)緩存。我每次給項(xiàng)目做體檢時(shí)不會(huì)直接動(dòng)手優(yōu)化而是先用Lighthouse和瀏覽器DevTools的性能面板拿一組基線數(shù)據(jù)再對(duì)癥下藥。沒有基線的優(yōu)化就是閉眼開車改完也不知道自己到底是變好了還是變壞了。3.3 運(yùn)行時(shí)性能滾動(dòng)、點(diǎn)擊、動(dòng)畫都不能掉幀加載快只是第一步用戶還要在頁面上持續(xù)操作。如果滾動(dòng)卡頓、點(diǎn)擊延遲、動(dòng)畫掉幀前面攢下的好感會(huì)瞬間清零。瀏覽器要做到的流暢標(biāo)準(zhǔn)是60fps也就是說每一幀大約16.67毫秒內(nèi)要完成從布局到繪制到合成的全部工作。想做到這一點(diǎn)核心思路是“能不動(dòng)布局就不動(dòng)布局能走合成層就只走合成層”。比如動(dòng)畫優(yōu)先使用transform和opacity而不是去動(dòng)畫left、top這類會(huì)觸發(fā)布局計(jì)算的屬性。長(zhǎng)列表是運(yùn)行時(shí)性能的重災(zāi)區(qū)。渲染幾千條DOM即使瀏覽器撐得住節(jié)點(diǎn)數(shù)和內(nèi)存占用也會(huì)拖垮交互。虛擬列表的思路是只渲染可視區(qū)域附近的節(jié)點(diǎn)配合高度估算和滾動(dòng)偏移計(jì)算出哪些節(jié)點(diǎn)可見。我這里強(qiáng)烈建議自己動(dòng)手實(shí)現(xiàn)一遍虛擬列表而不是直接拿組件庫(kù)的來用。不親手踩一遍坐標(biāo)系和滾動(dòng)監(jiān)聽的坑理解永遠(yuǎn)停在表面?,F(xiàn)代框架里還有一個(gè)隱藏殺手不必要的重新渲染。React里memo和useMemo能攔截?zé)o效渲染Vue里計(jì)算屬性和v-memo可以做類似優(yōu)化。但優(yōu)化的前提是先定位我一般會(huì)在DevTools的Profiler里錄制一段交互看哪些組件毫無必要地重渲染了再動(dòng)手去改而不是閉著眼睛給每個(gè)組件加緩存。性能優(yōu)化的第一原則永遠(yuǎn)是測(cè)量沒有測(cè)量就沒有優(yōu)化。4. 實(shí)戰(zhàn)復(fù)盤一次把LCP從4.8秒壓到2.1秒的完整過程4.1 復(fù)盤起點(diǎn)問題清單比動(dòng)手更優(yōu)先理論說多了容易飄我拿一個(gè)親手做過的中后臺(tái)項(xiàng)目來復(fù)盤。項(xiàng)目是一個(gè)數(shù)據(jù)管理后臺(tái)功能不算復(fù)雜但首屏加載奇慢Lighthouse給出的LCP基線是4.8秒用戶已經(jīng)在內(nèi)部反饋群里直接開火了。我先沒急著改代碼而是列了一份問題清單路由沒有懶加載整個(gè)應(yīng)用所有代碼被打成一個(gè)體積很大的bundle首屏圖片全是原圖單張動(dòng)輒2MB某個(gè)第三方時(shí)間選擇器組件被全局注冊(cè)很多頁面根本用不上字體庫(kù)把大量用不到的字形也下發(fā)到了客戶端還有一部分接口串行請(qǐng)求頁面要等最后一個(gè)結(jié)果才肯渲染。問題清單列完目標(biāo)也就清晰了LCP壓到2.5秒以內(nèi)包體體積至少砍掉一半。這個(gè)目標(biāo)是可衡量的不像我早期做項(xiàng)目時(shí)只寫一句“優(yōu)化一下性能”然后完全沒有抓手。4.2 實(shí)操鏈路與數(shù)據(jù)記錄第一步拆包。路由級(jí)別全部改成懶加載把用不到的第三方組件改成按需引入。這一步操作后首屏JavaScript體積從8.6MB降到了2.7MB。第二步壓圖片。把圖片資源整體走一遍壓縮管線首屏的幾張關(guān)鍵圖轉(zhuǎn)成WebP格式單張?bào)w積從2MB左右降到200KB附近。第三步調(diào)整加載策略。關(guān)鍵CSS內(nèi)聯(lián)字體庫(kù)改為自托管并做子集化同時(shí)給靜態(tài)資源加帶hash的長(zhǎng)緩存。第四步把接口層從串行改成并行頁面不再等那個(gè)最慢的接口才渲染。每一步做完我都在相同的網(wǎng)絡(luò)模擬條件下重新跑一輪Lighthouse保留對(duì)比記錄。最終結(jié)果優(yōu)化項(xiàng)優(yōu)化前優(yōu)化后首屏JS體積8.6MB2.7MB圖片總體積約15MB約3MBLCP4.8s2.1sTTI可交互時(shí)間5.6s2.9s這張表放到團(tuán)隊(duì)評(píng)審會(huì)上一貼比任何解釋都有說服力。我一直覺得性能優(yōu)化最大的成就感不是技術(shù)上有多高級(jí)而是用戶那句“這次打開快多了”。4.3 三個(gè)月進(jìn)階節(jié)奏參考如果你打算系統(tǒng)走這條“Top2”路線我按自己的成長(zhǎng)經(jīng)歷給一個(gè)三個(gè)月的參考節(jié)奏方向可以借鑒細(xì)節(jié)根據(jù)自己項(xiàng)目調(diào)整。第一個(gè)月專攻工程化。目標(biāo)是能獨(dú)立從零搭建并解釋一套前端工程方案自己配Webpack、寫一個(gè)簡(jiǎn)單loader、搭一套ESLint加Prettier加Husky的規(guī)范鏈。月底的檢驗(yàn)方式是把手頭老項(xiàng)目的構(gòu)建日志和規(guī)范問題整理成一份優(yōu)化提案。第二個(gè)月專攻性能優(yōu)化。把瀏覽器渲染機(jī)制讀透用Lighthouse和DevTools給項(xiàng)目做一次體檢至少完成首屏加載和運(yùn)行時(shí)卡頓兩個(gè)方向的優(yōu)化并且記錄前后數(shù)據(jù)對(duì)比。第三個(gè)月綜合實(shí)戰(zhàn)。把工程化和性能優(yōu)化用在同一個(gè)中型項(xiàng)目里這種項(xiàng)目沒法靠單點(diǎn)技巧解決必須同時(shí)動(dòng)用工程手段和性能手段。這一步走完你再回頭看那些只有“初級(jí)水平”的項(xiàng)目眼睛會(huì)自動(dòng)長(zhǎng)出問題清單。5. 常見問題與進(jìn)階避坑指南最后整理一批高頻問題和真實(shí)的踩坑經(jīng)驗(yàn)?zāi)憧梢灾苯訉?duì)照著排查自己的項(xiàng)目。5.1 工程化高頻問題的排查方法先說五類我一再遇到的工程化問題。組件越拆越碎props層層穿透。十層嵌套加十幾個(gè)props改一個(gè)需求就要?jiǎng)右慌盼募?。這種情況可以嘗試組合模式或者把一部分共享狀態(tài)收進(jìn)全局狀態(tài)管理但注意上下文一旦被濫用代碼追蹤起來同樣痛苦。原則是就近共享用props跨層共享用store不要在中間層瞎傳。依賴升級(jí)像拆彈升級(jí)一個(gè)庫(kù)崩一片。升級(jí)前一定先讀變更日志特別是破壞性變更在小分支上升級(jí)并跑完整測(cè)試再合回主線。忽略這一步線上出事故只是遲早的事。構(gòu)建慢到崩潰。先查是不是loader匹配范圍太大把node_modules排除掉再開啟持久化緩存Webpack 5的cache配置和Babel緩存都能明顯提升二次構(gòu)建速度實(shí)在不行再考慮拆分構(gòu)建任務(wù)或者換更快的工具。鎖文件不提交。package-lock.json或yarn.lock不提交依賴就像流水一樣到處淌今天能裝上明天就掛。鎖文件是團(tuán)隊(duì)依賴穩(wěn)定的錨必須入庫(kù)。monorepo依賴提升帶來的迷之報(bào)錯(cuò)。多包項(xiàng)目里依賴會(huì)被提升到根目錄子包偶爾用到根目錄才有的依賴就會(huì)出現(xiàn)“幽靈依賴”。解決思路是顯式聲明每個(gè)包的依賴并用工具約束依賴提升規(guī)則別覺得不報(bào)錯(cuò)就沒問題。5.2 性能優(yōu)化的四個(gè)盲區(qū)第一只盯首屏忽略滾動(dòng)和交互。首屏做到2秒內(nèi)用戶一滾動(dòng)掉幀體驗(yàn)照樣崩。優(yōu)化順序應(yīng)該是加載性能與運(yùn)行時(shí)性能并進(jìn)不能偏廢。第二優(yōu)化前后沒有數(shù)據(jù)對(duì)比。沒有數(shù)字支撐你的優(yōu)化在別人眼里就是自嗨。每做一步改動(dòng)保留前后兩次測(cè)試數(shù)據(jù)用表格記錄下來。第三只測(cè)高端機(jī)。高端機(jī)性能過剩會(huì)掩蓋大量問題。我現(xiàn)在做性能體檢一定會(huì)選一臺(tái)中低端Android機(jī)器試一遍很多在開發(fā)機(jī)上“明明很流暢”的頁面到這臺(tái)機(jī)器上立刻原形畢露。第四緩存配置想當(dāng)然。入口HTML被強(qiáng)緩存是我踩過最痛的一個(gè)坑新版本發(fā)上去用戶那邊還是舊頁面。原則就是入口不緩存帶hash的靜態(tài)資源用長(zhǎng)緩存關(guān)鍵資源用preload提前請(qǐng)求。5.3 長(zhǎng)期積累的一個(gè)經(jīng)驗(yàn)漸進(jìn)改造比推倒重來更穩(wěn)最后聊一點(diǎn)心態(tài)。很多人在自家項(xiàng)目里想推行工程化和性能優(yōu)化時(shí)第一反應(yīng)是把技術(shù)棧全部換掉、推倒重來。這種做法在多數(shù)業(yè)務(wù)場(chǎng)景里都會(huì)失敗因?yàn)闃I(yè)務(wù)不能停線上不能斷。更穩(wěn)的方式是漸進(jìn)改造。先在新模塊里落地模塊化和代碼規(guī)范再給現(xiàn)有項(xiàng)目加構(gòu)建指標(biāo)監(jiān)控然后挑線上最卡的一個(gè)頁面做性能專項(xiàng)用真實(shí)數(shù)據(jù)說話。我?guī)F(tuán)隊(duì)做過的幾次改造成功率高的都是這種“邊跑邊換輪胎”的方式而不是急剎車。就像裝修老房子先保證水電能用再一個(gè)房間一個(gè)房間翻新不能上來就砸承重墻。走完這條“Top2”路線之后你看項(xiàng)目的眼光會(huì)徹底變掉從“這個(gè)頁面怎么寫”變成“這個(gè)系統(tǒng)怎么設(shè)計(jì)才穩(wěn)、才能更快”。積累了這么多年回頭看最值錢的真的不是多會(huì)用某個(gè)框架而是這套能跨框架、跨項(xiàng)目復(fù)用的系統(tǒng)能力。