最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React首頁(yè)加載速度優(yōu)化小結(jié)

 更新時(shí)間:2026年01月22日 09:47:41   作者:destinyol  
本文詳細(xì)介紹了如何優(yōu)化一個(gè)加載緩慢的React項(xiàng)目,從刪除未使用的導(dǎo)入、刪除不必要的依賴(lài)項(xiàng)、刪除sourceMap、使用Terser壓縮以及使用SplitChunksPlugin分包,再到React的懶加載優(yōu)化,感興趣的可以了解一下

背景

本文將以一個(gè)什么優(yōu)化都沒(méi)有的加載比較慢的React項(xiàng)目為例,一步一步探索怎樣提升React首次打開(kāi)項(xiàng)目首頁(yè)時(shí)加載特別慢的問(wèn)題。

問(wèn)題分析

首先用網(wǎng)頁(yè)控制臺(tái)查看了一下網(wǎng)頁(yè)加載的進(jìn)度,定位到了加載速度很慢的地方

發(fā)現(xiàn)下載網(wǎng)頁(yè)的js文件,有15mb大小,用了8秒,然后看了下打包好的build文件夾,有19.1mb,并且沒(méi)有分包,是一個(gè)js文件。

問(wèn)題探索

代碼精簡(jiǎn)自查

我首先想到的是刪除每個(gè)js文件中沒(méi)有使用到的導(dǎo)入,簡(jiǎn)化一下文件依賴(lài)結(jié)構(gòu),再刪除一些不需要的代碼,清理一下用不到的圖片素材之類(lèi)的。

刪除這個(gè)的時(shí)候,我沒(méi)找到什么好辦法,我使用的是vscode自帶的功能,自動(dòng)整理所有未使用的import。

使用方法:

打開(kāi)左上角,文件-首選項(xiàng)-設(shè)置,輸入“setting”,選擇“字體”,點(diǎn)擊“在settings.json中編輯”,在json文件中輸入

"editor.codeActionsOnSave": { "source.organizeImports": true },

輸入這個(gè)之后,每個(gè)js文件,在保存時(shí)會(huì)自動(dòng)去除沒(méi)有使用的import。

全部刪除之后,build完,小了一點(diǎn),但依然還有17.7mb,這很顯然還是不滿足要求。

刪除沒(méi)用的包

然后我再想著刪除不需要的依賴(lài)項(xiàng),這里用到了一個(gè)小工具,可以查看哪些包未被使用。

# 安裝
npm install -g depcheck
# 安裝完成后輸入該命令查看為使用的包
depcheck
# 對(duì)于不需要的包,使用以下命令刪除
npm uninstall xxx

找到不需要的包之后,去package.json里面把對(duì)應(yīng)的包全部刪除。

然后使用npm install命令,就可以重新整理依賴(lài)了。

可以看到刪了很多包,我再重新build一個(gè)試試。構(gòu)建完了,還是有17.6mb,并沒(méi)有起到什么作用

刪除sourceMap

在瀏覽網(wǎng)頁(yè)的過(guò)程中,我看到一種解決措施,可以將打包好的build文件夾中的map文件去掉,這樣會(huì)讓整體變小很多

所以我又查詢了map文件是做什么的

打包后產(chǎn)生后綴名為.map的文件是由于配置了sourcemap選項(xiàng)生成的,打包后的文件不容易找到出bug對(duì)應(yīng)的源代碼的位置,sourcemap就是來(lái)幫我們解決這個(gè)問(wèn)題的,有了map就可以像未壓縮的代碼一樣,準(zhǔn)確的輸出是哪一行哪一列有錯(cuò)。

可以看到map是用來(lái)在報(bào)錯(cuò)時(shí)定位源碼位置的,是個(gè)不錯(cuò)的功能,但我打包好的build文件夾一共17mb,其中map文件就占了12mb

所以生產(chǎn)模式部署到服務(wù)器上,如果map文件太大還是刪除了比較好

以下是我查到的一種比較合適的刪除map文件的方法:

因?yàn)閣ebpack的代碼中在打包時(shí)會(huì)自動(dòng)讀取env文件

// 加載環(huán)境變量
require('../config/env')

所以我們可以利用這個(gè)性質(zhì),在根目錄下創(chuàng)建一個(gè).env的文件,并在里面輸入

# 該變量用于控制讓 npm run build 是否會(huì)生成map文件,為false則不生產(chǎn),true則生成
GENERATE_SOURCEMAP = false

這樣設(shè)置完之后,再次打包build,發(fā)現(xiàn)文件大小只剩下5mb了

Terser壓縮

然后我又搜索了相關(guān)資料,我使用的打包是webpack5,發(fā)現(xiàn)可以使用TerserWebpackPlugin對(duì)代碼進(jìn)行壓縮,它不僅可以壓縮,還可以順便進(jìn)行代碼混淆,改所有變量名,去掉所有縮進(jìn)空格然后壓縮到一行里

閱讀了webpack的官方文檔之后,我對(duì)插件配置進(jìn)行了一些調(diào)整(官方文檔:https://webpack.docschina.org/plugins/terser-webpack-plugin/)

在webpack.config.js中進(jìn)行相關(guān)配置

// 這是我TerserPlugin打包的相關(guān)配置,在optimization下進(jìn)行配置
new TerserPlugin({
          parallel: true,	// 并行打包,打包加速
          extractComments: false,	// 刪掉注釋?zhuān)魹閠rue,表示會(huì)將注釋抽取到一個(gè)單獨(dú)的文件中
          terserOptions: {
            parse: {
              ecma: 8,
            },
            compress: {
              ecma: 5,
              warnings: false,
              comparisons: false,
              inline: 2,
            },
            toplevel: true, 
            mangle: true,	
            keep_classnames: false,
            keep_fnames: false,
            output: {
              ecma: 5,
              comments: false,
              ascii_only: true,
            },
          },
        }),

這樣設(shè)置之后再次打包,發(fā)現(xiàn)build文件夾只有4.35mb了,已經(jīng)比一開(kāi)始小很多了,但感覺(jué)加載速度還是不會(huì)非常流暢。

SplitChunksPlugin分包

Code Splitting拆包優(yōu)化的最終目標(biāo)是什么?

  1. 把更新頻率低的代碼和內(nèi)容頻繁變動(dòng)的代碼分離,把共用率較高的資源也拆出來(lái),最大限度利用瀏覽器緩存。
  2. 減少 http 請(qǐng)求次數(shù)的同時(shí)避免單個(gè)文件太大以免拖垮響應(yīng)速度,也就是拆包時(shí)盡量實(shí)現(xiàn)文件個(gè)數(shù)更少、單個(gè)文件體積更小。

這是這部分的官方文檔:https://webpack.docschina.org/plugins/split-chunks-plugin

以下是我的配置

optimization: {
    splitChunks: {
      chunks: 'initial',
      minSize: 20000,
      minRemainingSize: 0,
      minChunks: 1,
      maxAsyncRequests: 30,
      maxInitialRequests: 30,
      enforceSizeThreshold: 50000,
      cacheGroups: {
        defaultVendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10,
          reuseExistingChunk: true,
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        },
      },
    },

這樣可以將重復(fù)使用的一些js文件比如組件庫(kù)的代碼,拆成多份,按需分塊加載

路由按需懶加載

在React16.6.0版本中,新增了React.lazy函數(shù),它能讓你像常規(guī)組件一樣處理動(dòng)態(tài)引入的組件,配合 webpack 的 Code Splitting,只有當(dāng)組件被加載,對(duì)應(yīng)的資源才會(huì)導(dǎo)入,從而達(dá)到懶加載的效果。
一般懶加載和動(dòng)態(tài)路由一起使用,本文以靜態(tài)路由舉例,動(dòng)態(tài)路由多了個(gè)動(dòng)態(tài)生成路由的過(guò)程,技術(shù)層面本質(zhì)對(duì)優(yōu)化有用的還是懶加載。

// 路由懶加載demo
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import React, { Suspense, lazy } from 'react';

const Home = lazy(() => import('./routes/Home'));
const TestPage= lazy(() => import('./routes/TestPage'));

const App = () => (	
      <BrowserRouter>
         <Router>
    		<Suspense fallback={<div>Loading...</div>}>
      			<Routes>
        			<Route exact path="/" component={Home}/>
        			<Route path="/testPage" component={TestPage}/>
      			</Routes>
    		</Suspense>
  		</Router> 
      </BrowserRouter>
)

我使用的React版本是18.2.0,只需要按上面的寫(xiě)法,就可以直接實(shí)現(xiàn)代碼分塊+路由懶加載了,其余設(shè)置在creat-react-app的時(shí)候已經(jīng)自動(dòng)配置好相關(guān)文件了

這樣實(shí)現(xiàn)的懶加載其中代碼分包已經(jīng)集成進(jìn)去了,webpack會(huì)根據(jù)你路由懶加載這部分的分塊,自動(dòng)對(duì)代碼進(jìn)行拆包。

PS:其中有一點(diǎn)需要注意的是,<Suspense>一定是在<Router>的下級(jí),Route或Routes的上級(jí),不能放在Routes和Route之間,因?yàn)檫@個(gè)問(wèn)題我卡了大半天,一開(kāi)始看著demo隨便放的,沒(méi)在意,結(jié)果報(bào)錯(cuò)在網(wǎng)上查了半天也查不到,最后自己沒(méi)注意試出來(lái)的。

這樣弄完之后就沒(méi)有大的代碼塊了,只需讀取較小的文件,就能顯示出主頁(yè)來(lái),其余部分按需懶加載,用戶體驗(yàn)感upup

小技巧

還有個(gè)小技巧,如果是在路由的地方,頁(yè)面級(jí)別的懶加載,如果直接按上文那么寫(xiě)的話,在切換頁(yè)面的時(shí)候會(huì)閃爍一下,因?yàn)橛袀€(gè)懶加載的過(guò)程,就算加載的再快也會(huì)閃爍一下<Suspense>組件未加載完等待的效果。

這本身是沒(méi)什么問(wèn)題的,切頁(yè)面閃一下,但如果你當(dāng)前頁(yè)面有不希望閃爍的地方,它會(huì)跟著一起閃爍,無(wú)論那部分你是否設(shè)置了懶加載

舉個(gè)例子,就比如你路由用到了Layout,如下圖,你的<Suspense>組件不能放在Route中間,只能整個(gè)包裹Routes,所以要閃爍它都會(huì)一起閃,這樣給用戶的體驗(yàn)就會(huì)很差

解決方法:

把每個(gè)需要懶加載的頁(yè)面使用函數(shù)式組件包裝一下,把<Suspense>換個(gè)位置放,這樣layout就不會(huì)跟著其他懶加載頁(yè)面一起閃了

# 函數(shù)部分
const lazyComponent = (element) => {
        return (
            <Suspense fallback={<p>loading...</p>}>
                {element}
            </Suspense>
        )
    }
# ----------------------------------------------------------------------------
# return的ReactNode部分
<Route element={<StuLayout />}>
      <Route path='/StuIndex' index element={lazyComponent(<StuIndex />)} />
      <Route path='/StuIndex/ViewAnn' element={lazyComponent(<ViewAnn />)} />
</Route>

到此這篇關(guān)于React首頁(yè)加載速度優(yōu)化小結(jié)的文章就介紹到這了,更多相關(guān)React首頁(yè)加載速度內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • react中的雙向綁定你真的了解嗎

    react中的雙向綁定你真的了解嗎

    這篇文章主要為大家詳細(xì)介紹了react中的雙向綁定,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • React Antd Select組件輸入搜索時(shí)調(diào)用接口方式

    React Antd Select組件輸入搜索時(shí)調(diào)用接口方式

    為優(yōu)化Select組件中文輸入時(shí)的接口調(diào)用,使用lodash.debounce實(shí)現(xiàn)防抖,避免每輸入一個(gè)字母即觸發(fā)請(qǐng)求,待用戶點(diǎn)擊空格完成輸入后,再調(diào)用接口獲取數(shù)據(jù),提升性能與用戶體驗(yàn)
    2025-08-08
  • 淺談React19事件調(diào)度的設(shè)計(jì)思路

    淺談React19事件調(diào)度的設(shè)計(jì)思路

    本文主要介紹了React選擇MessageChannel作為事件調(diào)度機(jī)制的原因,essageChannel屬于宏任務(wù),延遲極低且不會(huì)阻塞渲染,能夠滿足React在不阻塞瀏覽器的前提下,盡可能多地推進(jìn)Fiber渲染進(jìn)度的需求
    2026-05-05
  • 在React Router中使用JWT的實(shí)現(xiàn)

    在React Router中使用JWT的實(shí)現(xiàn)

    本文主要介紹了在React Router中使用JWT的實(shí)現(xiàn),包括創(chuàng)建AuthProvider和AuthContext,實(shí)現(xiàn)ProtectedRoute組件,以及在React項(xiàng)目中處理公共路由和受校驗(yàn)保護(hù)路由,下面就來(lái)詳細(xì)的介紹一下
    2026-06-06
  • React Grid Layout基礎(chǔ)使用示例教程

    React Grid Layout基礎(chǔ)使用示例教程

    React Grid Layout是一個(gè)用于在React應(yīng)用程序中創(chuàng)建可拖拽和可調(diào)整大小的網(wǎng)格布局的庫(kù),通過(guò)使用React Grid Layout,我們可以輕松地創(chuàng)建自適應(yīng)的網(wǎng)格布局,并實(shí)現(xiàn)拖拽和調(diào)整大小的功能,本文介紹了React Grid Layout的基礎(chǔ)使用方法,感興趣的朋友一起看看吧
    2024-02-02
  • React更新組件狀態(tài)的常用方法

    React更新組件狀態(tài)的常用方法

    React是一個(gè)用于構(gòu)建用戶界面的JavaScript庫(kù),廣泛應(yīng)用于開(kāi)發(fā)現(xiàn)代單頁(yè)應(yīng)用(SPA),在 React 中,狀態(tài)管理是一個(gè)關(guān)鍵概念,因?yàn)樗苯佑绊懙浇M件的渲染和用戶體驗(yàn),本文將深入探討 React 中如何更新組件狀態(tài),需要的朋友可以參考下
    2025-06-06
  • React中狀態(tài)設(shè)置this.setState()的實(shí)現(xiàn)

    React中狀態(tài)設(shè)置this.setState()的實(shí)現(xiàn)

    本文對(duì)比了React中類(lèi)組件和函數(shù)組件的狀態(tài)管理方式,前者合并更新,后者替換更新,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-09-09
  • 詳解使用React進(jìn)行組件庫(kù)開(kāi)發(fā)

    詳解使用React進(jìn)行組件庫(kù)開(kāi)發(fā)

    本篇文章主要介紹了詳解使用React進(jìn)行組件庫(kù)開(kāi)發(fā),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-02-02
  • npx create-react-app xxx創(chuàng)建項(xiàng)目報(bào)錯(cuò)的解決辦法

    npx create-react-app xxx創(chuàng)建項(xiàng)目報(bào)錯(cuò)的解決辦法

    這篇文章主要介紹了npx create-react-app xxx創(chuàng)建項(xiàng)目報(bào)錯(cuò)的解決辦法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • React.Js添加與刪除onScroll事件的方法詳解

    React.Js添加與刪除onScroll事件的方法詳解

    這篇文章主要給大家介紹了關(guān)于React.Js添加與刪除onScroll事件的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11

最新評(píng)論

淮南市| 繁峙县| 锦屏县| 临夏县| 包头市| 西充县| 临颍县| 乌苏市| 思茅市| 扶余县| 永平县| 敦化市| 汉川市| 泾源县| 武城县| 平远县| 仲巴县| 三河市| 右玉县| 漠河县| 项城市| 兴义市| 稻城县| 阳曲县| 松原市| 贵德县| 南投县| 阿勒泰市| 佛山市| 建始县| 宜都市| 神农架林区| 道孚县| 随州市| 宁城县| 河间市| 平定县| 岫岩| 惠水县| 讷河市| 西乌|