99精品久久精品一区二区-亚洲熟妇无码?v在线播放-日本国产精品无码字幕在线观看-久久久亚洲永夜AV-亚洲一级无码一区二区一-免费国产成高清人在线视频-中文字幕乱码免费观看-国产毛片精品妇女久久久

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營(yíng)的一線實(shí)戰(zhàn)洞察。

React老項(xiàng)目打包優(yōu)化實(shí)戰(zhàn):用webpack-bundle-analyzer降低65%體積

React老項(xiàng)目打包優(yōu)化實(shí)戰(zhàn):用webpack-bundle-analyzer降低65%體積 最近接手了一個(gè)維護(hù)了三年的 React 老項(xiàng)目用戶反饋首屏白屏?xí)r間越來(lái)越離譜我隨手 build 一次產(chǎn)物里光 JS 就有接近 6MB。團(tuán)隊(duì)之前一直用換個(gè)網(wǎng)絡(luò)環(huán)境試試來(lái)掩蓋問(wèn)題直到要發(fā)新版本連本地開(kāi)發(fā)都明顯卡頓這才決定認(rèn)真做一次打包優(yōu)化。整個(gè)分析和動(dòng)手的過(guò)程核心工具就是 webpack-bundle-analyzer前后花了一周多時(shí)間產(chǎn)物體積降了約 65%首屏加載從 4 秒多壓到了 1.8 秒左右。這篇文章把我這次的完整思路、操作步驟和踩過(guò)的坑記錄下來(lái)如果你手上也有一個(gè)能跑但越來(lái)越慢的 React 老項(xiàng)目正打算做打包優(yōu)化可以直接照著這條路線走。1. 老項(xiàng)目動(dòng)刀之前的三個(gè)準(zhǔn)備工作先看清現(xiàn)狀再想怎么優(yōu)化很多同學(xué)拿到老項(xiàng)目就直接裝 webpack-bundle-analyzer、生成個(gè)報(bào)告然后對(duì)著報(bào)告一頓亂拆拆完發(fā)現(xiàn)構(gòu)建報(bào)錯(cuò)、線上白屏、緩存全失效。我這次學(xué)乖了動(dòng)手前先做了三件事這幾步幾乎決定了后續(xù)優(yōu)化能不能順利落地。1.1 鎖定項(xiàng)目當(dāng)前的構(gòu)建工具鏈版本老項(xiàng)目最麻煩的地方在于你不知道它在哪一年突然停更過(guò)。所以第一步不是裝插件而是先確認(rèn) webpack 和 React 的版本這兩個(gè)版本直接決定你能用哪些優(yōu)化手段。我一般這樣排查看package.json里的devDependencies確認(rèn)webpack主版本執(zhí)行webpack --version確認(rèn)命令行實(shí)際使用的版本在package.json里確認(rèn)react和react-dom版本這關(guān)系到能不能用React.lazy做路由懶加載檢查 webpack 配置里有沒(méi)有DllPlugin、CommonsChunkPlugin這類(lèi)歷史遺留方案。這里有個(gè)容易忽略的點(diǎn)webpack 3 時(shí)代流行的CommonsChunkPlugin在 webpack 4 里已經(jīng)廢掉了如果你項(xiàng)目里還有這個(gè)配置同時(shí)又想用optimization.splitChunks運(yùn)行時(shí)會(huì)有沖突或者直接報(bào)錯(cuò)。我接手這個(gè)項(xiàng)目時(shí)配置文件里就同時(shí)存在CommonsChunkPlugin和一堆手寫(xiě)的externals這些都是早年用 CDN 方式引第三方庫(kù)留下的需要先理清楚哪些還生效哪些其實(shí)已經(jīng)是死代碼。另外React 版本決定了懶加載方案。React 16.6 之前沒(méi)有React.lazy只能用react-loadable或者自己寫(xiě)高階組件做異步加載。我的項(xiàng)目是 React 16.8后來(lái)用React.lazy Suspense比較順。如果你手里的老項(xiàng)目還在 React 15.x別急著抄后面的代碼得先解決 React 版本升級(jí)或者改用react-loadable。1.2 建立優(yōu)化前的數(shù)據(jù)基線沒(méi)有基線后面所有優(yōu)化都沒(méi)有說(shuō)服力第二件事是在任何優(yōu)化動(dòng)作之前把優(yōu)化前的各項(xiàng)數(shù)據(jù)記錄下來(lái)。這不是走形式而是整個(gè)優(yōu)化工程里最重要的參照物。沒(méi)有基線你拆完包之后說(shuō)感覺(jué)快了很多那跟換個(gè)網(wǎng)絡(luò)環(huán)境試試有什么區(qū)別我用 Chrome DevTools 調(diào)成 Slow 3G 網(wǎng)絡(luò)用無(wú)痕窗口打開(kāi)線上頁(yè)面記錄以下幾項(xiàng)指標(biāo)記錄值說(shuō)明首屏請(qǐng)求的 JS 資源總大小通過(guò) Network 面板的 Transfer Size 合計(jì)這是用戶真實(shí)下載的字節(jié)數(shù)首屏請(qǐng)求數(shù)Network 面板統(tǒng)計(jì)老項(xiàng)目常見(jiàn)二三十個(gè)請(qǐng)求DOMContentLoaded 時(shí)間Performance 面板粗略反映 HTML腳本執(zhí)行完的時(shí)間FCP首次內(nèi)容繪制Lighthouse 或 Performance用戶感知到頁(yè)面有東西了的時(shí)刻構(gòu)建產(chǎn)物體積總和webpack --profile或 build 輸出本地產(chǎn)物總大小我當(dāng)時(shí)記錄的基線數(shù)據(jù)是這樣的首屏 JS 資源 transfer 大小約 1.9MBgzip 后請(qǐng)求數(shù) 27 個(gè)FCP 在 Slow 3G 下是 4.2 秒。這些數(shù)字寫(xiě)下來(lái)之后后面每做一步優(yōu)化都可以對(duì)照著看是否真的有效避免自我感覺(jué)良好。這里要額外提醒一句測(cè)量工具本身會(huì)帶來(lái)干擾。比如 Chrome DevTools 的 Network 面板如果開(kāi)著緩存禁用測(cè)出來(lái)的數(shù)字會(huì)偏大。建議統(tǒng)一用無(wú)痕窗口并且固定設(shè)備模擬檔位保證前后對(duì)比在同一個(gè)環(huán)境下進(jìn)行。1.3 別急著清依賴先整體過(guò)一遍 package.json 的重復(fù)依賴?yán)享?xiàng)目的依賴幾乎都是能用就行堆出來(lái)的。我在優(yōu)化前先執(zhí)行了npm ls --depth0和npm ls lodash發(fā)現(xiàn)項(xiàng)目里同時(shí)存在lodash和lodash-es還有兩套版本相差很大的moment一個(gè)是業(yè)務(wù)代碼直接用另一個(gè)是被某個(gè)內(nèi)部組件庫(kù)間接依賴的。這種重復(fù)依賴如果不提前發(fā)現(xiàn)優(yōu)化到一半很容易被為什么拆了這個(gè)庫(kù)包還是這么大卡住。這一步不需要把依賴全部理清但至少要回答三個(gè)問(wèn)題項(xiàng)目里有沒(méi)有同名不同版本的庫(kù)有沒(méi)有功能重疊的庫(kù)moment和dayjs同時(shí)存在有沒(méi)有通過(guò)externals從 CDN 引入的庫(kù)這三個(gè)問(wèn)題的答案會(huì)直接影響后面 splitChunks 的 cacheGroups 怎么設(shè)計(jì)。2. 接入 webpack-bundle-analyzer兩種方式各有利弊工具接入本身不難難的是選對(duì)方式。我在這個(gè)項(xiàng)目里兩種方式都試過(guò)一種是在 webpack 配置里直接掛插件另一種是用stats.json配合命令行獨(dú)立分析。下面把細(xì)節(jié)和適用場(chǎng)景都講清楚。2.1 方式一作為 webpack 插件集成構(gòu)建完自動(dòng)打開(kāi)報(bào)告最直接的方式就是在 webpack 配置文件里加一個(gè)插件實(shí)例。我通常不會(huì)直接寫(xiě)死在生產(chǎn)配置里而是用一個(gè)環(huán)境變量控制避免團(tuán)隊(duì)每次構(gòu)建都彈出瀏覽器窗口。const { BundleAnalyzerPlugin } require(webpack-bundle-analyzer); module.exports { // ... 其他配置 plugins: [ process.env.ANALYZE ? new BundleAnalyzerPlugin({ analyzerMode: server, // server 模式會(huì)啟動(dòng)本地服務(wù)并自動(dòng)打開(kāi)瀏覽器 analyzerHost: 127.0.0.1, analyzerPort: 8888, reportFilename: bundle-report.html, openAnalyzer: true, generateStatsFile: false, // 如果只需要報(bào)告不必生成 stats.json }) : null, ].filter(Boolean), };然后在package.json里加一條腳本{ scripts: { build:analyze: cross-env ANALYZE1 webpack --config webpack.prod.config.js } }這樣執(zhí)行npm run build:analyze就會(huì)啟動(dòng)一個(gè)本地服務(wù)瀏覽器自動(dòng)打開(kāi)127.0.0.1:8888展示可視化的依賴樹(shù)形圖treemap。每個(gè)方塊代表一個(gè)模塊方塊越大說(shuō)明該模塊占用的體積越大顏色深淺則代表是否為 gzip 壓縮后的大小。插件方式的好處是集成簡(jiǎn)單適合團(tuán)隊(duì)里所有人都能一鍵跑分析的場(chǎng)景。但它的缺點(diǎn)也很明顯BundleAnalyzerPlugin會(huì)作為 webpack 插件參與構(gòu)建雖然不影響產(chǎn)物但會(huì)在構(gòu)建過(guò)程中增加額外的統(tǒng)計(jì)開(kāi)銷(xiāo)構(gòu)建時(shí)間會(huì)長(zhǎng)一些。而且如果 webpack 配置特別復(fù)雜比如有多個(gè)環(huán)境配置文件你需要確保插件加在了正確的那個(gè)配置文件里。2.2 方式二用 stats.json 配合命令行不污染業(yè)務(wù)配置第二種方式是我比較推薦的尤其適合老項(xiàng)目——因?yàn)樗耆粍?dòng) webpack 配置。webpack 本身就支持導(dǎo)出整個(gè)構(gòu)建過(guò)程的 stats 信息導(dǎo)出成 JSON 文件后用webpack-bundle-analyzer這個(gè)命令行工具直接分析。# 先構(gòu)建并導(dǎo)出 stats 數(shù)據(jù) webpack --config webpack.prod.config.js --json --profile stats.json # 再啟動(dòng)分析器 npx webpack-bundle-analyzer stats.json這種方式有幾個(gè)實(shí)際好處不需要在項(xiàng)目代碼里引入任何插件不影響正常構(gòu)建stats.json是構(gòu)建的完整快照包含模塊依賴、體積、耗時(shí)等信息后續(xù)做對(duì)比分析時(shí)可以直接復(fù)用可以配合 CI 流程把每次構(gòu)建的stats.json歸檔形成體積趨勢(shì)圖。要注意的是--json輸出的文件很大我這個(gè)項(xiàng)目大概 40 多 MB所以用完記得從項(xiàng)目目錄里刪掉或者用.gitignore排除。另外如果.babelrc或tsconfig里配置了緩存--json導(dǎo)出的是實(shí)際構(gòu)建結(jié)果不受緩存影響這點(diǎn)可以放心。2.3 拿到報(bào)告之后先看這四個(gè)地方再動(dòng)手報(bào)告生成后很多人的第一反應(yīng)是盯著最顯眼的那個(gè)大色塊準(zhǔn)備開(kāi)始拆它。我的建議是先快速過(guò)四個(gè)關(guān)鍵點(diǎn)這樣你腦子里對(duì)項(xiàng)目整體的構(gòu)成能有一個(gè)完整的圖景看parsed size還是gzip size。雙擊某個(gè)色塊可以切換展示模式。parsed size是未壓縮的原始大小gzip size是壓縮后的傳輸大小。判斷是否值得優(yōu)化時(shí)應(yīng)該以 gzip 為主要參考因?yàn)榫€上服務(wù)器通常開(kāi)了 gzip??慈肟?chunk 的大小分布。把報(bào)告左側(cè)的 chunk 列表展開(kāi)關(guān)注哪些 chunk 是首屏加載時(shí)就要請(qǐng)求的entry chunk哪些是路由懶加載之后才會(huì)請(qǐng)求的async chunk??从袥](méi)有異常大的單模塊。有些庫(kù)本身不算大但因?yàn)橐肓怂姓Z(yǔ)言包、所有主題體積會(huì)成倍膨脹這類(lèi)問(wèn)題非常適合定向處理??粗貜?fù)模塊。如果同一個(gè)庫(kù)名出現(xiàn)在多個(gè) chunk 里說(shuō)明業(yè)務(wù)代碼對(duì)它的引用方式有問(wèn)題可能是按需引入沒(méi)生效也可能是 cacheGroups 沒(méi)有正確聚合。我當(dāng)時(shí)看完報(bào)告最直觀的感受就是這個(gè)項(xiàng)目不是某一個(gè)庫(kù)太大而是每一個(gè)庫(kù)都沒(méi)被好好控制。這也為后面的優(yōu)化定下了基調(diào)——不是做一兩個(gè)大改動(dòng)而是系統(tǒng)性地把每一類(lèi)依賴都重新過(guò)一遍。3. 報(bào)告暴露出來(lái)的問(wèn)題React 老項(xiàng)目的五個(gè)典型通病我的項(xiàng)目報(bào)告里vendor.js這一個(gè) chunk 的 parsed size 就達(dá)到了 4.6MB。如果你現(xiàn)在也正對(duì)著一份類(lèi)似的報(bào)告發(fā)愁不用慌下面這五個(gè)問(wèn)題在 React 老項(xiàng)目里幾乎是標(biāo)配而且都有成熟的解法。3.1 全量引入 UI 組件庫(kù)和圖表庫(kù)我的項(xiàng)目里antd的 parsed size 是 1.8MB 左右。為什么這么大因?yàn)闃I(yè)務(wù)代碼里寫(xiě)的是import { Button } from antd看似是按需引入但如果 babel 沒(méi)有配babel-plugin-import這條語(yǔ)句最終會(huì)被編譯成var Button require(antd)也就是把整個(gè)antd全部加載進(jìn)來(lái)。本質(zhì)原因就是import { Button } from antd這個(gè)語(yǔ)法本身具備 tree-shaking 的可能但前提是antd的 package.json 里配置了sideEffects: false或module入口而且 babel 轉(zhuǎn)譯時(shí)不能把模塊系統(tǒng)直接轉(zhuǎn)成 CommonJS。圖表庫(kù)也是這樣。項(xiàng)目里用了echarts業(yè)務(wù)代碼是import * as echarts from echarts這等于把 echarts 全部圖表類(lèi)型、渲染器和組件都帶上了parsed size 超過(guò) 1MB。正確做法是echarts/core按需引入需要的圖表和渲染器這個(gè)在后面 4.3 節(jié)詳細(xì)講。3.2 moment.js 把所有語(yǔ)言包都打進(jìn)來(lái)了moment是 React 老項(xiàng)目里最典型的體積元兇之一。默認(rèn)情況下moment會(huì)打包全部 locale 語(yǔ)言文件即便你只需要中文。報(bào)告里你會(huì)看到moment的 parsed size 超過(guò) 700KB但其中真正用的只有一小部分。專(zhuān)門(mén)的 locale 文件全部打進(jìn)包里屬于典型的用不到的體積。這類(lèi)庫(kù)的優(yōu)化思路有兩個(gè)方向用IgnorePlugin剔除 locale 文件或者干脆換dayjs這種體積小一個(gè)數(shù)量級(jí)的替代庫(kù)。我最后選擇了后者細(xì)節(jié)在后面單獨(dú)說(shuō)。3.3 lodash 全量引入導(dǎo)致 tree-shaking 失效老項(xiàng)目里幾乎不可能沒(méi)有l(wèi)odash。我的項(xiàng)目里lodash的 parsed size 是 400KB 左右原因是大量代碼里直接import _ from lodash。lodash主包是 CommonJS 格式現(xiàn)代打包工具很難對(duì)它做 tree-shaking所以最佳習(xí)慣是改為import debounce from lodash/debounce這樣的按需路徑引入或者配置babel-plugin-lodash自動(dòng)轉(zhuǎn)換。如果你在報(bào)告里看到lodash-es而不是lodash那又是另一種情況lodash-es是 ES module 版本理論上可以被 tree-shaking但前提是你的業(yè)務(wù)代碼沒(méi)有被 babel 轉(zhuǎn)成 CommonJS。很多老項(xiàng)目的.babelrc里配置了babel/preset-env默認(rèn)會(huì)把 ES module 轉(zhuǎn)成 CommonJS這會(huì)導(dǎo)致lodash-es的 tree-shaking 優(yōu)勢(shì)完全喪失。所以排查時(shí)不能只看庫(kù)本身還要看 babel 的配置鏈。3.4 polyfill 全量引入導(dǎo)致基礎(chǔ)工具函數(shù)被重復(fù)打包React 老項(xiàng)目里babel/polyfill或core-js全量引入的情況非常多。babel/polyfill本質(zhì)上是core-js和regenerator-runtime的合集全量引入會(huì)讓每個(gè)用到新 API 的頁(yè)面都背上幾百 KB 的 polyfill 成本。正確的做法是按需要的特性引入core-js中的具體模塊或者用babel/preset-env配合useBuiltIns: usage實(shí)現(xiàn)按需 polyfill。老項(xiàng)目之所以容易踩這個(gè)坑是因?yàn)楫?dāng)年寫(xiě)import babel/polyfill的時(shí)候覺(jué)得省事后面就再也沒(méi)人記得去改。同時(shí)如果 babel 配置里沒(méi)有采用babel/plugin-transform-runtimebabel 轉(zhuǎn)譯時(shí)會(huì)在每個(gè)文件里都內(nèi)聯(lián)一部分輔助函數(shù)造成大量重復(fù)。這個(gè)在報(bào)告里不容易一眼看到因?yàn)槊總€(gè)重復(fù)模塊都很小但積少成多后總效果非常明顯。3.5 所有的路由頁(yè)面都打包進(jìn)了首屏入口 chunkReact 老項(xiàng)目普遍沒(méi)有做路由懶加載。如果你的 App 里有十幾個(gè)路由頁(yè)面它們會(huì)全部打包進(jìn)一個(gè)入口 chunk 里用戶訪問(wèn)首頁(yè)時(shí)所有頁(yè)面的代碼都要先下載完。報(bào)告里體現(xiàn)為入口 chunk 特別大async chunk 數(shù)目為零。這是優(yōu)化優(yōu)先級(jí)最高的一項(xiàng)因?yàn)樗氖找鎺缀趿⒏鸵?jiàn)影。4. 按優(yōu)先級(jí)動(dòng)手我實(shí)際執(zhí)行的五步優(yōu)化下面按我執(zhí)行的順序把每一步的具體操作和理由講清楚。這個(gè)順序不是隨便排的每一步都會(huì)影響下一步的方案選擇所以建議大家按順序來(lái)。4.1 第一步用 splitChunks 把 node_modules 里的公共依賴統(tǒng)一抽離這是 webpack 4 之后最基礎(chǔ)、也是收益最大的一步。把第三方依賴統(tǒng)一抽成獨(dú)立的 chunk一方面減少了模塊在多個(gè) chunk 之間的重復(fù)打包另一方面利用瀏覽器緩存讓用戶升級(jí)業(yè)務(wù)代碼時(shí)不用重新下載體積龐大的第三方庫(kù)。我當(dāng)時(shí)的 splitChunks 配置大致是這樣optimization: { splitChunks: { chunks: all, maxInitialRequests: 4, maxAsyncRequests: 6, cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, priority: -10, name: vendors }, antd: { test: /[\\/]node_modules[\\/]antd[\\/]/, priority: 10, name: antd }, echarts: { test: /[\\/]node_modules[\\/]echarts[\\/]/, priority: 10, name: echarts }, common: { minChunks: 2, minSize: 30000, priority: -20, name: common } } } }這里有幾個(gè)細(xì)節(jié)值得展開(kāi)。chunks: all表示同步引入和異步引入的代碼都參與拆包。如果你只寫(xiě)chunks: initial那么動(dòng)態(tài)import()引入的模塊不會(huì)被拆分可能導(dǎo)致懶加載的 chunk 里又重復(fù)打了一遍 React 或 antd。這個(gè)參數(shù)是最容易配錯(cuò)的點(diǎn)。priority決定多個(gè) cacheGroup 匹配時(shí)誰(shuí)優(yōu)先。antd 和 echarts 的體積大我希望它們能單獨(dú)成 chunk這樣它們的 hash 只會(huì)在自身內(nèi)容變化時(shí)才變化業(yè)務(wù)代碼更新不會(huì)導(dǎo)致這兩個(gè)大 chunk 重新下載。如果不給它們單獨(dú)分組的 priority它們會(huì)被并進(jìn)vendors那樣雖然拆包總數(shù)少但 antd 一更新整個(gè) vendors 都失效緩存利用率會(huì)低很多。name字段一定要固定。webpack 4 默認(rèn)會(huì)給自動(dòng)生成的 vendor chunk 按數(shù)字編號(hào)命名當(dāng)依賴順序變化時(shí)編號(hào)會(huì)漂移導(dǎo)致 chunk hash 大面積變化這是明明沒(méi)改代碼hash 卻全變了的經(jīng)典原因。我踩過(guò)這個(gè)坑后所有 cacheGroup 都顯式指定 name。如果你是從 webpack 3 升級(jí)上來(lái)一定要先刪掉原來(lái)配置里的CommonsChunkPlugin否則它和splitChunks會(huì)同時(shí)生效產(chǎn)生大量重復(fù)的小 chunk。這一步做完我的vendor.js從 4.6MB 拆成了antd、echarts、vendors三個(gè) chunk加起來(lái)反而比原來(lái)小了不少因?yàn)槔锩娴闹貜?fù)模塊被剝離了。4.2 第二步路由級(jí)代碼分割讓首屏只加載當(dāng)前頁(yè)面需要的代碼拆完公共依賴后入口 chunk 依然很大因?yàn)槭畮讉€(gè)路由頁(yè)面全都打包在里面。這一步的目標(biāo)是把所有頁(yè)面的代碼變成當(dāng)前頁(yè)面的代碼 運(yùn)行時(shí)按需加載的代碼。如果你的 React 版本在 16.6 以上直接用React.lazy加Suspenseimport { lazy, Suspense } from react; import { BrowserRouter as Router, Route, Switch } from react-router-dom; import Loading from ./components/Loading; const Dashboard lazy(() import(/* webpackChunkName: dashboard */ ./pages/Dashboard)); const UserManage lazy(() import(/* webpackChunkName: user */ ./pages/UserManage)); const Settings lazy(() import(/* webpackChunkName: settings */ ./pages/Settings)); function App() { return ( Router Suspense fallback{Loading /} Switch Route exact path/ component{Dashboard} / Route path/user component{UserManage} / Route path/settings component{Settings} / /Switch /Suspense /Router ); } export default App;關(guān)鍵點(diǎn)在于import(/* webpackChunkName: dashboard */ ./pages/Dashboard)里的webpackChunkName注釋它給動(dòng)態(tài)生成的 chunk 起了一個(gè)有意義的文件名否則你會(huì)在報(bào)告里看到一堆0.js、1.js完全沒(méi)法定位是哪個(gè)頁(yè)面。如果你項(xiàng)目還在 React 15.x用react-loadableimport Loadable from react-loadable; const Dashboard Loadable({ loader: () import(./pages/Dashboard), loading: Loading, delay: 200, });這一步做完優(yōu)化效果非常直觀。首屏入口 chunk 從一個(gè) 近5MB 的龐然大物變成了只包含 React 運(yùn)行時(shí)、路由、布局框架等公共代碼的 200KB 左右 chunk。每個(gè)路由頁(yè)面獨(dú)立成 chunk用戶訪問(wèn)哪個(gè)頁(yè)面就加載哪個(gè)頁(yè)面的代碼。這里有一個(gè)反直覺(jué)的坑不要對(duì)首屏默認(rèn)進(jìn)入的那個(gè)頁(yè)面做懶加載。如果首頁(yè)本身就是落地頁(yè)把首頁(yè)也做成動(dòng)態(tài) import首屏?xí)喟l(fā)起一個(gè) HTTP 請(qǐng)求反而增加延遲。我在項(xiàng)目里把登錄頁(yè)和首頁(yè)放在了入口 chunk 里其余頁(yè)面懶加載。4.3 第三步UI 庫(kù)和圖表庫(kù)按需引入讓 tree-shaking 真正生效路由拆分解決了整體過(guò)大的問(wèn)題接下來(lái)要解決單個(gè)庫(kù)過(guò)大的問(wèn)題。先是 antd配置babel-plugin-import后import { Button } from antd會(huì)被自動(dòng)轉(zhuǎn)換為import Button from antd/es/button連同樣式也會(huì)按需加載。.babelrc里這樣配{ presets: [babel/preset-react, [babel/preset-env, { modules: false }]], plugins: [ [import, { libraryName: antd, libraryDirectory: es, style: css }] ] }注意preset-env里的modules: false這個(gè)配置讓 babel 保留 ES module 語(yǔ)法不轉(zhuǎn)成 CommonJS這樣打包工具才能在后續(xù)做 tree-shaking。如果你項(xiàng)目里同時(shí)用了 TSbabel/preset-typescript也要注意同樣的設(shè)置。style: css表示按需加載組件對(duì)應(yīng)的 css 文件。如果你的項(xiàng)目用的是 less 定制主題可以把style改成trueantd 會(huì)加載 less 文件。這個(gè)改動(dòng)需要注意全局樣式覆蓋如果你之前靠antd/dist/antd.css引入的全局 reset 樣式改成按需后要在公共入口處手動(dòng)引一次。echarts 的處理也類(lèi)似但思路不同。echarts 5 開(kāi)始支持echarts/core方式按需注冊(cè)import * as echarts from echarts/core; import { BarChart, LineChart } from echarts/charts; import { GridComponent, TooltipComponent } from echarts/components; import { CanvasRenderer } from echarts/renderers; echarts.use([BarChart, LineChart, GridComponent, TooltipComponent, CanvasRenderer]);這一步實(shí)際上是把 echarts 從一個(gè) 1MB 的大包縮小到只包含你用到的那幾種圖表。我項(xiàng)目里主要用柱狀圖和折線圖配完工具提示和網(wǎng)格gzip 后只有原來(lái)的三分之一左右。lodash 的處理我選了最保守的方式不換庫(kù)直接把全量引入改成按路徑引入。import _ from lodash改成import debounce from lodash/debounce。如果你的代碼里用了大量 lodash API可以在 babel 里加babel-plugin-lodash自動(dòng)轉(zhuǎn)換省得手動(dòng)改幾十個(gè)文件。但是要留意這個(gè)插件對(duì)lodash-es和 CommonJS 混用的情況處理得不夠理想所以我最后還是手動(dòng)改了一部分關(guān)鍵模塊。4.4 第四步對(duì) moment.js 這種頑固分子下手先裁剪再替換moment 的問(wèn)題前面說(shuō)過(guò)了默認(rèn)打包全部 locale體積大。最省事的操作是先用IgnorePlugin把 locale 文件剔除掉const webpack require(webpack); module.exports { plugins: [ new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), ], };這個(gè)正則的意思是匹配包名以moment開(kāi)頭、導(dǎo)入路徑是./locale的模塊直接忽略。配置之后 moment 的 parsed size 大概能從 700KB 降到 300KB 左右因?yàn)楹诵膸?kù)本身還是保留的。別小看這個(gè)正則IgnorePlugin的resourceRegExp和contextRegExp兩個(gè)參數(shù)的順序很容易寫(xiě)反寫(xiě)反后可能導(dǎo)致整個(gè) moment 都被忽略運(yùn)行時(shí)報(bào)錯(cuò)。如果你希望體積縮得更狠就把 moment 整體替換成 dayjs。dayjs 的核心只有 2KB 左右API 和 moment 高度一致。我的替換步驟是這樣的在package.json里加入dayjs暫時(shí)保留 moment先用 webpack alias 把所有import xxx from moment指向 dayjsresolve: { alias: { moment: dayjs, }, },全局搜索業(yè)務(wù)代碼里所有moment用法逐個(gè)處理 API 差異最典型的差異是moment().format(YYYY-MM-DD)在兩者中寫(xiě)法一致moment().startOf(day)在 dayjs 里行為基本一致moment.locale(zh-cn)需要改成import dayjs/locale/zh-cn加上dayjs.locale(zh-cn)moment.isMoment()在 dayjs 里要改成dayjs.isDayjs()。處理完所有業(yè)務(wù)代碼后最后再看報(bào)告確認(rèn)項(xiàng)目里還有沒(méi)有其他包比如某個(gè)老版本 antd 或業(yè)務(wù)組件庫(kù)依賴 moment。我當(dāng)時(shí)發(fā)現(xiàn)一個(gè)內(nèi)部統(tǒng)計(jì)組件間接依賴了 moment 2.x但它只是用它格式化日期于是我把那個(gè)組件也改了。這一步做完moment 相關(guān)體積從 700KB 變成了 dayjs 的 7KB。甚至比很多同學(xué)在第一步做的拆包效果更明顯。4.5 第五步輸出文件加上 ContentHash讓之前拆出來(lái)的緩存真正生效前面拆了那么多 chunk如果輸出文件名還是固定的bundle.js那瀏覽器永遠(yuǎn)不知道這些文件更新了會(huì)一直使用舊緩存。這次優(yōu)化的最后一步就是把輸出文件改成帶內(nèi)容 hash 的形式。output: { filename: [name].[contenthash:8].js, chunkFilename: [name].[contenthash:8].js, },[contenthash]是根據(jù)文件內(nèi)容生成的 hash文件內(nèi)容變化時(shí) hash 才變化。加上這個(gè)之后業(yè)務(wù)代碼更新時(shí)只有業(yè)務(wù) chunk 的 hash 會(huì)變antd、echarts、vendors 這些第三方 chunk 的 hash 保持不變?yōu)g覽器可以直接走緩存。但這里有一個(gè) webpack 4 特有的坑模塊的 id 默認(rèn)是自增數(shù)字只要新增或刪除一個(gè)模塊所有模塊的 id 都可能變化導(dǎo)致許多本來(lái)沒(méi)變的 chunk 的 hash 跟著變。解決方式是加上optimization.moduleIds: hashed讓模塊 id 基于模塊路徑生成內(nèi)容路徑不變 id 就不變。webpack 5 已經(jīng)默認(rèn)用deterministic方案不需要手動(dòng)配。optimization: { moduleIds: hashed, },這個(gè)配置本身其實(shí)也是優(yōu)化的一部分。很多人只加了[contenthash]卻漏了moduleIds發(fā)現(xiàn) hash 還是到處變以為配置無(wú)效其實(shí)問(wèn)題就出在模塊 id 不穩(wěn)定。另外如果服務(wù)器還沒(méi)開(kāi) gzip這一步建議一并處理。最穩(wěn)妥的方式是讓運(yùn)維在 Nginx 層開(kāi)啟 gzip 或 brotli如果不方便改服務(wù)器配置也可以用compression-webpack-plugin在構(gòu)建時(shí)直接生成.gz文件讓服務(wù)器直接返回壓縮文件。開(kāi)啟 gzip 后JS 體積大概能再縮小 60% 到 70%效果非??捎^。5. 拆包優(yōu)化之后的隱藏坑緩存穩(wěn)定性、請(qǐng)求數(shù)與驗(yàn)證方式優(yōu)化做完不等于萬(wàn)事大吉。我這次在收尾階段又踩了幾個(gè)坑都是拆包之后才會(huì)暴露出來(lái)的問(wèn)題專(zhuān)門(mén)寫(xiě)一節(jié)提醒后來(lái)的同學(xué)。5.1 拆包的穩(wěn)定性直接決定緩存命中率拆包方案確定之后最重要的一件事是保證每次構(gòu)建相同的代碼生成相同的 chunk 和 hash。否則哪怕你沒(méi)改代碼重新構(gòu)建出來(lái)的 hash 也變了緩存全部失效優(yōu)化等于白做。保證穩(wěn)定性的關(guān)鍵有三個(gè)cacheGroup 里的name必須顯式指定不要用 webpack 自動(dòng)生成的數(shù)字編號(hào)配置optimization.moduleIds讓模塊 id 穩(wěn)定動(dòng)態(tài)import()必須在代碼里用靜態(tài)字符串路徑不要用變量拼接路徑否則 webpack 沒(méi)法確定 chunk 邊界可能生成不可預(yù)測(cè)的 chunk。我建議在優(yōu)化完成后連續(xù)構(gòu)建兩次對(duì)比兩次dist目錄里的文件名是否完全一致。如果兩次 hash 不同說(shuō)明配置里還有不穩(wěn)定因素不要急著上線。5.2 拆得太碎首屏請(qǐng)求數(shù)反而拖累加載拆包有個(gè)陷阱不是越細(xì)越好。HTTP/1.1 時(shí)代瀏覽器對(duì)同域名的并發(fā)請(qǐng)求數(shù)限制在 6 個(gè)左右如果你把業(yè)務(wù)代碼拆成三十個(gè)小 chunk首屏要排隊(duì)下載反而更慢。即便現(xiàn)在普遍用 HTTP/2每個(gè)請(qǐng)求也有 header 和連接開(kāi)銷(xiāo)請(qǐng)求數(shù)過(guò)多依然會(huì)拖慢首屏。我在這個(gè)項(xiàng)目里嘗試過(guò)把每個(gè)頁(yè)面里的業(yè)務(wù)模塊進(jìn)一步拆成細(xì)粒度 chunk結(jié)果首屏請(qǐng)求數(shù)從十幾個(gè)變成三十幾個(gè)FCP 反而從 1.8 秒漲回 2.1 秒。后來(lái)我把maxInitialRequests設(shè)置為 4把首頁(yè)相關(guān)的幾個(gè)核心模塊合并到一個(gè) chunk 里才回到理想狀態(tài)。如果你的服務(wù)器不支持 HTTP/2尤其要注意不要拆太碎。老項(xiàng)目有時(shí)還掛著某種內(nèi)網(wǎng)環(huán)境的舊瀏覽器請(qǐng)求并發(fā)限制更嚴(yán)格寧可單個(gè) chunk 大一點(diǎn)也別讓首屏請(qǐng)求數(shù)失控。5.3 優(yōu)化效果的驗(yàn)證同時(shí)看體積數(shù)字和真實(shí)加載表現(xiàn)最后驗(yàn)證階段我又把 webpack-bundle-analyzer 生成了一份新的報(bào)告和優(yōu)化前的報(bào)告對(duì)比。同一份stats.json也可以直接復(fù)用跑一次webpack-bundle-analyzer打開(kāi)舊文件和 新文件看顏色塊的面積變化非常直觀。我優(yōu)化前后的關(guān)鍵數(shù)據(jù)對(duì)比項(xiàng)目?jī)?yōu)化前優(yōu)化后總構(gòu)建產(chǎn)物 parsed size約 6.8MB約 2.4MBgzip 后總傳輸體積約 1.9MB約 700KB首屏 chunk 數(shù)量1 個(gè)所有頁(yè)面都在一起4 個(gè)FCPSlow 3G4.2 秒1.8 秒白屏?xí)r間用戶反饋3 秒以上基本感覺(jué)不到但是要特別注意構(gòu)建產(chǎn)物小了不一定代表線上真實(shí)體驗(yàn)就快了。還要在線上環(huán)境重新測(cè)一遍 FCP、LCP、請(qǐng)求數(shù)用前面同樣的網(wǎng)絡(luò)條件。我見(jiàn)過(guò)有同學(xué)本地構(gòu)建產(chǎn)物很小但上線后因?yàn)榉?wù)器沒(méi)開(kāi) gzip、或者某些 chunk 被錯(cuò)誤的緩存策略緩存了體驗(yàn)反而更差。所以驗(yàn)證一定要以真實(shí)線上環(huán)境為準(zhǔn)?;氐介_(kāi)頭說(shuō)的那個(gè)問(wèn)題老項(xiàng)目不是不能優(yōu)化而是要有方法、有順序、有驗(yàn)證。webpack-bundle-analyzer 的價(jià)值在于把我覺(jué)得項(xiàng)目很慢變成我知道項(xiàng)目慢在哪個(gè)模塊所有決策都建立在數(shù)據(jù)之上。順著報(bào)告暴露的問(wèn)題按順序解決每一步改動(dòng)都能在下一份報(bào)告里看到反饋這才是打包優(yōu)化最踏實(shí)的打開(kāi)方式。最后再分享一個(gè)我在收尾時(shí)保留的習(xí)慣我把 webpack-bundle-analyzer 接進(jìn)了 CI 的一個(gè)可選任務(wù)每次發(fā)版前指定跑一次報(bào)告以 HTML 形式歸檔。幾個(gè)月后回頭翻就能看到項(xiàng)目體積的走勢(shì)。只要新引入的依賴讓體積明顯反彈下一次報(bào)告里立刻能看出來(lái)。這種讓數(shù)據(jù)持續(xù)說(shuō)話的做法比任何一次性的優(yōu)化都更管用。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
思思热在线播放| 99久免费视频| 五月天 婷 欧美亚洲| 日本激情91| 五月丁香色婷婷| 色综久久AV| 综合在线观看99| 99玖玖免费视频| 婷婷五月丁香综合桃花色网| 成人无码精品1区2区3区免费看| 五月丁香欧美综合免费视频| 狠狠狠婷婷五月综合| 狠狠色综合无线观看| 天天久久狠狠色综合| 思思久ren热| 免费无码毛片一区二区A片| 亚洲婷婷免费| 人人干AV| 99人人干| 日韩高清成人| 99精品国产在热久久婷婷| 美女五月天| 深爱五月日韩| WWW、日本色丁香、co m| 成人短视频在线观看| 呦呦视频无码播放| 99热精品网| 九九超碰人人| 六月婷在线| 天天爱天天操| 午夜69成人做爰视频| 99玖玖在线视频| 人人干人人干骚美女| 免费无码毛片一区二区A片| 操逼三区| 五月天婷婷基地| 婷婷六月开心网| 99人人干| 亚洲一个色| 成人午夜免费电影| 五月婷婷色啪| 久婷婷色| 婷婷丁香五月激情中文字幕版| 香蕉久久六月| 久久香蕉福利| 精品五月视频婷婷在线观看| 久久久久久草黄色片AV在线观看| 青青夜夜狠狠夜夜狠狠| 日日爱678| 欧美三级黄色片久久| Y11111111111少妇电影院| 久久在线视频免费观看| 日本色色视频| 七月激情六月婷婷综合在线播放| 天天综合区| 成人 在线观看国产| 97色在线| 99热九九热| 女人天堂AV| 亚洲天天| AV九九| 九九综合九九| 色综合色| 任我肏视频精品| 欧美A片在线视频免费观看| 婷婷丁香六月| 夜夜嗨一区二区三区直播内容 | 综合激情五月丁香| 久久 这里只有精品1| 99色看这里只有精品| 九九热这里有精品23| 国产伦理精品高清在线观看网站一区二区 | 丁香五月综合久久八| 色狠狠999综合| 色色色婷婷| 91视频人人做97| 九九亚洲综合| 一本道综合网| 婷婷大乡焦噜噜| 女同激情久久av久久| 日韩成人综合网| 色婷婷电影网| 日本狠狠干| 国产做爰视频免费播放| 精品亚洲日韩99欧美片| 26uuu国产色| 人人摸人人射| 婷婷激情人妻| 真实的国产乱XXXX在线91| 色站9/| 九九99九九99九九99视频网| 日韩无码人妻一区二区三区综合| 99精品国产在热久久婷婷| 91久久久久久久久18| 色综合伊人网| 狠狠干在线| 99色在线视频| 五月开心色| 九九热视频99| 婷婷中文综合网| 久久3p| eeuus五月婷| 天天操天天谢| 婷婷五月天在线观看| 亚洲色图欧美色图日本视频| 99精品热视频| 激情五月天com| 五月天堂婷婷| 亚洲蜜桃精久久久久久久久久久久| 97色精品视频| 小视频aaa久久久| 开心五月深爱婷婷| 又大又粗九一在线| 99热九九这里只有精品10| 久久66成人网站| 激情四射五月天| 成人在线二区| 一區四區歐美日韓| 天天日天天摸| 操碰91| 五月天艹天天| 激情视频网址| 欧在线一区| 五月丁香A片| 激情五月丁香六月综合AVXXXX| 色噜噜狠狠插综合| 人操综合| 五月婷婷综合色啪首页| 色婷婷亚洲| 国产亚洲99久久精品熟| 99re热视频| 2025年最新亚洲在线欧美| 五月婷丁香| 激情久久综合网| 激情网 五月天| 色婷婷97| 91婷婷在线| 免费五月婷婷网| 日本狠狠干| 五月天婷婷激情在线色图| 综合亚洲五月天| 色婷婷激情| 国产av一区二区三区| 五月天综合久久| 丁香婷婷色情社区成人小说| 欧美天堂婷婷日韩| 天天爽天天爽天天爽天天爽天天爽| 婷婷五月天激情五月天深爱五月天| 丁香香五月激情免费视频| 天天草天天摸| 婷婷五月天你懂的| 色欲五月婷婷| 91丨九色丨国产打屁股| 丁香六月婷| 久久草中文日韩欧美| 五月婷婷五月| 91黄址| 色五月成人| 91制片厂久久久国产电影| 久久激情综合| 日曰躁夜夜躁2026| www夜夜操com| 色欲色香,www,com| 天天综合色| 国产综合A片| 婷婷五月天亚洲精品| 欧美性生交XXXXX无码小说| 五月婷婷综合影院| 婷婷五月天激情小说| 婷婷玖玖五月天| 直接看的av| 夜夜AVV| 天天日,天天射,天天舔| 91精产一区三区免费观看| 色色色热| 五月天婷婷基地丁香| 国产成人高清| 色五月91| 日产精品一线二线三线芒果| 五月天婷婷小说| 亚洲熟女乱色综合亚洲网站| www.99热这里只有精品| 婷婷五月天免费| 超碰cap| www激情网| 99热热热天天人人人超超碰| 99re视频在线播放| 色婷五月天网站| 丁香五月婷婷影视先锋| 在线中文字幕视频| 五月花婷婷最新| 婷婷五月娱乐在线| 色99在线观看| 色婷婷色五月天| 无码人妻一区二区一牛影视| 五月丁香啪啪网| 五月丁香va| 热日韩欧美| 五月婷丁香亚洲| 丁香六月成人网| 操操自拍| 天天狠狠色| 久久激情天堂| 狠狠狠狠狠狠| 日韩在线一级| 奸逼视频| 五月天激情综合网俺也去| 涩五月婷婷| 99热这里有精品| www,婷婷五月天,com| av激情在线| 婷婷五月色| 99亚洲综合| 色婷婷五月综合色婷婷| 开心五月天激情网| 激情图片婷婷| 婷婷五月天香蕉| 七七九色| av超碰在线| 五月丁香六月激情综合| 激情综合色婷婷啪啪六月天| 综合色久| 97碰人人操| 国产精产国品一二三在观看| 日韩亚洲视频| 性色五月天| 天天婷婷操| 日韩一级网站| 丁香五月天日韩无码| 人妻久久久久久久 | 色婷婷狠狠干芒果TV| 色婷久久| 99久.| 欧美婷婷| 99啪| 99在线视频精品| 亚洲九九99精品视频在线播放| 久草性爱| 婷婷久久99| 大香蕉丁香婷婷| 超碰三级片| 丁香婷婷久久综合在线| 97色色色色色色色色色色色色色| 婷婷五月丁香五月丁香| 天天做天天爱天天爽夜夜揉| 五月丁香成人| 极品人妻VIDEOSSS人妻| 中文字幕精品无码一区二区| 色综合色色| 丁香五月婷婷香| 色婷婷狠狠色| 色婷婷色人人射| 思思热久在线观看视频| 99热 在线观看| 婷婷午夜精品久久久| 九九性视频| 激情五月天在线观看婷婷| 免费看片在线观看| 激情综合五月丁香六月婷婷| 五月黄色婷婷| 婷婷爱五月| 五月婷婷之综合激情在线| 国产露脸150部国语对白| 色色亚洲视频| 免费无码毛片一区二区A片| 久久这里有精品| 91偷拍视频| www.婷婷五月| 丁香六月久久| 日本久久精品| 激情五月黄色| 久久女人九九| 久久五月激情| www.天天干.com| 丁香五月激情综合| 五月激情天天干| 91成人品| 国产色色视频| 日产精品久久久久久久蜜臀 | 日本色色影片| 五月婷天堂视频| 婷婷激情综合色五月久久91| 欧美激情久| wwwxxx五月婷婷小说| 久碰视频| 丁香五月综合婷婷| 婷婷色五月天在线观看| 97碰碰人人| 色综合久| 五月婷婷久久爱| 欧美十二区| 久久五月综合| 很很操很很操| 欧美激情凹凸丁香网| 九色色| 久久机热这里只有精品| 超碰男人色| 天天干天天干天天干天天干天| 97久人人| 丁香五月婷婷综合视频| ji'qi'luan'ren'lun| 丁香综合婷婷五月天| 久久久久激情| 丁香婷婷五月份| 乱岳熟女50岁| 婷婷五月天激情网| 丁香激情五月少妇| 99热精在线九九久久保| 丁香五月在线播放| 激情六月婷婷| 99热这里有精品首页10| 激情久久天天| 色综合久久天天综合网| 123日本不卡在线| 97超碰在线免费观看| 国产激情综合| 狠狠操.COM| 婷婷五月天社区| 激情五月综合婷婷| 欧美在线视频免费播放| 五月婷在线色视频| 丁香六月婷| 九九久99免费视频| 婷婷六月天精品| 99re8在这里只有精品| 丁香色婷婷五月天| 香蕉久久六月| WWW,五月| 天堂在线观看视频| 99激情网| 99热这里只有精品免费观看| 全部老头和老太XXXXX| 色婷婷91| 色婷婷婷婷| 99成人| 噜噜色五月| 五月丁香色婷婷基地| 婷婷欧美激情综合| 人妻在线观看视频| 天天射综合网天天插| 99自拍视频网站| 丁香婷婷六月激情综合| 五月天狠狠| 久久九九激情五月天 | 秋霞电影一级黄| 天天插天天操| 色婷婷很很十八禁| 丁香五月天婷婷在线视频| 亚洲精品午夜国产va久久成人| 精品人妻伦一二三区久久| 九九热内射| 伊人99热| 色色五月婷婷| 伊人干综合| 26uuu亚洲| 俺来也狠狠| 激情丁香婷婷| 久久婷婷成人综合色怡春院| 日本操碰碰| 五月婷婷成人| 色色五月激情| 播五月开心婷婷欧美综合| 999热在线观看视频| 激情五月婷婷欧美极品| 精品香蕉99久久久久网站| 色综天天综合| 91狠狠综合久久| 五月色婷| 色99自拍| 7月婷婷六月丁香| 99性爱视频网站| 99热99精品在线观看| 天天激情夜夜干| 色色激情五月天| 九九蜜臀精品| 99热99在线| 丁香六月综合激情| 成片免费播放| 激情五月天之五月婷婷| 亚洲激情综合| 麻豆科斗777| 无码日本精品XXXXXXXXX | 精品一区二区三区四区五区六区介绍| www.婷婷| 色天天久婷婷| 亚洲国产黄色电影| 991国产精选视频在线播放下载| 亚洲精品又粗又大又爽A片 | 九九热国产| 婷婷WWW久久| 99爱最新免费视频在线观看| 亚洲无码影片| 欧美日本黄色| 99热香港| 国产亚洲精品久久久久苍井松 | 亚洲黄网AV| 丁香五月激情六月| 天天插操| 婷婷月综合| 婷婷在线播放av| 五月综合激情| 天天爱天天做天天| 99久久久国产大片| 色色色色色九九九九九| www夜夜| 中文字幕,综合,91| 婷婷丁香六月| 婷婷成人视频| 中文不卡一二三区| 97色精品视频| 婷婷五月天久久| 国产精品视频| 色五月天婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷 | 奇米网大香蕉| 丁香五月综合| 丁香五月婷婷网| 久热九九| 日日操夜夜操中国无码| 天天艹夜夜艹| 激情婷婷五月基地| 人妻爽爽爽久久久久久久久| 激情综合另类| 日本猛少妇色XXXXX猛叫| 综合婷婷五月丁香在线观看| 五月丁香爱婷婷深深| 大香蕉啪啪啪| 五月婷婷人人人操| 91人人爽久久涩噜噜噜| 玖玖在线资源视频| 特黄三级片| 色婷婷色综合久久精品V| AV成人在线播放| 99热这里有精品首页10| 色优久久| 天天日,天天插| 五月激情天天干| 99玖玖在线视频| 激情综合网激情五月婷婷| 午夜成人AV在线| 成 人 色 色| 九九热亚洲中文在线观看免费| 狠狠色婷| 国产成人AV不卡| 色色婷婷丁香| 蜜乳中文字| 丁香五月天激情网址| 97久久五月丁香婷婷| 亚洲精品无AMM毛片| 日本丰满久久| 无码激情AAAAA片-区区| 狼人婷婷久久| 婷婷五月天亚洲五码| 激情丁香六月| 99热免费18| 激情开心五月天| 久久婷婷五月综合| 91婷婷五月天嫩女| 久色欧美| 婷婷五月综合欧美在线播放| 91碰碰视频| 综合色视频| 婷婷综合视频| 大香蕉久久| 五月天婷婷影院影院观看| 婷婷综合一二三| 爆乳熟女-区二区三区| 久久精品一区二区三区四区| 99精品视频在线观看| 九九碰九九爱97| 14色综合婷婷| 99精品久久久| 狠狠狠狠狠狠狠狠| 天天日天天爽| 99热这里有精品| 99久久网站| 五月丁香综合激情| 国产亚洲精品AAAA片APP| 怡红院视频| 色婷婷五月综合在线| 夜夜资源站| 久9无码视频| 色婷婷色九月| 啪啪综合网| 精品人人操| 国产伦亲子伦亲子视频观看| 久久XX日本综合| 色综合久久久无码中文字幕999| 色婷婷丁香女女| 丁香五月天激情综合| 丁香五月激情婷婷婷婷在线观看| 天天爱综合网| 超碰成人电影| 丁香六月婷| 国产成人精品123区免费视频| 五月天激情小说| 超碰成人av| 久久丁香五月| 国产一级片| 99精品无码| 亚洲色网络| www.超碰在线| 日逼影音先锋男人资源站| 色婷狠狠| 婷婷丁香69精华| 九九sese| 熟妇高潮一区av| 色综合色色色色色色综合| 97碰成超视频免费视频| 大香蕉啪啪啪| 五月天婷婷色播综合在线| 色婷激情网| 人人视频人人干人人做| 夜夜操夜夜操| 51精品国自产在线| 另类激情码| 色呦呦美女| 五月婷精品| 婷婷色系婷色| www.久久99热地址发布| 久久久国产精品黄毛片| 丁香五月色五月| 丁香五月网络网络| 热99在线精品| 色婷青青| 丁香婷最新动态| 停停五月天激情网| 这里只有精品视频| www.超碰97| 91久久综合亚洲噜噜成人在线| 天天 青草 制服丝袜 在线| 亚洲色综久久五月| 26UUU精品一区二区| 色婷婷综合久久| 日本三级日本三级三级人妇四虎| 天天操夜夜爽| 成人丁香五月| 日韩精品999| 亚洲、热| 六月丁香网| 激情四射婷婷色色色| 天天艹夜夜爽| 亚洲成人五月天| 久久九九九九| 色色免费网战视频| 日本人妻伦在线中文字幕 | 人人天堂操| 婷婷免费视频| 青青久久五月天丁香婷婷| 丁香六月婷婷激情综合| 狠狠色97| 97日本在线| 丁香五月天av| 五月激情在线| 婷婷色综合| 99免费在线视频| 欧美日韩成人h| 国产精品在线视频| 伊人激情影院| 99热18| 亚洲熟妇无码乱子AV电影| 偷拍丁香九月激情| 99热国内| www久久久| 91色色色| 丁香六月| 婷婷久久精品| 丁香五月婷婷欧美激情-中文天堂最新版在线观看 | 99热在这里只有精品| 婷婷六月丁香五月| 91精品久久久久| 99免费视频在线观看爱| 99久久97| 激情婷婷网| 激情综合色婷婷啪啪五月天| 噜综合| 婷婷午夜| 国产超碰在线| 99热这里是精品| 91久久久久久| 激情网五月天| ,99视频久久| 97人人搞| 色情综合| 五月激情在线| 久久婷婷婷婷伊人| 六月婷婷操逼| 久久人人妻| 国产资源在线视频| 色色色色五月天| www.综合久久| 九艹在线| 五月天丁香六月综合| 伊人婷婷五月天| 丁香香五月激情免费视频| 99欧美| 玖玖精品资源| 月色色综合婷婷网| 91丨九色丨熟女| 综合激情五月丁香| 欧美成人AAA片一区国产精品| 99久久这里只有精品免费官网| 天天爽天天| 在线五月婷婷小电影| 久久久婷婷| 丁香五月98| 男人的天堂av俄罗斯热| 久久草中文日韩欧美| 97人妻碰碰碰久| 久热 91| 日韩成人综合网| 九九热再线九九视频免费在线观看| 99精品成人无码A片观看金桔| 久色网五月| 偷拍九九五月丁香婷婷| 思思热在线观看| 久久婷婷操| 狠狠婷婷日韩| 五月丁香综合| 大地资源色婷婷视频在线| 亚洲人人操| 狠狠插狠狠操| 五月丁香 久久久| 操逼综合网| 激情五月综合网| 久久这里99| 玖玖午夜视频| 4438亚洲欧美| 人人操99| 五月丁香六月婷婷综合网站| 五月色亭丁香| 97碰碰视频| 精品一二三区久久AAA片| 日韩三级高清无码| 5月色婷婷| 色射7856五月天激情四射| 婷婷丁香色五月| 五月激情六月婷婷| 99小精品| 久久性操| 色吧网91| 97久久视频| 婷婷丁香六月| 99思思热只有在这里看| 少妇丁香婷婷| 九九九九九九九九九九九九九国产精品| 夜夜操天天干| 九九视屏| 五月婷婷啪啪啪啪| hd五月婷婷在线| 色婷婷丁香| 婷婷色六月| 69超碰在线| 99无码黄色视频| 欧美婷婷五月| 丁香五月综合图片在线观看| 久久久久9| 九九久久高清| 奇米色大香蕉| 久久人人添人人爽添人人片αV| 六月丁香五月天| 99热亚洲| 99视频| 久久五月天激情| www.五月激情红色| 伊人六月无码视频| 欧美天天综合网站上去吧| 色色爽爽天天| 亚洲黄色精品| 久热精彩视频98| 日日操夜夜擼| 欧洲MV日韩MV国产| 亚洲乱码日产精品BD| 六月婷婷综合| 91性高潮久久久久久久久| 99ri国产| www99热| 激情九月婷婷| 另类图片天天影视在线观看| 97久久人人| 五月天激情图片网| 人人叉久| 六月婷婷香蕉| 9191avse| 婷婷激情五月综合| 思思热久久阴99| 国在线激情网| 在线VA视频| 月婷婷亚洲| ...婷婷国产成人亚洲日韩| 天天色综合色色色色色。| 亚洲丁香婷婷五月天综合色| 性爱在线播放av| 五月色丁香成人| 五月综合色| 色婷婷五月天天天天天| 天天做天天爱天天爽在| 激情婷婷五月天在线观看| 天天天天做夜夜夜夜做| 丁香六月婷婷综合啪啪| 天天爽天天爽| 久久这里只有精品热在99| www.婷婷| 五六月婷婷久久| 成人在线网站| www。狠狠干。com| 精品人妻久久久| 丁香五月综合在线观看| 婷婷成人AV| 色色色9| 日韩免费视频| 激情婷婷五月社区| 五月丁香好婷婷A片网| 亚洲va在线∨a天堂va欧美va| 99综合| 4438全国最大视频成人网站在线观看 | 狠狠干夜夜干| 四川BBB搡BBB搡多人乱亂| 色色色com| 色爱综合五月| 丁香色五月婷婷17C| 五月社区婷婷激情| 婷婷五月天av| www.狠狠| 超碰精品国产首页| 伊人久久激情图区五月| 九九机热| 99精彩视频| 91碰碰视频在线观看| 亚洲成人无码网站| 天天做天天干天天综合网| 丁香婷婷视频| 亚洲第一综合| 无码九九九九| 狠狠另类视频| 干一干xxxx| 国产国产乱老熟女视频网站97| 九月大香蕉| 手机在线日韩视频中文字幕| 夜夜夜夜操| 亚洲色婷婷| 欧美顶级少妇做爰HD| 日本精品干| 日在线V视频在线播放| 久久天堂婷婷五月| 涩涩涩,com| 人人操AV| 色五月天婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷婷 | 成人午夜无码视频| 99碰在线视频| 婷婷五月丁香五月天| 91丨九色丨高潮丰满日本| 亚洲五月天激情| 丁香婷婷婷五月综合色情| 五月丁香综合伦理片| www.精品99| 日本在线观看aaa 99| 亚洲日本激情| 91婷婷丁香五月| 人人肏逼视频在线一区二区| 噜噜综合网| 综合色五月| 91色碰| 婷婷丁香综合成人| 大地9中文在线观看免费高清| 亚洲成人av中文| 久色成人| 五月丁香六月婷| 激情综合网址| 色激情五月| 日韩AV在线免费| 丁香五月综合图片在线观看| 丁香激情网| 97超碰人人操| 站长推荐无码播放| 青996青| 婷婷丁香成人在线视频| 偷拍五月丁香| 超碰91在线| 99热国产免费| www.com色播五月天| 五月丁香花激情综合网| 99久久久99久久91熟女| 深爱五月月天| 九九热精品| 97色色综合| 天天操天天操天天操天天操天天操| 色婷婷狠狠禁18久久| 蜜乳A√| 粉嫩AV久久一区二区三区| 亚洲色精彩| 日日操天天操| 性爱在线播放av| 99玖玖在线视频| 久9久成人精品视频| 26uuu亚洲| 婷婷色基地在线看 | 成人免费黄色短视频| 六月丁香五月亭亭| www.lchjjc.com| 淫水导航| 中文成人在线| 一本婷婷丁香久久| 新激情五月开心五月婷婷五月丁香五月| 五月综合视频| 天天色天天舔天天爱天天爽| www.99操| 热99精品视频五月| 丁香婷婷综合精品六月初| 五月婷在线| 99re66热这里只有精品| 婷色五月| 99色播| 中文字幕有多少字| 99re在线这里只有精品视频首页| 亚洲a片免费观看| 日本色天堂| 狠狠操天天操天天操| 狠狠狠狠青草| 亚洲五月花| 六月五月婷婷| 在线中文av| 日韩av变天就操逼不卡区| 五月天综合| 久久婷婷丁香五月一二三| 婷婷五月天丁香综合网| 亚洲操操| 国产精品A片| 六月婷婷九月丁香| 另类天堂| 婷婷丁香一月| 丁香五月天婷婷91| 99热在线观看| 婷婷丁香人妻天天久久| xx久久| 人妻体体内射精一区二区| 激情深爱五月| 99视频内射三四| 婷婷五月天VI| 97在线综合| 97婷婷丁香五月| 日本丁香久在线| 中文字幕在线免费| 丁香激情六月天婷婷| 精品久久婷婷| 人妻内射一区二区在线视频| 噜噜国产| 天天天天天色| 1024操逼视频| 色综合五月天| 婷婷综合六| 激情久久久久久| 亚洲精级| 婷色五月天| 开心深爱激情网| 亚洲成色综合网站免费观看| 停停综合色色| 少妇高潮呻吟A片免费看软件| 俺去也五月天| 草AV9999| 337p大胆噜噜噜噜噜91Av| 丁香av网| 丁香激情五月| 超碰9| 亚洲aV写真天天综合网久久| 成人操呦av| 婷婷色吧| 日本偷拍九九九| 91碰碰碰| 五月丁香狠狠爱| 色五婷婷在线视频| 色丁香久久久| 激情精品久久| 99综合免费视频| 五月花激情网| 97人人干人人操| 99这里只有精品|v| 天天天操天天天日| 五月好婷婷| 五月婷六月丁| 99热777| 国产一区男女| 97婷婷丁香五月| 丁香五月激情综合在线观看| 99在线爽| 一个色的综合| 六月米奇色综合| 色五月婷婷五月久久| 色97综合婷婷天天色| 深夜婷婷五月丁香| 天天天天天操| 91制片厂久久久国产电影| 99re热视频这里只精品| 国产肥白大熟妇BBBB视频| .精品久久久麻豆国产精品| 久热婷婷| 精品国产一区二区三区四区阿崩 | 五月丁香六月激情在线| 六月婷婷中文字幕| 五月激情小说| 99年操人人爽| 99久久97| 97超级操操| 台湾无码A片一区二区| 日本啪啪网| 中文字幕成人| 五月婷婷深深爱爱| 噜噜噜色噜噜| 五月婷婷之综合激情| 五月天婷婷久久| 婷婷综合网| 激情婷婷五月天| 激情6月| www.久久9| 婷婷精品在线| 丁香五月色播中文在线播放| 欧美婷婷五月天综合| 婷婷六月啪啪| 99黄色性生活| 色婷婷成人做爰A片免费看网站 | 久久婷五月影院| 久久久五月婷婷| 激情小说五月天社区丁香 | 国产精品色色| 亚洲无码99| 色99综合色88| 色综合久久中文| 色七色九九| 婷婷丁香五月高清| 成人av播放| 成人综合网站| 射久久丁香五月| 台湾综合丁香五月蜜桃| 久热播这里只有精品| 五月天伊人久久久久| 五月婷婷啪啪| 99ri国产精品| 免费成人va| 六月婷婷久久| 青青草成人网| 国产91在线视频| 日韩中文欧美| 超碰1999| 26uuu欧美| 婷婷五月激情五月丁香五月| 开心六月丁香五月婷婷| 终合激情网| 狠狠干婷婷| 99偷拍视频在线日本| a69在线视频| 久久精品系列| 99热这里只有精品 搜| 色五婷婷在线视频| 免费做A爰片77777| 夜夜躁婷婷AV| av在线色五月丁香婷区久| 99久久婷婷国产综合| 五月天丁香婷婷视频网址| 日韩综合网络男女香蕉a片| 久色网五月| 99热网站| 狠狠色丁香久久婷婷综合五月| 噜色精品| 成人午夜无码视频| 婷婷丁香五月天色色| 婷婷五月中文在线| 日本一毛片| 精品九九久久| 五月六月激情婷婷| 91chinese在线| 五月婷婷,六月婷婷| 色婷綜合网| 热久精品| 91ncm视频| 99在线观看视频| 69超碰在线| 天天操夜夜啊| 97精品综合| 欧美性猛交99久久久99| 亚洲六月色| j五月香在线| 日日色五月天| 五月婷婷丁香| 欧美影院婷婷| 色婷婷五月在线| 大胆伊人久久| 情婷婷五月天| 久久九九激情五月天 | 9热在线观看| 丁香五月婷婷影院| 99性爱精品| 狠狠婷婷色| 婷婷六月激情啪啪| 丁香五月婷婷啪啪| 九九九精品视频免费观看| 婷婷九月激情| 97人人操| 激情五月丁香社区| 91久久综合| 97碰碰在线观看视频| 婷婷狠狠97| 成人丁香五月天Av| 久一网站| 午夜成人网站在线观看| 五月天丁香婷| 丁香五月影视| 激情九月综合| 五月丁香色| 九九国产精视频| 成人AV在线电影| 精品99久久久久成人网站免费| 人妻少妇色综合| 美女天天久久| 专区无日本视频高清8| 国产寻花在线| 五月天婷婷综合色| 婷婷丁香色情| 婷婷久久五月天中文字幕在线观看| 免费观看的婷婷五月视频在线| 国产黄色大片| 99免费在线视频| 久热中文字幕| 色播五月天激情| 就爱操www com| 色色综合网www| 色欲色香伊人| 操逼视频一区| 噜噜视频| 丁香五月宝贝激情网| 丁香五月婷婷图片综合| 六月丁香激情网| 插逼综合网| 大香蕉综合在线| 襙逼网| 丁香六月天婷婷| 亚洲天堂啪啪| 美女va| 色色综合网www| 亚洲精品99| 九九国产精视频| 五月婷婷香蕉视频| 五月丁香亭亭| 天天激情综合| www。五月,com| 99久久婷婷五月综合| 五月天狠狠网站| 婷婷五月在线影院| 99色色网| 婷婷五六月丁香| 免费V片在线| 五月天婷婷久久| 婷婷六月中文字幕| 六月色激情| 99操99| 色婷婷视频在线| 大香蕉伊人久久| 婷婷五月天性色| 久热91精品| 五月丁香六月婷婷不卡免费无码| 综合久久综合综合| 99成人在线观看| 久久性爱视频这里只有精品| 丁香婷婷五月天激情四射| 牛牛热这里只有jingpin| 日日夜夜天天| 99在线视频精品| 99九九综合久久九九| 日韩限制级大尺度黑料泄密大尺度视频一区二区在线观看 | 久色视频| 欧美激情综合五月色丁香| 思思热久久阴99| 亚洲成人中文字幕| 99超级碰免费视频| 人人草人人爱| 狠狠999| 日本色天堂| 久久综合66| 99热这里有精品| 天天色天天日天天舔| 激情六月五月婷婷综合网| 亚洲免费观看高清完整版AV线| 情欲禁地| 99热综合| 色情成人五月天| 丁香六月毛片| 97成人丁香婷婷| 无码橾| 综合色七七| 色婷婷电影网| 爆乳熟妇一区二区三区爆乳照片| 丁香六月视频免费观看| 天天插天天狠| 9久久久久| WWW、日本色丁香、co m| 无码少妇高潮喷水A片免费| 成人在线网| 五月丁香综合网| www.亭亭五月天| 五月婷婷熟女| 性色欲情 网站| 久久与婷婷| 99视频在线观看视频| 婷婷大香焦| 2018国产大陆天天弄| 91日韩在线| 欧美99视频| 亚洲狠狠婷婷| 玖玖婷婷色欲| 日本不卡一区二区三区| 久久这里只精品| 亚洲精品成人| 中文资源在线a | 91丨九色丨熟女| 婷婷丁香18| 五月伊人婷婷| av中文网站| 亚洲久热无码| 俺去也在线www色官网| 丁香五月激情月| 一本久久亚洲五月婷婷| 精品色情一区二区三区四区| 五月丁香啪啪| 天天色月| 99er这里只有精品视频| 欧美色图天堂网| 婷婷啪啪| 日韩婷婷五月| 婷婷五月天受日本法律保护| 欧美婷婷| 精品国产va久久久久| 性色欲情 网站| 久久久思思热| 五月丁香怕啪啪| 午夜理论片最新午夜理论剧| 激情综合五月激情| 欧美综合激情五月丁香| 九九sese| 亚洲婷婷婷| 五月天玖玖狠狠色色| 色5月婷婷| 伊人啪啪网| 免费视频无码| 婷婷九月激情| 天天操天天操天天操天天操天天操 | 五月婷婷中字在线| 国产在线6| 色色aⅤ網| 五月情色天| 日本3级片一区2区| 九九综合精品| 色色婷婷丁香| 婷婷五月在线影院| 99ri6在线视频| 人人干女人| 婷婷97| 99精品在| 天天爽夜夜爽夜夜爽精品视频| 能看的av| 婷婷丁香人妻天天爽| 色婷婷成人做爰A片免费看网站| 琪琪色综合网站| 极品九九九九九九| 久操大香蕉| 五月丁香av在线| 亚洲a色| 久久五月网| 99re在线播放| 99久久久精品| 黄网网站在线播放| 五月天婷婷色播综合在线| 欧美日韩aaaa| 午夜丁香| 69凹凸成人综合网| 色婷婷色九月| 最新激情五月天| 激情图片五月天| 午夜精品人妻无码一区二区三区 | 色五婷婷| 激情性爱五月| AV九九| 九九久久偷拍| 色色婷婷丁香| 五月丁香激情深爱婷婷| 九九re精品视频在线观看| 天天日天天色| 婷婷成人在线| 色五月丁香总合网| 这里只有精品免费| 99碰碰| 美国不卡视频| 天天噜天天爱| 国产.亚洲.欧洲视频在线| 狠狠精品干练久久久无码中文字幕| 丁香婷婷久久综合在线| 九九热99re8热免费观看 | www,五月丁,com| 玖玖无码中文| 99色在线观看视频者| 久久久久9999| 亚洲综合色色色| 五月丁香综合| av在线免费网站 | 狠狠香婷婷五月| 婷婷色导航| 日本色色影片| 婷婷亚洲日本| 蜜臀99精品| 深夜婷婷 丁香| 婷婷色激情网| 激情五月天网| 五月天婷婷丁香成人网| 婷婷五月天最新综合你懂的 | 99久久久久久久| 99色播| 天天日,天天干,天天操| 久久一品区| 丁香五月天啪啪激情综和网| 人人操av| 99A级片| 五月天婷婷无码视频| 夜夜穞天天穞狠狠穞AV美女按摩| 午夜爱爱网站| 丁香五月香蕉| 天堂久热| 欧美综合丁香网| 五月婷婷激情| 色色爽爽天天| 六月激情综合| 五月丁香日逼| 激情网五月婷婷| 强壮的公次次弄得我高潮A片日本 | 91偷拍视频| 五月久久婷婷天堂视频| 亚洲AV电影美洲AV电影| 色五月六月婷婷| 2018国产大陆天天弄| 婷婷五月激情网站| 婷婷五月天影院| 夜夜爱伊人| 色五月亚洲| 91热手机在线| 九九99久久| 久久无意婷婷| 色五开心五月五月深深爱| 婷婷无五月无码视频| 五月丁香六月婷婷中文版| 日日夜夜天天| 欧美久草在线日本一级特黄大片做受9在线观看韩国电影《两个女人》未删减-毛片 | 成人婷婷色综合| 亚洲尤物在线| 爱爱网址9| 国产一级婬片毛片| 成人在线观看国产| 久色五月婷婷综合| 这里只有精品96| 九九热在这里只有精品| 亚洲AV在线免费看| 激情小说之五月| 婷五月天影院| 日日艹思思热| 97人妻人人| 五月婷婷综合丁香视频| 五月五月婷婷| 五月色婷婷中文字幕| www.激情| 大香蕉人妻| 亚洲婷婷丁香五月视频|