免费国产精品自在自线-91精品国产色综合久久久浪潮-99热久久免费频精品-国产精品国模在线观看-久久亚洲国产精品成人?V秋霞-久久国产一级A片免费播放-亚洲国产欧洲综合97久久-久久国产白嫩美女呻吟高潮

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色看| Blackedraw视频一区二区| 99视频在线观看欧| 久久九九99| 天天艹夜夜爽| 激情五月天婷婷五月天| 99惹精品视频| 婷婷色五月激情| 丁香五月成人自拍| 色情激情五月婷婷| 大伊香蕉精品视频在线| 日本综合久久| 成片免费播放| 大香网伊人久久综合| 五月婷婷亚洲色视频| 99热网址| 只有精品在线观看| 久久天堂色| 98色花堂98t.R| 性爱先锋AV| 丰满少妇猛烈A片免费看观看| 丁香欧美| 色色婷婷丁香| 97超碰99热99| 九月丁香婷婷| 天天综合网站| 丁香五月婷婷激情123| 99色天堂| 91久久久久久| 色播婷婷五月天| 99热99精品| 狠狠综合网| 五月天婷婷丁香社区| 五月久久| 久久精品五月天| 4399精品一区二区| 懂色av蜜臀av粉嫩av永陈冠希| 婷婷六月激情综合| 996re热精品视频| 教师性爱毛片| 亚洲视频无| 一本婷婷丁香久久| 一级性爱大片| 26UUU欧美激情一区二区| 婷婷色五月色| 先锋五月婷婷丁香草草| xxxx五月天色色| 色播五月婷婷| 99噜噜| www 五月天 com| 先锋资源91| 亚洲精品国产熟女久久久| 色综合色综合色综合色综合| 天天操天天操天天操| 丁香五月婷婷av影院| 伊人激情| 国产做爰视频免费播放| 91窝窝| 大香蕉婷婷五月| 五月天婷婷色播在线网| 最新热中文字幕| 9在线9在线婷婷在线国产| 欧洲综合视频| 依人大香蕉| 欧美搡BBBBB摔BBBBB| 无码激情AAAAA片-区区| 91人人妻人人操| 精品亚洲日韩99欧美片| 色六月天天激情综合网| 丁香色综合| 综合激情五月天六月婷免费视频| www.91在线观看| 狠狠久久婷五月| 六月激情丁香一道本7777| 婷婷五月天激情小说| 青草五月天| 99热99精品在线观看| 91久久久久久久| 9色在线视频精品观看| 亚洲精品久久久久久久久久吃药| www.操.com| 婷婷五月天影院| 天天日天天操天天干| AA丁香综合激情| 色欲婷婷五月天丁香| 九九热10| 色五月婷婷天天操夜夜操| 影音先锋男人站,影音先锋男人色资源网,影音先锋AV最新资源站,影音先锋AV资源 | 五月丁香色色网| 大香蕉婷婷| 久久小视频| 久久久宗合视频88| 九九色中文| 视频免费精品免费精品免费精品免费精品免费精品免费精品免费99 | 亚洲成人网站在线观看| 综合深爱五月| 丁香六月婷婷综合| 亚洲无码激情| Jh7Uf088VHafNm| 六月天婷婷| 久久99网| 成人版视频在线观看| 热99热| 99热这里都是精品| 成人va在线播放| 99碰碰视频| 欧洲亚洲精品| 日本久久性| A久久| 99热免| 婷婷开心激情五月激情网| 丁香五月激情六月综合| 六月色国内综合| 日日狠夜夜狠| 99精色| 婷婷色五月综合| 五月婷婷六月奇米网丁香| 婷婷五月天激情综合| 99热精品网| 天天天操天天天爰| 天天久久综合| 99这里| 开心激情五月天网| 五月综合激情| 综合久久婷婷| 极品精品一区二区三区在线| 色玖玖网| 另类精品视频在线观看| 五月丁香婷婷在线综合蜜桃| 伊人婷婷激情| 日韩中文字幕| 91精品久久久久久77777| 99热99热不卡| 春色激情| 99色热视频| 思思精品视频| 人妻狠狠操| 麻豆雪千夏| 中文AV网站| 婷婷爱综合| 另类专区在线观看| 欧美综合123区| 日本VA视频| 中文字幕中文有码在线| 538久久| 五月亭亭六月天| 激情综合色婷婷啪啪六月天| 五月婷婷六月丁香玖玖玫瑰91| 少妇出轨做爰高潮A片| 这里只有精品视频222| 亚洲色爱综合| 大胆伊人久久| 丁香婷婷激情六月五月开心| 天堂网啪啪| 亚洲成人在线五月天| 日本女色人人| 五月婷婷在线观看| 超碰A V在线| www色中色综合| 7EzOBIhNq85TO| caopeng超碰| 4399成人黄A片| 婷婷狠狠18禁久久| 九九热99视频| 日日干天天| 五月丁香啪啪啪啪| 色婷五月天| 九久9精品| 亚洲AV网址| 六月丁香狠狠爱| 五月婷婷激情网| 无码一级片| 天天激情| 99久久99久久| 久久婷五月天| 婷婷网五月| 国产视频色色色色色色色| 丁香五月婷婷动漫视频| 人人摸人人干| xx久久| 99九九热在线观看| 久99热| 久久黄色免费视频| 97色一二三| 天天操夜夜橾| 大香蕉五月天婷婷丁香91| 玖玖婷婷综合| 日本在线免费中文com.| www.久操| 亚洲色网络| www.激情五月天.com| 风流少妇A片一区二区蜜桃| 色婷婷影音| 色欲色香,www,com| 99热国产这里只有精品| 99视频精品全部免费观看| 久草婷婷在线| 五月婷婷啪啪啪| 久久这里精彩免费在线观看| 色哟呦av| 香蕉综合网| 中文字幕在线免费观看视频| 在热视频精品| 亚洲色啪| 日噜噜色| 99久久九九| 激情五月天色爱| 色婷婷影音| 色欲av伊人久久大香线蕉影院| 99热99网| 丁香花婷婷五月天| 深夜婷婷 丁香| 免费V片在线| 99re这里有精品手机在线| 婷婷五月综合色中文字幕| 欧洲不卡视频| 天天色综合网1| 九九九九大香蕉| 九九热在线精品视频| 婷婷五月天日日日干干干| 影音先锋91资源站| 日韩AV无码影片| 青青草原伊人网| 五月天婷五月天综合网小说首页-五月天激激婷婷大综合,婷婷亚洲综合五月天小说 | 日韩无码成人电影| 久久色9| 亚洲五月天第一综合干| www.yw色| 丁香五月色情av| 婷婷操逼| 婷婷五月天在线视频网站| 思思99热热热99| 九月性爱网| 99啪啪| 五月丁香在线综合| 欧美色小说婷婷| 久久久久亚洲AV无码网影音先锋| 大香蕉丁香五月| 天天激情站| 五月激情六月综合| 久久aaaa片一区二区| 国产成人AV在线| 亚州男人天堂婷婷五月| 成人无码精品1区2区3区免费看| 泰州成人视频| 丁香五月激情无码视频| 五月丁香婷婷激情在线| 天天做天天爱天天爽夜夜揉| 日本啪啪网| 色五月美女| 开心五月网| 天天拍天天操| 人人摸人人摸| www色五月天| WWW·天天操·视频?| enecarbon-materials.com污K127封锁请涟系@wip1688 | 婷婷五月天美女| 天堂五月婷婷| 丁香五月天天| 婷婷性爱综合| 97日日碰碰| 国产免费性爱| 怎么样可以看免费的一级av| 风流少妇A片一区二区蜜桃| 日本99热| 五月丁香婷婷综合网| 色五月中文网| 综合色色婷婷| 色在线99| 国产精品成人AV在线| 天天综合网网欲色| 79色色色色| sewuyue第四色| 热99国产精品| 另类色网| 亚州欧美国产久精国产99综合视频| 日韩高清成人| 99在线精品观看99| 五月丁香六月婷婷精品| 激情久久四色| 久久婷五月综合色| 九九婷婷五月天影视| 亚洲激情99| 丁香六月婷婷综合激情欧美 | 色婷婷综合五月| 婷婷5月色| 91久热| 欧美 日韩 成人在线| 超级碰碰碰碰视频| 黄网免费看| 色婷婷免费视频| 亚洲色图五月丁香| 婷婷综合激情| 多精窝99在线视频| 五月WWW| 这里只有精品在线看| 热这里| 丁香五月第四色88| 国产欧美va| 丁五月激情视频免费| 色色com| 久久婷婷视频| 国产午夜一区二区三区| 99精品视频在线观看| 人妻内射一区二区在线视频| 91狼友视频在线观看| 影音先锋男人av资源站| 日本丁香久在线| 精品在线网站| 久色成人| 激情五月天综合婷婷网| 97人妻碰碰中文无码久热丝袜| 婷婷金品综合视频| 夜夜嗨一区二区三区直播内容| 色五月色综合| 久久婷婷五月综合成人d啪| 99爽视频| 情情五月天色| WWW.桔色成人.COM| 五月天伊人| 极品人妻VIDEOSSS人妻| 丁香五月ⅤA久久久| 婷婷激情在线| 九九成人精品| 色婷婷88| 国精产品一区一区三区免费视频| 五月丁香激情啪啪网| 97在线视频人妻九色| AAAA亚洲| 亚洲综合激情五月久久| 色人久久| 岛国午夜视频| 99超在线| 激情五月丁香六月综合AVXXXX| 五月婷婷激情综合网| 丰满少妇猛烈A片免费看观看| 六月婷综合| 色色九九五月天 | 亚洲热热视频| 国产女人十八水真多1| 999精品乱码77777| 久久九精品| 久久性爱视频| 五月丁香啪啪激情| 亚洲V国产V欧美V久久久久久| 久久婷婷丁香花综合网| 深爱丁香激情| 梁铮版《蜘蛛女侠》在线| 操人精品| 就爱日五月天| 久久AAAA片一区二区| 97影院一级片| 激情五月天婷婷在线网址发给我| 激情五月www| 激情五月天在线观看婷婷| 91丨九色丨老农村| 4399精品一区二区| 桃色五月婷婷| 疯狂做受XXXX高潮A片动画| 91婷婷色五月| 狠狠99| 另类综合婷婷五月天欧美视频| 五月天婷五月天综合网小说首页-五月天激激婷婷大综合,婷婷亚洲综合五月天小说 | 久久这里只有精品热在99| 第四色五月天| 99热在线成人网站| 色五月视频,小说| 婷婷丁香六月影视| 激情六月丁香综合| 婷婷丁香视频在线观看免费| 色一情一乱一乱一区91Av| 色五月大香蕉婷婷| 天堂久久大香蕉| 91大操| 艹B高清无码| 激情综合亚洲| 色丁香五月婷婷| 亚洲精品午夜国产va久久成人| 激情网婷婷五月天| 色色色热热热| 五月婷婷六月激情| 2017人人操| 狠狠色狠狠操| 人人草人人舔| 婷婷色在线视频| 色五月天成人| 婷婷五月天伊人| 噜噜网免费视频| 99亚洲无码| 日日夜夜噜噜爽爽| 国产成人+亚洲+欧洲| 天天草天天日| 久久66成人网站| 五月天狠狠干| 99久.| 国产成人AV在线播放| 大香蕉久久婷婷精品综合| 91色欲综合| 欧美婷婷综合网| 91碰九色| 六月丁香停| 骚五月婷婷| 日韩超碰在线| 伊人春天av| 婷丁五月| 丁香婷停五月激情综合深爱| 六月天丁婷婷| 久久a热| pacopacomama 070722_670 素人奥様初撮りドキュメント 103 大久保純子 | 9精品一区| 极品五月天| 99在线综合视频| 超碰京东热av男人的天堂| 五月香蕉网| 97碰人人操| 991精品在线视频| 99re热在线视频| 九九色热| 五月综合激情综合久| 久久这里只有国产视频| 日本狠狠色| 99熟女啪啪视频| 色伊人婷婷| 开心激情站| 精品夜夜澡人妻无码AV| 婷婷色综合中心站| 天天肏在线观看| 视频这里只有精品| 五月激情丁香| 婷婷激情视频| 五月色综合| 色婷婷五月综合激情中文字幕| 波多野结衣成人作品在线| 日本精品九九九| 91chinese在线| 激情五月综合免费| 99久在线精品99re8热| 婷婷激情性爱| 江苏少妇性BBB搡BBB爽爽爽| 色婷婷在线影院| 7777激情基地| 深爱激情av| 国产精品爽爽久久久久久| 五月婷婷三级| 久777| 97碰碰在线看视频免费| 久久机热这里只有 | 嫩模草| 99啪啪网| 五月丁香婷中文| 天天天天天天操| 亚洲热综合| 丁香五月之久操视频| 久久婷婷夜| 婷婷成人网五月天| 五月婷婷,六月丁香| 五月天婷婷影院| 精品少妇人妻AV无码专区偷人 | 丁香伊人综合| 五月婷婷啪啪网| 日韩成人无码| 六月婷婷激情图片| 久久久久思思热| 色五月色五天色情网| 国产精品久久久爽爽爽麻豆色哟哟| 伊人玖玖综合| www,色中色| 99热碰碰热| 丁香狠狠干| 色啪综合| 亚洲色网址| 五月丁香影视| www.henhenl| 欧美综合五月丁香六月婷| 亚洲av综合网| 51精品国内探花| 婷婷丁香视频在线观看免费| 五月婷婷日| 人妻无码视频网| 网色99| 丁香六月情| www.五月天| 五月丁香综合激情网| 天天综合网亚洲综合网| 五月丁香激情啪啪| 另类A片| 色婷婷激情五月天| 激情内射人妻1区2区3区| 欧美在线97| 久久A区B区| www.婷婷| 欧美婷婷六月丁香综合色| 狠狠穞A片一區二區三區| 影音先锋91网站在线观看| 色色五月天婷婷| 欧美婷婷五月天| 91 欧美| 天天干,天天舔| 久久婷五月综合| 99热黄| 亚洲综合干| 天天干夜夜谢| 性爱网五月天| 激情人妻综合| 99视频91| 久久九九色| www.玖玖九| 干婷婷五月天| 思思热在线视频精品| 成人在线网址| 99热综合网| 麻豆精品| 五月丁香五月综合欧美| 久青草大香蕉| 色在线视频网2025| 99色综合久久| 五月亭亭综合五码| 99九九精品视频推荐| 五月激情开心婷婷| 国产精自产拍久久久久久蜜 | 国产精品操| 亚洲综合五月天| 久久精彩视频99| 思思久热| 97男人天堂| 婷婷激情五月天小说校园| 亚洲欧美日韩VIP| 婷婷五六日| 激情五月丁香五月| 色五月久久成人婷婷| 色偷偷五月天| 凹凸7777操操操| 丁香五月天色婷婷| 五月天色狠狠| 国产精品人成A片一区二区| 第四色婷婷日本| 日本99视频| 99热 这里只有精品 国产 日韩| 婷婷丁香五月综合| 九九蜜臀精品| 久久A V无码视频| 婷婷五月天亚洲综合网| 色五月丁香婷婷| 久久中国毛毛片爱久久| 久久99大全| 91久久综合亚洲鲁鲁五月天| 色色五月天婷婷| 亚洲成人网无码| 婷婷午夜| 欧美婷婷五月天综合| 伊人婷婷99热精品| 欧美这里只有精品| 欧日韩成人| 丁香六月激情综合| 亚洲综合网激情小说| 9精品久久999| 婷婷伊人网| 91丨九色丨白浆| 婷婷97| 综合99在线| 五月丁香花成人社区| 五月丁六月香| 天天综合网91| 五月天综合| 五月婷婷开心六月激情小说| 色综合久网| 99热在线精品播放| 丁香五月AV综合| 色色色色色色综合网| 99国产这里只有精品| 伊人玖玖网| 丁香婷婷色五月| 66久久视频在线| 99re资源在线视频导航| 婷婷五月丁香欧洲| 婷香五月网在线| 久久这里只有精品视频15| 激情网婷婷五月天| 操操操av| 丁香色五月AV在线| 欧美日韩aaa| 婷婷五月天熟妇| 最新日韩久热免费视频看看| 久久激情视频| 99热国产这里只有精品| 丁香婷婷激情综合五月激情 | 亚洲成人在线播放| 97夫妻超碰| www.99热在线| 襙比视频| 香蕉操亚洲| 亚洲欧洲中文日韩久久AV乱码| 99热费观看| 久久激情五月| 五月婷护士| 九色视频91疯狂| 人妻久久久久久久久妻久久久久| 婷婷丁香五月91| 免费视频WWW在线观看网站| 五月天天天色| 开心深爱五月天| 五月婷婷之综合激情在线| 久久这里只有精彩| 久久久免费图片视频| 五月天婷婷在线AN| 这里只有精品在线观看视频| 五月天婷婷久久日| 蜜乳人妻一区二区三区| 五月丁香影视| 在线天堂9| 激情www.98com| 嫩草视频在线观看| 九九久久腿| www.婷婷五月天| 丁香五月天激情免费在线观看AV777| 狠狠色丁香五月婷巨| 婷婷久久天堂网| 图片区 小说区 区 亚洲五月| a久久| www.日韩艹| 亚州色婷婷| 丁香五月婷婷激情蜜桃| 国产伦亲子伦亲子视频观看| 人妻激情综合| 五月婷婷综合在线视频小说| 五月天影院婷婷在线观看| 亚洲成人AV在线观看| 丁香五月欧美婷婷| 被强行糟蹋的女人A片| 婷婷月综合| 免费观看欧美成人AA片爱我多深 | 91碰在线| 黄色五月婷| 亚洲网综合在线| 性综合网| 五月色网| 97碰碰视频| 丁香六月激情综合啪啪| 五月天综合区| 婷婷五月天伊人在线| 任我肏| 成人资源在线| 综合激情九月婷婷,激情综合婷婷中文字| 狠狠色色| 五月天com| 操操人人| 日韩色五月| www夜夜| 伊人五月丁香| 五月丁六月婷| WWW.桔色成人.COM| 我爱婷婷五月天综合88| 激情婷婷综合| 婷婷亚洲激情在线观看视频| 丁香五月天无码AV| 久久三级视频| 97综合在线| 色六月婷婷| AV色婷婷| 欧美五月婷婷| 婷色五月天| 综合激情在线| 六月丁香av| 大香蕉久热| 一起草性爱不卡视频| 99热碰碰热| 99九九玖玖| 在线成人视频免费| 夜夜爱伊人| 五月综合激情| 欧美99视频| 91丨九色丨熟女|老版| 激情第四色| 五月天综合网| 秋霞A V毛片| 久草大| 丁香五月电影| 可以看的av网站| www激情| 99九九久久| 天天插天天干| 超碰在线caop| 中文AV网站| 在线不卡的视频| 91久久国产综合久久| 日韩操女| 婷婷午夜精品久久久| 婷婷激情综合| bbwcuckold精品熟妇| 天天拍天天做视频| 人人干Av| 五月婷婷啪| 婷婷99狠狠| 综合久久影院| 丁香五月成人| 日本人人超碰| 色色九区| 爱射综合| 五月丁香六月婷婷不卡免费无码 | 色婷婷婷av | 能看的AV| 久色资源| 《亚洲操B久久免费在线观看,亚洲操B久久在线播放》在线播放 - 高清资源 - 97 | 日本A片一区| 中文字幕激情综合| 无遮挡国产高潮视频免费观看| 婷婷丁香中文字幕| 九月激情综合婷婷| se99高清无码| 99视频一区| 大香蕉久久婷婷精品综合| 激情五月婷婷| 色一色综合| 欧美超碰人人| 天天综合色丁香| 九九热视频免费| 久久婷婷五月综合色丁香| 日日杆天天| 婷五月天影院| 99熟女视频| 六月丁香婷婷网| 婷婷激情六月| 婷婷五月天成人网| 超碰中文字幕在线| 五月婷婷丁香啪啪| 色色色免费视频| 丁香婷婷大香蕉| 亚洲字幕AV一区二区三区四区| 亚洲在线成人| 这里只有视频精品| 亚洲美女网Va| 熟妇无码乱子成人精品| 极品九九九九九九| 五月婷六月综合在线观看| 婷婷干五月综合在线播放| 婷婷色导航| 大狠狠在线| 久色资源| 久久 婷婷 五月天| 色色色色色色网站| 五月婷婷操操| 亚洲综合新99视频| 亚洲欧美婷婷五月色综合| 亚洲啪| 婷婷丁香五月激情中文字幕版| 99干日本| se99热久久一本| 激情五月天色婷婷综合| 日本欧美成人片AAAA| 无码人妻激情| www.久久爱.com| 色婷大香蕉| 色婷婷丁香中文在线播放| 色五月网址| 色综合九九| 五月天婷婷社区| 被强行糟蹋的女人A片| 欧美内射AA| 天天激情视频| 大学生高潮无套内谢视频| 二色av| www.射伊蕉婷婷| 无码色综合| 天天色综合网吨吧| 9色资源在线| 婷婷五月天色综合翘| 99这里只有精| 色婷婷免费观看| 成人综合视频在线| 97偷拍在线视频| 丁香成人视频| 婷婷99狠| 人人摸人人搞| 亚洲成人av在线观看| 思思热久久久在线| 97 天堂| 99久久综合精品五月天| 国产精产国品一二三在观看| 六月丁香深深爱| 99精品久久| 亚洲五月天天| 色婷婷成人做爰A片免费看网站| 99高级会所久久| 91性高潮久久久久久久久| 狠狠狠婷婷五月综合| 人妻AV在线| 婷五月丁香俺| 激情综合在线观看| 色色五月天婷婷| 婷婷91| 夜夜躁狠狠| 成人国产欧美大片一区| 俺也去综合| 91av色色乱视频| 成人精品亚洲性爱| www.日韩国产| 91精品久久久久久77777| 五月天婷婷综合久久| 六月丁丁香| 最新精品视频99| 一区二区成人电影免费播放| 深爱激情五月婷婷| 丁香婷婷五月人体| 五月婷在线| 婷婷六月丁香在线| 操大屄五月天视频| 综合久久五月天| 五月婷精品| 99热免费| 狠色色狠网| 99热久草| 免费视频无码| 亚城区在线| 五月天婷综合| 日日夜夜天天| 五月激情五月婷婷五月天在线| 九九九九成人| 欧美人人操| 日日干干天天干| 五月丁香亭亭| 夜夜骑天天操| 婷婷欧美色| 久久人妻少妇嫩草AV| 婷婷丁香五月亚洲17cao| 日本三级中国三级99| 99精品偷自拍| 久久九九免费视频| 欧美狠狠草| 五月婷婷婷色| 狠狠色成人影片| 夜夜操少妇| 五月 成人 婷婷| 婷婷免费视频| 婷婷深爱五月天在线| 五月丁香综合中文| 色婷婷导航| 亚洲美女网Va| 色六月天天激情综合网| 狠狠色丁香婷婷五月| 色色99| 婷婷成人视频| 天天在线久久综合 | 天天揷综合网| 久久99精品久久只有精品| 激情婷婷六月| 婷婷丁香五月天综合AV| 美女久久婷婷| 色婷视频| 五月丁香婷婷激情澎湃四射| 欧美极品999| 五月婷婷六月综合| 丰满少妇乱A片无码| 东京热伊人| 亚洲AV成人无码久久精品老人法拉利| 久久99热只有精品| 九伊人网| 九月婷婷综合在线| 99婷婷| 色五月丁香五月| 99色热视频| 五月色网| 久99久在线观看| 性爱111111| 三年高清大片免费观看国语| 日本色99| 中文字幕成人影视| 另类小说激情五月天| 另类图片 五月激情| av婷婷丁香 六月| 日韩欧美成人片| 視频福利乱色| 综合久久五| 亚洲三级无码| 91天天操天天干天天射| 免费啪啪亚州视频| 91视频综合网| 亚洲色模骚货| 成人性爱无码| 婷婷丁香五月天亚洲| www.日韩艹| 五月天第四色开心色播| 華人性愛AV在線| 久久婷婷青草五月天| 久久久久久99精品无码| 美欧成人视频| 丁香五月成人自拍| 五月丁香色色色| 丁香五月天激情综合| 梁铮版《蜘蛛女侠》在线 | 老司机伊人| 色五月首页| 夜夜操狠狠操| 五月天婷综合| Va另类视频| www.射伊蕉婷婷| 人妻第九页| 99九九在线视频| 五月天成人手机在线视频| 99热热这里只精品996小说| 丁香五月天视频| 日本爆乳片手机在线播放| 丁香五月天色| 五月天伊人综合| 麻豆AV一区二区三区| 婷婷久久五月天丁香| 狠狠色噜噜狠狠狠888了| 91婷色| 五月丁香六月停停停| 色吧综合网| 日韩AAAAAAAAAAA片| 精品一二三区视频立| 激情文学第四色婷婷丁香五月| 国产高清av黄色看片| 色综合久久99色| 91大屁股| 久久女婷| 美国不卡视频| 色天堂婷婷| 亚洲视频99| 婷婷综合一二三| 日本九九热| 激情q青青草在线婷婷| 9 9 9色色| 丁香五月天成人| 五月丁香六月婷婷网| 色噜噜狠狠一区二区三区| 欧洲亚洲欧洲99久久| 色婷婷久久| 97五月久久丁香婷婷| 色婷婷色综合久久精品V| 啪啪啪综合网| 99综合| 色5月丁香婷婷| 人人摸人人干人人做| 五月丁香综合激情在线观看| 欧美日韩成人免费在线| 亚洲免费av观看| 婷婷五月天啪啪| 丁香网五月网| 激情综合自拍五月婷婷色五月| 99 re视频一区| 色五月婷婷1| 任我干视频在线观看| 欧美成人精品A片免费一区99| 欧美在线操| 99热精品在线观看| 激情综合网五月激情网| 欧美性爱特黄一级aaaassss| 色婷婷久久综合久色| 超碰成人在线观看| 九九综合色综合| 中文字幕成人网站| 日韩成人无码| 双性美人被调教到喷水A片| 狠狠色综合网| 久久综合五月天| 天天色,天天日,天天做| 色狠狠色噜噜噜a天堂一区| 99 这里只有精品| 伍月婷婷免费视频| 五月色视频| 天天噜天天插| 国产激情综合| 91精品久久久久久77777| 人人操女人| 丁香五月777| www.9797国产| 丁香五月婷婷大香蕉| 97碰碰碰| 日韩成人综合| 亚洲操B视频| 超碰a女人的天堂| 日韩大片艹艹| 涩九九九九| 色婷婷精品视频| 色色色色色色色色色色色色色97| 五月伊人婷婷999| 91jiuseshunv| 五月婷婷av| 久久婷色| 97人人搞| 五月丁香网站| 岛国AAAV| 精品99爱免费视频在线观看| 99色在线视频| 26uuu偷拍亚洲欧洲综合| 丁香 婷婷 亚洲 熟女| 色色五月婷婷| 看全色黄大色大片| 天天综合久久| 激情人妻综合| 丁香啪啪| 天天日日夜夜| 狠狠CAO日日穞夜夜穞AV| 丁香六月婷婷缴情欧美| 北京熟妇搡BBBB搡BBBB| 丁香五月婷婷综合啪啪| 丁香五月婷婷激情蜜桃| 日本情色一区二区| 五月婷啪啪| 九九热色视频| 色播五月丁香婷婷| 五月丁香激情婷婷| www.夜夜操.com| 色色五月天激情| 另类少妇人与禽zOZZ0性伦| 日产精品一线二线三线芒果| 嫩草哈哈操| 久久久久8888| 五月丁香六月久久| 婷婷五月激情欧美大胆视频| 五月天婷婷在线观看精品男人| 五月婷婷综合潮喷| 99国产精品久久久久久久久久久| 天天插天天爱| 五月婷婷丁香社区| 色综合久久8| 婷婷大乡焦噜噜| 99re热在线视频| 深爱五月中文字幕| 丁香六月婷婷色XXXXX| 婷婷五月天亚洲综合| 五月丁香六月色| 激情性爱五月天网页| 婷婷五月开心六月AV| 啪啪99| 丁香五月激情天AV无码| 五月婷婷我| 久久9视频欧美| 久99| 久久机热探花| 在线观看五月婷婷网| 丁香五月天激情小说| 婷婷五月色惰| 免费做A爰片77777| 99艹精品在线观看| 久久久婷婷| 激情婷婷狠狠干| 99操免费视频| 野战J办公桌椅H| 激情久久综合网| 亚洲视99| 亚洲成人婷婷| 五月婷婷成人| 一区操| 亚洲激情亚洲激情| 狠狠五月天激情| 激情六月丁香综合| 九九视频这里只有精品| 超碰成人免费| 亚洲中文字幕在线电影| 五月丁香另类图片| 天天干-天天日| aa久久| 丰满女老板BD高清A片| www.玖玖婷婷在线| 亚色网站小视频| 日日操日日撸| 色婷婷小说| 99热在线精品播放| 思思99re这里只有| 色婷婷狠狠爱| 欧美色偷偷大香| 婷婷激情肏屄网| 天天日综合| 一本色综合色| 久久与婷婷| 精品,99| 色婷婷成人| 久久婷婷草| 五月婷婷免费视频| 婷婷激情社区| 色99欧洲色19| 国产va在线视频| 九色自拍| 影音先锋男人站,影音先锋男人色资源网,影音先锋AV最新资源站,影音先锋AV资源 | 丁香五月www| 五月丁香激情婷婷综合字幕| 日日噜噜夜夜狠狠久久丁香六月| 色色色色欧美| 婷婷五月四狠狠| 午夜婷婷久久 | 婷婷激情图片| www:99热视频| 99精品在| 色色色在线观看| 五月婷婷激情啪啪| 狠狠狠狠狠狠草| 久久久久久人妻久久久久久久久久人妻久久久 | 久久久久9久无码视频| 丁香女人五月天| 婷婷激情综合| AV免费在线网站| 激情五月天免费视频| 激情深爱五月天| 亚洲在线操| 日本五月天网站| 亲子乱AV-区二区三区| 欧美亚洲999| 色999亚洲人成色| 全高清无码视頻| 丁香五月天在线| 色欲五月丁香| 国产淫熟妇| 婷婷五月天激情网| 99久久网站| 久热 91| 久色激情| 激情五月天婷婷五月天| 婷婷五月综合色小姐小说| 亚洲人妻一区二区| 激情综合色| 色波激情五月天| 久草热在线视频| 日韩av在线电影| 婷婷激情在线| 丁香五月婷婷偷拍| 美女五月天| 超碰免费电影| 丁香六月无码播放| 色色a| 人妻性爱av网站| 激情小说在线视频| 深爱激情中文五月天av| 色五月天堂| 色色丁香五月天| 色婷婷欧美| 91超级碰在线视频| 成人一级片| 99久在线精品| 99在线视频资源| 亚洲婷婷91丁香| 色欲天天综合网| 色色99| 91欧美| 国产99美少妇| 五月激情综合网| 色六月天天激情综合网| 婷婷伊人綜合中文字幕| 99热欧| 亚洲人人操| 色狠狠综合网| 爱穴久久| 五月激情婷婷丁香| 日本三级色| 综合一区二区三区| 九热精品| 97热视频| 激情久久四色| 国精产品一区一区三区免费视频 | 色色色网站| www.jiujiujiu| 五月天婷婷久久| 成人看片网站| 色五月婷婷网| 丁香五月综合在线播放| 狠狠爱深色婷婷综合| 欧美成人五月天| 婷婷色偷拍| 成人亚洲精品| 日本va欧美va欧美va精品| 激情五月天网站| 九九99九九精品免费 | 亚洲愉拍99热成人精品| 婷婷激情网五月天| 97在线天堂| pacopacomama 070722_670 素人奥様初撮りドキュメント 103 大久保純子 | 欧美啪啪网| 99干视频| 综合网色| 成人午夜视频精品一区| 狠狠插日日干撸| 2021日韩无码| 黄色AV日韩| 婷婷色天香| 99热伊人综合| 色噜噜狠狠色综无码久久合欧美 | 九九热视频思思| 停停五月色宗合| www.99热这里只有精品| 丁香五月综合激情久久潮喷| 色色色色色色综合网| 激情影院丁香五月| 午夜成人AV在线| 色五月激情五月| 婷婷天天色| 97av在线视频| 日本欧美成人片AAAA| 丁香五月婷综合网| 九九aV| 婷婷99狠狠躁天天久久久九九九| 99热这里只有免费| 99欧州偷拍视频| 亚洲亚洲人成综合网络| 狠狠干狠狠干狠狠干狠狠干| 色99无码| 99综合| 5月丁香婷婷激情网| 久99久在线| 九九亚洲天堂| 99九九视频精彩在线| www.国产亚洲69ty.久久久久久久久久久久 | 欧洲亚洲免费视频9| 久综合4| 91超碰人人操| 99热.com| 97碰碰碰免费公开在线视频| 五月丁香大相交| 夜夜爽日日躁| 久久久久久欧美精品se一二三四| 婷婷五月综合中文字幕| 7超碰自拍| 99热国产这里只有精品| 成人视频网| AV在线中文| 久久色五月天综合网| 五月综合久久| 超碰九九热| 免费视频99| 丁香五月五月婷婷欧美大香蕉| 色综合九九| 婷婷六月综合基地| 色九月丁香婷婷蜜桃在线观看| 99热自拍| 成人电影AV在线观看| 任你干线上免费视频有3吗| 丁香五月婷婷色五月| 五月天狠狠色| 久久五月婷综合网| 久热这里只有精品66| 99热这里只有精品3| 色色色色色五月| 色久五月天| 丁香五月-激情综合| 婷婷色无码| 91中文在线| 综激情网| 激情久久久久久久久| 久人人操| 色五月婷激情| 9精品久久999| 午夜青草资源| 99精品成人无码A片观看金桔| 欧美色99| 久久92| 99日逼视频| 五月丁香花视频| 亚洲综合欧美色丁香婷婷888月图片| 五月综合亚洲婷婷| 婷婷五月花| 五月丁花色综合网| 女人天堂AV| 久久九九怡红院| 日本va欧美va国产激情| 色色操| 色99网| 性爱综合网| 国产日韩欧美性爱| 丁香六月色香蕉视频| 丁香五月婷婷啪啪| 日韩色色色99| 香蕉AV777XXX色综合一区| 777精品成人a v久久| 99精品视频播放|