免费国产精品自在自线-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
返回資訊列表
激情五月婷婷视频| 婷婷五月天丁香社区| 色婷婷丁香AV综合| 99小视频| www.五月天色色色| 丁香五月婷婷高清| 嫩草AV久久伊人妇女超级A| 天天色激情| 热九九精品| 五月婷婷综合激情小说| 婷婷综合久久| 99热在这里只有精品| 色情五月天婷婷| 99综合视频一体| 九九99精品视品| 午夜婷婷| 91九九| 婷婷五月天激情亚洲小说| 六月激情丁香一道本7777| 六月丁香五月婷婷| 激情四射五月天| 色激情五月| 五月婷婷亚洲天堂激情在线| 人人爱操| 99re熱| 先锋资源91| 熟妇天天综合| 日本nghangse中文字幕| 性爱111111| 五月丁香啪啪| av大片在线| 五月婷婷六月激情| 国产精品电影| 久久久国产精品黄毛片| 伊人久久丁香狠狠婷婷综合香蕉 | 无码A片一区二区免费| 91人在线观看| 婷婷五月天国产性感美女演员久久久久| 大香蕉综合| 成年人丁香五月| 伊人久久五月天综合| 日本女va| 亚洲婷婷丁香五月视频| 亚洲另类噜噜| 91丨九色丨熟女丰满| 亚州操人在线视频| 色色婷婷丁香五月天| 婷婷激情社区| 色爱综合网| 夜夜干天天操| 天天射综合网站| 久久精品9| 99无码视频| 激情5月婷婷| 99精品久久久久久久婷婷久久| 色综合天天网| 日日天天干| 色噜噜婷婷| 五区毛片七区毛片| 激情AV在线| 99热综合色图| 五月天激情国产综合婷婷婷| 香蕉曰比| 五月天激情久久| 亚洲操精品| 五月婷婷在线短视频| 人妻熟妇国产精品| 国熟女视频| 玖操97| 综合五月激情网| 99成人精品视频| 五月天婷婷丁香社区| 国产成人亚洲综合A∨婷婷| 婷婷性色| 国产精产国品一二三在观看| 日韩精品无码AV| 99热99精品| 二色av| 99区视频| 操人久久| 91丁香色| 2014天天爽| 激情婷婷丁香色情五月天| 五月婷婷色吧!| 五月丁香六月婷婷网站| 超碰成人电影| 久久性爱激情| 天天色一道本综合婷婷| 丁香五月综合| 2050人人操免费工开爱| 影音先锋毛片网站| 五月天激情视频网站| 操逼视频一区| 丁香五月天91| AV天堂淫乩| 九九热免费| 另类天堂| 婷婷激情综合色五月久久图片| 久草 天堂| 九九视频在线免费视频| 久久亚洲婷婷| 91AV婷婷| 99久久极情精品一区| 久99在线视频| 日本 色综合| 开心五月六月婷婷| 97热精品| 国产视频福利| 51avj视频大全| 九九色色| 操操天堂| 五月天开心网| 丁香五月 性爱| 色吧综合网| 激情综合网激情五月丁香| 久草大| 亚洲一二三网| 性天天中文网| 99在线资源视频| 婷婷成人网五月天| 91在线日本| 九九热精品| 噜噜操操| 91日日日| 亚洲无码成人| 99热这里只有精品1025| 玖玖在线视| 免费色婷婷| 五月天无码视屏播放| 日本久久人| 天天视频精品9| 丁香五月天激情网址| 天天干天天干天天| 高清成人综合| 欧美视频五区| 色碰干| 激情五月丁香五月| 久久狠婷婷| 久久婷婷五月综合色和| 青青艹b| 婷婷久久六月费| 欧美人与性动交CCOO| 五月丁香| 在线理论片| 性爱网久久| 99热主页日本| 五月六月丁香激情视频| 久热久| 色999五月色| 亚洲综合色色| 婷婷免费精品视频| 激情四射亚洲| 少妇激情五月天| 嫩草视频| 久/久精品99看9| 激情图片婷婷| 丁香六月啪啪| 丁香五月亚洲无码| 99九九热视频免费| 91超碰在线播放| 97碰久久| 婷婷色情 | 99爱视频在线免费观看| 色婷婷玖玖影院| 强伦轩人妻一区二区电影| 丁香色情五月综合激情| 人妻激情综合| 婷婷舔| 四LLL少妇BBBB槡BBBB| 婷婷五月天少妇| 激情都市另类| 婷婷五月综合社区| 婷婷五月免费观看| 精品综合爱| 色婷婷在线播放| 五月天日日操夜夜操 | 一级视频网址| 九九热精品| 婷婷四月 成人 狠狠干| 一本色道久久综合狠狠躁一二三| 激情亚洲婷婷| 亚洲精品性色| 成人视屏在线观看| 久99久视频精品| 天天日本夜夜谢| 婷婷综合色网| 无码成人AAAAA毛片AI换脸| 久久久精品人妻录| 亚洲小视频免费播放| 色婷婷小说| 五月丁香激情欧洲啪啪| 五月花综合| 色.五月综合网| www夜夜操| 丁香五月香蕉| 九九热内射| 国产综合婷婷| 五月天停停基地| www.日本91| 欧美交换配乱吟粗大25P| 婷婷丁香色五月| 99操碰| 少妇2做爰HD韩国电影| 亚洲视色| 综合色五月天| 91中文在线| 91久久久久| 狠狠久久婷五月| 欧洲综合色| 91视频一起草| 日韩成人综合| se色婷婷视频| CHINESE熟女老女人HD视频| 99热6精品| AV堂狠狠干| 91人人妻人人操人人爽| 丰满少妇猛烈A片免费看观看| 99久久五月婷婷| 九九综合精品| 人妻中文在线| 97资源欧美日韩大香蕉超碰一区| 婷婷久久天堂网| 狠狠操狠狠插| 久99热| 色色五月婷婷久久| 99色热| 春色激情第四色| 日韩狠狠色| 色婷婷狠狠禁久久| 五月天天丁香婷婷| 五月丁香婷婷五月色| 日日天天干| 婷婷五月天播播| 久久婷婷五月丁香| 五月丁香综合伦理片| 欧洲一区二区| 日本色久| 五月天婷婷基地综合网| 色色色区| 99热青青草| 婷婷五月丁香色综合| 97日韩无套内| 激情综合色婷婷啪啪五月天| 色色色五月天婷婷| 大香蕉福利导航| 国产一区二区三区影院| 国产偷人爽久久久久久老妇APP| 色五月婷婷久久| 日日干日日| 99精品视频免费| 天天擼久久擼在线| www激情| 日日爽天天| 婷婷激情五月综合丁| 六月丁香婷婷亚洲中文玖玖| 69er小视频| 99re这里只有精品首页| 日韩欧美一级大黄网站| 开心激情综合| 亚洲六月婷婷| 五月天激情国产综合婷婷婷| 老妇六区| 久久五月情| 激情五月天第四色| 久久9视频| 超碰人人操人人干| 在线色五月婷婷| 激情综合网,五月| 第四色婷婷色五月| 思思热视频在线| 5五月综合网亚洲| 亚洲色网址| 天天干天天爽| 999热这里只有精品| 久久婷婷五月天| 99热综合| 色97啪啪| 天天爽在线视频| 婷婷丁香五月天婷婷| 五月天婷婷黄色视频| 五月婷婷久久综合| 俺去也五月| 天天色丁香| 天天射影院| 91九色最新视频| 丁香五月 激情文学| www.色色五月天.com| 99热欧美| 色色色色色网站| 丝袜激情网| av色色国产| 99国产精品白浆在线观看免费 | 九九色人| 丁香六月亚洲综合| 久草性爱| 在线看的免费网站| 97亚洲婷婷| 五月婷婷与六月丁香图片激情| 丁香五月婷婷五月天在线| 色五月丁香六月资源站| 色婷婷亚洲在线| 99热手机在线精品| 婷婷综合在线| 欧美日韩国产伦精品日韩人妻一| 婷婷久久视频| 丁香五月色五月| 色色a| 九九九激情综合| 超碰93在线观看| www.av视频xx999.com| 日韩精品色| www.99热视频| 欧美经典片免费观看大全| 激情婷婷在线| 久久99热这里只有精品23| 丁香六月婷婷一区二区三区| AV性爱网| 超碰在线99热| 五月天六月婷婷| 色情五月综合婷婷| 色五月大香蕉婷婷| 久久五月婷婷开心网| 天天透天天摸天天舔| 操操人人| 五月天丁香综合在线| 久/久精品99看9| 色操b| 丁香六月在线| 色婷五月天| 丁香婷在线| 亚洲丁香花色| 色色色五月婷| 深爱激情六月天| 九九综合| 在线观看五月婷婷网| 六月丁香五月天| 欧美丰满熟妇BBB久久久| 野外99热| 性生活视频98791| 丁香五月自拍| 丁香六月婷婷综合啪啪| 丁香六月色婷婷| 97一区二区| 狠狠色丁香五月婷巨| 婷婷社区五月天| 五月天色小说| 五月丁香婷婷六月天| 久久久婷婷婷| 91婷婷丁香| 久久婷婷五月天蜜桃| 风流少妇A片一区二区蜜桃| 五月丁香婷中文| 五月天综合在线| 久热re视频在线观看网站| 五月天婷婷色在线视频免费观看 | 久9热在线免费观看| 99热99ai| 深爱五月激情| 色色五月婷婷久久| 久久五月天激情| 免费超碰在线观看| 狠狠插狠狠| 亚洲激情综合| 色色色99韩| 五月丁香六月婷| 日本综合久久| 开心五月天激情网| 99这里只有精品视频在线| 97色干| 五月婷婷三级| 天天插综合| 99 r热| 色婷婷九月| 一区色色色色网| 九九久久五月天| 一起草无码| 激情五月婷黄版| 99热热热国产超碰| 婷婷九月色| 五月丁香婷婷色| 99热免| 影音先锋按摩| 熟妇内谢69XXXXXA片| 天天狠狠色| avh片在线观看| 婷婷激情五月天视频在线| 久久XX日本综合| 婷婷深爱五月| 九九精品热| 久久精品这里只有精品免费首页| 色综合xx| 男人天堂AV在线一区二区| 久色大| 97碰| 国产伦亲子伦亲子视频观看| 99re热视频这里只精品| 亚洲免费看片| 日韩限制级大尺度黑料泄密大尺度视频一区二区在线观看 | 极品五月天| 色九月综合网| 狠狠色丁香| 色射婷婷五月天| 人人妻人人澡人人爽| 亚洲色色香蕉| 婷婷,五月天,丁香,第一| 精品色色| 五月丁香六月综合激情| 日本a片网址| 婷婷影视久久| 亚洲婷婷免费| 午夜丁香五月天综合| 亚洲婷婷激情综合激情999精品| 人妻啪啪啪| 99爱免费视频在线观看| 久超超碰| 丁香五月天91| 久久亚洲激情五码| 99综合网| 玖玖九九99| 婷婷六月视频| 久久久久久久久月丁| 五月天激情啪啪| 99热在线99| 综合久久六月| 极品人妻VIDEOSSS人妻| 五月婷婷激情综合网| 精品国产va久久久久久久| 免费看片在线观看| 欧美三级巜人妻互换| 日日日日日| 丁香婷婷六月天| 玖玖在线视| 91人在线观看| 色另类五月天| 99热免费网站| 天堂久久精品| 亚洲狠狠婷婷| 九月婷婷人人操人人舔人人爱| 在线视频99| 米奇影视资源婷婷狠狠色激情欧美五月丁香 | 色色射| 天天干天天日天天操| se色99| 六月丁香停| 丁香狠狠色婷婷久久无码视频| 高清无码入口| 婷婷伊人网| 久久五月天激情| 91超级碰碰| 99人人操人人操人人精| 热久91| 97碰碰碰免费公开在线视频| 五月天激情网图片| 久热九九| 丁香五月Av| 伊人www22综合色| 五月六月婷婷| 99热这里只有精品22| 激情婷婷亚洲五月| www.91.com处女在线直播| 好色婷婷| 综合激情九月婷婷,激情综合婷婷中文字| 影音先锋日本三级资源| 国产真人做爰视频免费| 热九九精品| 日韩AV大全| 五月婷婷六月丁香综合在线| 综合网色| 婷婷丁香成人| 丁香五月偷拍| 91久久日日| 国产毛片欧美毛片久久久| 九九热精品| 97色婷| 丁香婷婷基地| 亚洲日韩一页精品发布| 精品国产乱码久久久久夜深人妻| 丁香激情网| 黄急一级视频| 在线sebiav精品视频| WWW、99热| 伊人丁香在线| 人妻视频在线| 久久久思思热| 热99只有精品| 婷婷五月天高清无码| 婷婷五月天久久| 可以看的av| 欧洲一区二区| 夜夜操夜夜操| av婷婷丁香| 亚洲中文AV网站| 色婷婷啪啪| 婷婷狠狠18禁久久| 丁香五月第九色| 热这里| 色色色色网站| 99热精品在线播放| 一级黄色影片| 思思热久久艹| 天天色天天日| 91精品久久久久久综合五月天| 久久99综合| 婷婷亚洲综合| caopeng97人人| 激情床戏| 天天日夜夜草进麻麻的子宫| 欧美五月丁香| 精品一二三区久久AAA片| 久久中文网| 久久天堂婷婷五月| eeuss人妻| 亚州操人在线视频| 日日夜夜天天| 9久热在线精品| 操日本99| 婷婷久久99| 婷婷五月天色综合翘| 中文字幕色色| 九九视频在线| 天天综合色丁香| 激情深愛五月視頻| 五月丁香久久| 国自产拍偷拍精品啪啪一区二区| 高清国产AV| 色网站99| 成人版视频在线观看| 少妇性按摩无码中文A片| 亚洲亚洲人成综合网络| 色五月超碰| ss99热| 99热91| 色色综合热| 97色色色色色色色| 96丁香六月婷婷蜜桃综合久久| 网站免费一站二站| 欧美性久| 九九精品在线观看视频6| www色五月| 99热久久这里只有精品| 色情综合| 色播五月天激情| 粉嫩av懂色av蜜臀av熟妇| 天天插操| 五月婷高清视频| 99.N在线视频| 久婷婷色| 97色色综合| 女人天堂AV| 九九热99视频在线| 亚洲热热视频| 精品五月花| www.夜夜操.con| 色吧五月婷婷| www.久操| 久久这里有精品在线观看| 开心激情网在线| 99毛片| 亚洲激情网| 67194线路二在线观看| 天天弄天天爽| 五月丁香综合在线| 九九99精品视频在线观看| 五月天综合视频网| 综合婷| 天天干天天爽天天爽| 蜜桃人妻无码AV天堂三区| 亚洲综合婷婷| 热九九精品| 色伊人啪| 欧美va视频| 超碰在线9| 婷婷五月天激情网| 激情啪啪五月| 九热免费视频| 久热黄色| 深爱五月激情| 亚州激情网站无码| 国产精产国品一二三在观看| 五六月丁香激情视频| 97精品人人A片免费看| 久久婷婷六月| 激情内射人妻1区2区3区| 桃色激情婷婷伊人网| 激情色播| 日韩五月婷婷| 最新高清无码专区| 色宗合久久五月婷婷| 啪啪日本欧美| 婷婷午夜天| 色色色1网址| 色五月天成人| 91丨九色丨高潮丰满日本| 99九九99九九九视频精彩| 日本成人内射| 久久小视频| 97干免费视频| 国产精品大香蕉| 99免费热在线精品| 天天日日夜夜| 99色热综合| 久re在线| 99爱在线精品视频免费观看| 怡红院院在线导航网| 日本4399天堂中出| 欧美五月婷婷| 婷婷五月天渟渟| 五月丁香色色| 九九视频精品在线免费| 狠狠久久婷婷| 色色五月丁香| 五月婷婷影| 久热 91| 丁香五月天啪啪| 五月天夜夜爱夜夜操| 日韩美一级毛卡片| 久久这里只有精品8| 五月丁香六月欧美| 亚洲免费99| 99久久婷婷| 亚洲精品永久久久久久| 婷婷五月综合色中文字幕| 久久婷婷五月综合色丁香花| 婷婷五月色色| 九九视频热| 狠狠色噜噜狠狠| www.激情| 日本精品。999| 九九色天堂| 色香蕉影院| 日日日日操| 九九色热| 久久丁香社| 欧美操人| 五月天网站免费欧美| 五月综合亚洲色| 亚洲色区17| 99热这里| 久婷久婷| 怡红院视频| 午夜成人网站在线观看| 久99久视频精品| 日日干天天爽| 五月婷婷AV| 中文字幕综合网| 亚洲正能量欧美| 丁香午夜天| 天天干天天日天天操| 婷婷五月激情六月丁香| 综合99久久| 色色色99| 99操| 丁香五月香蕉| 婷婷十月激情综合网| 婷婷五月花免费视频在线| 黄久久久| 国产在线视频1234| 性爱网五月婷婷| 伊人婷婷五月天| 丁香五月婷婷AV| 五月婷婷,六月丁香| 色 丁香婷婷| 噜噜噜噜噜在线| 91日本在线观看| 小泽玛利亚视频一区二区| 成人草榴视频| 亚洲无AV在线中文字幕| 色999五月色| 97av在线视频| 综合大香蕉| 色欲午夜无码久久久久久张津瑜 | 六月婷婷色| 久久九九网| 五月婷婷综合在线| 激情小说之五月| 色婷婷在线视频综合| 99人这里只有精品| 新99思思视频| 26uuu美女三级视频| 精品思思久久| 久久久久久xxxxx| 97人人搞| 欧韩性爱| 2025最新亚洲激情在线| 99er日韩| 热99精品视频观看| 婷婷五月丁香高清无码| 第四色婷婷最爱| www.91有码.com| 激情丁香网| 青青草六月丁香| 五月天色婷婷基地| 99这里只有精品|v| 久久久久久久久99精品| 日本五月婷| 色人久久| www.金莲av| 精品AV无码超碰| 婷婷六月天| 久久色五月天| 国产亚洲在线观看| 五月婷婷伊人网| 天天檫天天爽| 精品久久久人妻| 噜噜在线| 五月丁香网站| 人人操婷婷| 99精品女人天堂| 激情丁香社区| 爱草视频在线观看| 丁香婷婷激情网站| 4399在线日本A片| 五月综合久久| 六月婷欧美丁香综合| 五月丁香六月婷婷的女人| 国产67194| 婷婷五月丁香狠狠| 五月婷婷六月综合| 综合五月天| 万月丁香狠狠爱| 九草性爱| 婷婷丁香77777| 婷婷五月天综合小说网| 色综合色五月| 中文字幕在线日亚洲9| 伊人五月婷| 色九月婷婷综合| 国产精品色一哟哟| 97操碰视频| 人妻丰满精品一区二区A片| 9在线9在线婷婷在线国产| 97影院一级片| 99性感视频| 婷婷永久在线| 丁香五月婷婷综合激情哟哟哟| 日本美女上人| 久久开心五月天激情| 色99网站| 丁香五月天激情| 国产综合久久久777777| 色必久悠悠影院| 中文字幕综合| 九九XX视频| 五月婷婷xxx| 五月丁香啪啪综合| 思思热在线观看| 无码动漫av| 色五月激情基地| 超碰久热| 久色五月天| 狠狠干五月丁香综合网| 人人操AV| 成人丁香五月| 天天天天操| 亚洲网综合在线| 九九色之九九色之88| 思99热精品久久只有精品| 色婷婷电影网| 色色五月天 亚洲| 色婷婷五月天天天天天| 操逼六区| 色一情一乱一乱91Av| 丁香五月天激情综合网| 五月天婷婷综合网| 亚洲av网站| 天天天天做夜夜夜夜做| 综合激情婷婷| 色5月婷婷| 97干综合网| 毛片蕉地一二| 综合久久五月天| av在线婷婷| 欧日美女Va| 操久久网| 99狠狠色| 玖玖在线| 久久婷婷五月综合成人d啪| 狠狠操婷婷| 日日夜夜天天| 色色热99| www.夜夜操.com| 99亚色色色| 色综合激情| 婷婷丁香色五月天久久88| 五月丁香天堂网| 六月色色| 五月天桃色深爱网| 韩日在线熟女| 丁香五月性爱| 人妻久久久久久久久| 国产乱妇乱子在线播视频播放网站 | 色狠狠综合| 丁香五月婷婷手机| 久久婷婷五月综合网| 99热这里只有精品 搜| 五月婷婷操操| 天天操天天爱天天玩| 2050人人操免费工开爱 | 欧美日韩一区二区三区四区| 香蕉99网| 天天操婷婷| 综合色网站| 婷婷色五月天在线观看| 久热精品视频在线观| 九九热超碰| 婷婷瑟五月天久久综合| 亚洲色就是色色色| www.26uuu.com亚洲电影| 影音先锋91视频| 五月天天天天天天天天天天天天天天天婷婷婷 | 色99在线看| 超碰碰碰碰| 亚洲精99| 人人肏逼视频在线一区二区| 饮料下药迷倒漂亮女同事强干| 在线中文亚洲| 亚洲人妻电影| 丁香婷婷综合激情五月色,开心五月丁香花综合网,激情综合五月亚洲婷婷,五月天 | 性视频久久| 久久久久久人妻| 激情婷婷丁香色情五月天| 综合久久婷婷99| 人人视频人人干人人做| 色碰碰视频| 午夜无码熟熟妇丰满人妻| 五月天狠狠草| 99精品一二三四视频| 亚洲天堂色色| 视色综合| 丁香五月激情啪| 99ER热精品视频| 丁香婷婷婷五月| 99精品视频偷拍| 中文字幕欧美日韩VA免费视频| 五月天婷婷成人资源站| 精品99视频| 天堂成人A片永久免费网站| 啪啪小说五月天| 99性视频| 一级视频网址| 99热日韩| 伊人五月成人| 丁香五月香蕉在线| 婷婷色色宗合网| 精品人妻一区二区三区四区不卡在| 丁香五月六月激情| 99自拍网| 毛v一区二区视频| 五月丁香六月综合激情| 精品人妻久久久| 西西4r午夜剧场| 人妻人人操| 亚洲综合色棒| 天天插天天很| 丁香婷婷五月激情| 丁香六月婷婷社区| 亚洲精品又粗又大又爽A片| 久久人妻系列| 91久久99久久91熟女精品| 久久ri精品| 色情成人五月天| 99久视频| 密桃激情五月天综合网| 婷婷五月丁香六月伊人网| 午夜丁香六月婷| 亚洲天堂婷婷| 成人做爰A片免费看网站找不到了 噼里啪啦在线观看免费完整版视频 | 九九人人精品| 色99欧洲色19| 婷婷丁香五月天欧美| 激情五婷网| 91jiuseshunv| 99色色网| 五月丁香六月婷婷网| 天天操天天操天天操天天操天天操天天操天天操天天操天天操 | 日本91在线播放| 婷婷五月天激情网| 婷婷五月综合色拍| 久久国产色| 久久aaaa片一区二区| 丁香五月婷婷亚洲色图| 久久黄A片| 久操激情| 婷婷在线综合| 99精品高潮| www.sebowuyue| 九九综合88| 91人妻九色大屁股| 免费无码毛片一区二区A片| 可以看的av| 91久久婷婷| 九月激情网| 色丁香婷婷| 色婷婷小说| 激情性五月天免费小说视频| 99热99热99热99热| 视色综合| 99热在线精品观看| 九九热视频思思| 六月婷色六月| 热久久成人| 婷婷激情另类| 猫咪伊人久久| 色婷婷888| 97精品自拍视频| 我去色色网五雨天| 啪啪色区| 97热在线精品| 午夜爱插插| 91人人爽人人操| 第1影院之五月婷婷| 亚洲精品444久久久久久| 中文字幕av亚洲| 丁香五月综合激情性爱| 婷婷激情五月综合| 99热热九九| 欧美欧盟性爱网| 人人人操Av| 久久视频婷婷视频| 国产美女最新VA在线免费观看| 激情综合婷婷| 99日这里只有精品| 深爱激情综合网| 婷婷色网站| 色情久久久| 777色色色| 人人人操| 五月丁香六月激情综合| 国产SUV精品一区二区6| 热久综合| 神马久久五月天| 99福利导航| 夜夜躁婷婷AV| 婷婷五月在线免费| 丁香六月爱综合| 亚洲五月花| 欧美色图天堂网| 欧美三级巜人妻互换| 国产精品岛国片在线观看免费| 青青久久91| 91色噜噜狠狠狠狠色综合| 六月婷婷九月丁香| xx久久| 五月天天天综合| 丁香五月av在线| 色色五月天网站| 91丨九色丨国产打屁股| 99re8在这里只有精品| 99无码视频| 亚洲欧美综合7777色亭亭| 久久99看免费| 六月天六月婷| 免费啪啪亚州视频| 色5月婷婷| 香蕉五月婷婷| 婷婷色女| 丁香婷婷五月| 婷婷五月综合在线| 去色色五月天| 国产精品久久99| 色区域网站视频| 成人在线网址| 91日本在线免费| 亚洲夜五月| 国产97色在线 | 日韩| 国产真实乱了老女人视频| 国产操B视频| AV国产有码| 婷婷性爱网| 久久五月天精品视频| 婷婷五月天AV| 日日日日日| 亚洲欧洲中文日韩久久AV乱码| 久久 婷婷 五月天| 五月丁香六月婷婷在线播放| 色播五月丁香| 97香蕉人人在线观看| 六月丁香五月亭亭| 婷婷五月骚厕所| 99色热| 人妻视频在线| 久久久久久天天日天天爱| 99乱视频| 九九99九九精品视频| 无码G高清天| 我爱大香蕉| 六月丁香色色色| 天天成人综合| 99无码精品| 97热精品| 色五婷婷开心缴| 色网五月婷婷| 国产色丁香| 色综合久久44| 婷婷丁香综合| 婷婷五月天成人网站| 99久久66综合| 思思99精品视频在线观看| 99操视频| 久久婷婷五月综合精品蜜芽| 五月婷婷亚洲色视频| 丁香五月综合网| 91操网| 99热这里只有精品9| 九九99精品视品| 久热这里只有精品视频6| 26uuu欧美| 婷婷六月爽| 九九热精品| 人妻射精AV| av在线资源| 精品成人在线观看| 国产性爱一级| 五月婷婷,狠狠操| 橾逼网| 久久久潮喷-久久久九九-成人AV| 色大综合| 另类五月激情| 热久久精品视频网站| 91se精品国产| 一区二区三区四区无码| 天天操天天插天天射| 国产高清精品色| 婷婷五月丁香基| 操丝袜视频影院导航| 亚洲深喉aV| 亚洲激情综合五月婷婷啪啪| 91人人人人人| 米奇影视资源777狠狠色婷婷五月天激情网 | 五月天婷婷基地| 五月天国产成人| www.五月天婷婷| 二人电影免费版在线观看| 久久人妻精品| 成人噜噜网| 五月丁香| 天天天天天天天操| 久久ri精品视频| 99在线精品视频| 99情色五月天| 婷婷五月天Av| 五月天婷婷色色| 天天爽人人综合免费7799| 激情伊人六| 综合久久激情久久| 播四月婷婷六月丁香| 久久九九中文字幕| www.日日夜夜.com| 99热这里只有精品一| 婷婷不卡基地| 亚洲欧洲国产精品| 99精品视频免费在线播放| 中文字幕丰满孑伦无码专区| 婷婷丁香在线播放| 伊人9在线| 婷婷色五月激情| 天天操夜夜橾| 日本三级日本三级三级人妇四虎| 久久丁香| 久久免片| 久这里只有精品99| 秋霞少妇AV网站| 99色色网| 思思色播| 国产99久久久国产精品免费看| 色综合久久久久久久久五月| 99热精品观看| 六月丁香网| 亚洲精品永久久久久久| 91久久久久久| 五月天社区婷婷| 婷婷午夜综合| 婷婷五月永远18免费久久久| 色婷婷六月| 亚洲成人网站在线播放| 99视频色在线观看| 色五月婷婷丁香凹凸| 天干夜夜操| 在热视频精品| 伊人影音无码一区二区三区| 丁香五月综合狠狠| 激情五月天影院| 自拍盗摄 另类| 九九综合视频在线观看| 香蕉曰比| 国产综合色婷婷精品久久| www..com色爱| 久久综合爱| 大鸡巴伊人网| 婷婷色色五月天| 五月丁香欧美综合| 开心五月丁香啪| 久久机热这里只有精品免费视频| www.九月婷婷丁香.com| 色五月综合网| 91免费看片| 五月六月激情| www.sd-xiangsu.cpm| 九九热中文| 激情婷婷护士激情| 天天插天天插| 日韩激情人伦人| 欲色人妻| 极品少妇XXXX精品少妇偷拍| 激情视频综合| 婷婷五亚洲| 丁香五月婷婷呀| 91九色丨国产丨爆乳| www.色色com| 99噜噜噜在线播放| www.夜夜| 日本久久婷| 五月天婷久精视频| 伊人五月天婷婷| 琪琪秋霞| 九九色影视| 六月婷色| 欧美性生交XXXXX无码小说| WWW.99热| 天天久久狠狠色综合| 婷婷丁香人妻天天爽| 丁香五月天综合网| 99高级会所久久| 99久久久99久久91熟女| 久热大香蕉| 久久久婷丁香五月天激情综合| 丁香av网| 婷婷影院A成人| 99精品视频在线观看| 丁香五月电影| 五月激情小说| 狠狠干,狠狠操| 99精品热| 99色综合| 欧美一级色| 97久久超碰| 色色色欧美| 亚洲成人影视在线观看| 97视频.干com| 最新色色五月天| 色玖玖爱| 免费在线观看欧美激情xx小视频| 激情九九这里只有精品| 亚洲成人va| 四月婷婷丁香| www.婷婷五月| 久久婷婷五月天激情四射| 狠狠操狠狠插| 成人婷99最新| 色五月婷婷av| 啪啪综合网| www.久热| 国产成人AV| 九九XX视频| 久久日本wwww色| 激情五月色综合网| 9l视频自拍9l视频自拍九色学生| 五月丁香91| 伊人丁香五月婷婷潮吹| 国产a视频| 91丨九色丨高潮丰满日本| 亚洲综合色婷婷| 亚洲精品乱码久久久久久按摩观| 久久婷五月| www.十八禁不禁AV.com| 天天做天天爱高潮片| 五月丁香婷婷成人伊人网| 337午夜福利| 99热激情| 色色色99| 尤物一区二区| 久热天堂| 91 九色 熟女| 激情5月婷婷狠狠干| 丁香六月婷婷色XXXX| 。久久久久久久久久久久久久人妻| 久久久久人妻精品| 天天骑天天操| 丁香六月啪啪| 91狠狠色丁香婷婷综合久久| 色婷久久| 五月激情久久| 综合激情九月婷婷,激情综合婷婷中文字| www.99免费视频| 国产片天天爽夜夜爽| 六月色日韩| 天天爽夜夜爽夜爽精品| 久久99热这里只频精品6学生| 日日操天天操| 人碰人人人玩91| 激情文学第四色婷婷丁香五月| 久久aaa| 中文在线视频久1| 天天操比比| 超碰A V在线| 婷婷五月丁香六月| 色爱终和网| 久久综合干| 性生生活大片又黄又| 超碰免费大香蕉| 五月五丁香婷婷| 久久99综合网| 亚洲精品国产A久久久久久| www.久久爱.com| 婷婷丁香五月激情图片| 亚洲人成色A777777在线观看| 亚洲欧洲中文日韩久久AV乱码| 丁香五月成人社区| 激情婷婷视频在线| 五月丁香综合精品| 国产免费一区二区三州老师F1F1| 极品人妻XXXXOOOO| 一级视频网址| 日韩成人精品中文字幕| 日日夜夜综合| 亚洲色五月| 91丨九色丨白浆秘| A网在线欧洲| 五月丁香六月婷婷啪啪| 美欧成人视频| 91免费看片| 久久婷婷六月综合| 丰满少妇猛烈A片免费看观看| 婷丁香五月天| 99在线国| 色一情一乱一伦一区二区三区| 人妻视频在线| 激情色视频| 国产67194| 五月天激情啪啪| 这里只有精9| 丁香五月天黄色片| 伊人玖玖网| 极品少妇XXXX精品少妇偷拍| 综合一区二区三区| 欧美Va在线| 午夜少妇在线观看视频| 婷婷五月天色色| 五月天综合| 午夜微拍福利| 翔田千里无码| 色五月激情综合网| 26UUU欧美激情一区二区| 五月婷婷色情| 天天日天天色| 五月婷婷在线视频免费观看| 久久在线大香蕉| 日韩情色在线观看| 五月六月婷| 99re资源在线视频导航| 操逼福利视频| 99视频这里有精品| 三区激情四射av| www婷婷| 99综合免费视频| 久久天堂网| 大香蕉 伊人夜| AV色五月婷婷| 99热亚洲精品| 永久思思热在线| 婷婷99狠狠| 九九色之九九色88| 激情六月天婷婷| www91在线| 欧美日综合| 再綫Av免费視品|