国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目錄
目錄
初始加載性能指標(biāo)介紹
效能 DevTools 概述
項目設(shè)定
探索必要的 DevTools
探索 Lighthouse 面板
探索性能面板
附加練習(xí)
探索不同的網(wǎng)絡(luò)條件
非常慢的服務(wù)器
模擬不同的帶寬和延遲
CDN 的重要性
重複存取效能
使用 Cache-Control 頭控制瀏覽器快取
Cache-Control 和現(xiàn)代打包工具
我簡單的用例真的需要了解所有這些嗎?
首頁 web前端 js教程 React 開發(fā)人員的初始負(fù)載效能:深入研究

React 開發(fā)人員的初始負(fù)載效能:深入研究

Jan 27, 2025 pm 06:33 PM

深入探討網(wǎng)頁首屏加載性能及優(yōu)化策略

Initial load performance for React developers: investigative deep dive

目錄

  1. 初始加載性能指標(biāo)介紹
  2. 性能 DevTools 概述
    1. 項目設(shè)置
    2. 探索必要的 DevTools
  3. 探索不同的網(wǎng)絡(luò)條件
    1. 非常慢的服務(wù)器
    2. 模擬不同的帶寬和延遲
    3. CDN 的重要性
  4. 重複訪問性能
    1. 使用 Cache-Control 頭控制瀏覽器緩存
    2. Cache-Control 和現(xiàn)代打包工具
    3. 我簡單的用例真的需要了解所有這些嗎?

在 AI 驅(qū)動的代碼生成蓬勃發(fā)展的今天,編寫 React 代碼的重要性正在下降。現(xiàn)在任何人和任何東西都可以用 React 編寫應(yīng)用程序。但是編寫代碼一直只是難題的一部分。我們?nèi)匀恍枰獙⑽覀兊膽?yīng)用程序部署到某個地方,向用戶展示它們,使它們健壯,使它們快速,並做一百萬件其他事情。沒有 AI 可以接管這些。至少現(xiàn)在還不行。

因此,讓我們專注於今天如何使應(yīng)用程序快速運行。為此,我們需要暫時離開 React。因為在使某些東西變快之前,我們首先需要知道“快”是什麼,如何衡量它,以及什麼可以影響這種“快”。

劇透警告:除了學(xué)習(xí)項目之外,本文不會出現(xiàn) React。今天都是關(guān)於基礎(chǔ)知識的:如何使用性能工具,Core Web Vitals 簡介,Chrome 性能面板,初始加載性能是什麼,哪些指標(biāo)可以衡量它,以及緩存控制和不同的網(wǎng)絡(luò)條件如何影響它。

初始加載性能指標(biāo)介紹

當(dāng)我打開瀏覽器並嘗試導(dǎo)航到我喜歡的網(wǎng)站時會發(fā)生什麼?我在地址欄中輸入“http://www.miracleart.cn/link/63ea3fef646010a7255aec506626ea32 GET 請求,並接收 HTML 頁面作為返回。

Initial load performance for React developers: investigative deep dive

執(zhí)行此操作所需的時間稱為“Time To First Byte”(TTFB):從發(fā)送請求到結(jié)果開始到達(dá)之間的時間。接收 HTML 後,瀏覽器現(xiàn)在必須盡快將此 HTML 轉(zhuǎn)換為可用的網(wǎng)站。

它首先在屏幕上渲染所謂的“關(guān)鍵路徑”:可以向用戶顯示的最小和最重要的內(nèi)容。

Initial load performance for React developers: investigative deep dive

關(guān)鍵路徑中究竟應(yīng)該包含什麼是一個複雜的問題。理想情況下,一切都是為了讓用戶立即看到完整的體驗。但是同樣 - 什麼也沒有,因為它需要盡可能快,因為它是一條“關(guān)鍵”路徑。兩者同時是不可能的,所以需要妥協(xié)。

妥協(xié)是這樣的。瀏覽器假設(shè)要構(gòu)建“關(guān)鍵路徑”,它絕對至少需要以下類型的資源:

  • 它從服務(wù)器接收的初始 HTML - 用於構(gòu)建實際的 DOM 元素,從中構(gòu)建體驗。
  • 樣式化這些初始元素的重要 CSS 文件 - 否則,如果它在不等待它們的情況下繼續(xù),用戶會在一開始看到奇怪的未樣式化內(nèi)容“閃爍”。
  • 同步修改佈局的關(guān)鍵 JavaScript 文件。

瀏覽器在服務(wù)器的初始請求中獲取第一個(HTML)。它開始解析它,並在這樣做的過程中提取它需要完成“關(guān)鍵路徑”的 CSS 和 JS 文件的鏈接。然後,它發(fā)送請求以從服務(wù)器獲取它們,等待它們下載完畢,處理它們,將所有這些組合在一起,並在某個時刻結(jié)束時,在屏幕上繪製“關(guān)鍵路徑”像素。

由於瀏覽器在沒有這些關(guān)鍵資源的情況下無法完成初始渲染,因此它們被稱為“渲染阻塞資源”。當(dāng)然,並非所有 CSS 和 JS 資源都是渲染阻塞的。通常只有:

  • 大多數(shù) CSS,無論是內(nèi)聯(lián)的還是通過 標(biāo)籤。
  • 標(biāo)籤中不是異步或延遲的 JavaScript 資源。

渲染“關(guān)鍵路徑”的整個過程大致如下所示:

  • 瀏覽器開始解析初始 HTML
  • 在此過程中,它從標(biāo)籤中提取 CSS 和 JS 資源的鏈接。
  • 然後,它啟動下載過程並等待阻塞資源完成下載。
  • 在等待的同時,如果可能,它會繼續(xù)處理 HTML。
  • 接收所有關(guān)鍵資源後,也會處理它們。
  • 最後,它完成需要完成的工作並繪製界面的實際像素。

這個時間點就是我們所說的首次繪製 (FP)。這是用戶第一次有機(jī)會在屏幕上看到某些東西。是否會發(fā)生取決於服務(wù)器發(fā)送的 HTML。如果那裡有一些有意義的東西,例如文本或圖像,那麼這一點也將是首次內(nèi)容繪製 (FCP) 發(fā)生的時間。如果 HTML 只是一個空 div,那麼 FCP 將稍後發(fā)生。

Initial load performance for React developers: investigative deep dive

首次內(nèi)容繪製 (FCP) 是最重要的性能指標(biāo)之一,因為它衡量的是感知到的初始加載?;旧?,這是用戶對您的網(wǎng)站速度的初步印象。

直到這一刻,使用者只是在盯著空白螢?zāi)灰е讣?。根?jù) Google 的說法,良好的 FCP 數(shù)字是低於 1.8 秒。之後,用戶將開始對您的網(wǎng)站可以提供的內(nèi)容失去興趣,並可能開始離開。

但是,F(xiàn)CP 並不完美。如果網(wǎng)站以旋轉(zhuǎn)器或某些加載畫面開始加載,則 FCP 指標(biāo)將表示該內(nèi)容。但用戶不太可能只是為了查看花哨的加載畫面而導(dǎo)航到該網(wǎng)站。大多數(shù)時候,他們想要存取內(nèi)容。

為此,瀏覽器需要完成它開始的工作。它等待其餘的非阻塞 JavaScript,執(zhí)行它,將源自它的更改應(yīng)用於螢?zāi)簧系?DOM,下載圖像,並以其他方式完善用戶體驗。

在這個過程中的某個時間點,就會發(fā)生最大內(nèi)容繪製 (LCP) 時間。它不是像 FCP 那樣非常第一個元素,而是頁面上的主要內(nèi)容區(qū)域 - 視窗中可見的最大文字、圖像或影片。根據(jù) Google 的說法,這個數(shù)字理想情況下應(yīng)該低於 2.5 秒。超過這個數(shù)字,用戶會認(rèn)為網(wǎng)站速度慢。

Initial load performance for React developers: investigative deep dive

所有這些指標(biāo)都是 Google 的 Web Vitals 的一部分 - 一組代表頁面上使用者體驗的指標(biāo)。 LCP 是三個核心 Web Vitals之一 - 三個指標(biāo)代表使用者體驗的不同部分。 LCP 負(fù)責(zé)載入效能。

這些指標(biāo)可以透過 Lighthouse 來衡量。 Lighthouse 是 Google 的效能工具,它整合到 Chrome DevTools 中,也可以透過 shell 腳本、Web 介面或節(jié)點模組運作。您可以將其作為節(jié)點模組使用,以便在建置中運行它並在生產(chǎn)環(huán)境中出現(xiàn)回歸之前檢測到它們。使用整合的 DevTools 版本進(jìn)行本地調(diào)試和測試。以及 Web 版本來檢查競爭對手的效能。

效能 DevTools 概述

以上是對過程的非常簡短和簡化的解釋。但這已經(jīng)有很多縮寫和理論讓人的頭腦混亂。對我個人而言,閱讀這樣的內(nèi)容是沒有用的。除非我能看到它在行動中,並能親自動手操作,否則我會立即忘記所有內(nèi)容。

對於這個特定主題,我發(fā)現(xiàn)完全理解這些概念的最簡單方法是在半真實的頁面上模擬不同的場景,並查看它們?nèi)绾胃淖兘Y(jié)果。所以在進(jìn)行更多理論(還有很多?。┲?,讓我們先這樣做。

項目設(shè)定

如果您願意,您可以在您自己的專案上進(jìn)行以下所有模擬 - 結(jié)果應(yīng)該或多或少相同。但是,為了更受控制和簡化的環(huán)境,我建議您使用我為本文準(zhǔn)備的學(xué)習(xí)項目。您可以在這裡訪問它:http://www.miracleart.cn/link/def14e8541708294d7558fdf2126ef27

先安裝所有相依性:

<code>npm install</code>

建置專案:

<code>npm run build</code>

啟動伺服器:

<code>npm run start</code>

您應(yīng)該在「http://www.miracleart.cn/link/66e8d052ec2230c66bd11ee6b5a0e3c8。

探索必要的 DevTools

在 Chrome 中開啟要分析的網(wǎng)站並開啟 Chrome DevTools。找到那裡的“性能”和“Lighthouse”面板並將它們放在一起。我們需要兩者。

此外,在本文中執(zhí)行任何其他操作之前,請確保已啟用「停用快取」複選框。它應(yīng)該位於最頂部的“網(wǎng)路”面板中。

Initial load performance for React developers: investigative deep dive

這樣我們就可以模擬首次訪客 - 從未造訪過我們網(wǎng)站的人,而且瀏覽器還沒有快取任何資源。

探索 Lighthouse 面板

現(xiàn)在打開 Lighthouse 面板。您應(yīng)該在那裡看到一些設(shè)定和“分析頁面載入”按鈕。

Initial load performance for React developers: investigative deep dive

對於本節(jié),我們感興趣的是「導(dǎo)航」模式 - 它將對頁面的初始載入進(jìn)行詳細(xì)分析。該報告將為您提供以下分?jǐn)?shù):

Initial load performance for React developers: investigative deep dive

本地性能完美無缺,這並不奇怪 - 一切都「在我的機(jī)器上運行」。

還會有以下指標(biāo):

Initial load performance for React developers: investigative deep dive

我們本文所需的 FCP 和 LCP 值就在頂部。

下面,您將看到一個可以幫助您提高分?jǐn)?shù)的建議清單。

Initial load performance for React developers: investigative deep dive

每個建議都可以展開,您將在那裡找到更詳細(xì)的信息,有時還會找到解釋該特定主題的連結(jié)。並非所有這些都可以採取行動,但它是一個開始學(xué)習(xí)表現(xiàn)並了解可以改進(jìn)它的不同事物的絕佳工具。光是閱讀這些報告和相關(guān)連結(jié)就可以花費數(shù)小時。

但是,Lighthouse 只提供表面信息,不允許您模擬慢速網(wǎng)路或低 ??CPU 等不同場景。它只是一個很好的切入點和一個追蹤性能隨時間變化的絕佳工具。要更深入地了解正在發(fā)生的事情,我們需要「性能」面板。

探索性能面板

首次載入時,「效能」面板應(yīng)如下所示:

Initial load performance for React developers: investigative deep dive

它顯示了三個核心 Web Vitals 指標(biāo),其中一個是我們的 LCP,使您可以模擬慢速網(wǎng)絡(luò)和 CPU,以及隨著時間推移記錄性能詳細(xì)信息的能力。

在面板頂部找到並選中“屏幕截圖”複選框,然後單擊“記錄並重新加載”按鈕,當(dāng)網(wǎng)站重新加載自身時 - 停止記錄。這將是您對頁面在初始加載期間發(fā)生情況的詳細(xì)報告。

此報告將包含幾個部分。

最頂部是常規(guī)的“時間軸概述”部分。

Initial load performance for React developers: investigative deep dive

您將在這裡看到網(wǎng)站上正在發(fā)生某些事情,但沒有更多內(nèi)容。當(dāng)您將鼠標(biāo)懸停在其上時 - 將顯示正在發(fā)生的事情的屏幕截圖,並且您將能夠選擇並放大到特定範(fàn)圍以仔細(xì)查看。

在下面是網(wǎng)絡(luò)部分。展開後,您將看到所有正在下載的外部資源以及它們在時間軸上的確切時間。當(dāng)將鼠標(biāo)懸停在特定資源上時,您將看到有關(guān)在下載的哪個階段花費多少時間的詳細(xì)信息。帶有紅色角的資源將指示阻塞資源。

Initial load performance for React developers: investigative deep dive

如果您正在使用學(xué)習(xí)項目,您將看到完全相同的圖片,並且此圖片與我們在上一節(jié)中逐字逐句進(jìn)行的內(nèi)容相匹配:

  • 一開始,有一個藍(lán)色塊 - 獲取網(wǎng)站 HTML 的請求
  • 加載完成後,稍作暫停(解析 HTML),兩個獲取更多資源的請求發(fā)出。
  • 其中一個(黃色)用於 JavaScript - 非阻塞。
  • 另一個(紫色)用於 CSS,這是一個阻塞。

如果您現(xiàn)在打開您的學(xué)習(xí)項目代碼並查看 dist 文件夾,源代碼將與這種行為相匹配:

  • 將有一個 index.html 文件和 assets 文件夾中的 .css 和 .js 文件
  • 在 index.html 文件中的部分中,將有一個 標(biāo)籤指向 CSS 文件。正如我們所知, 標(biāo)籤中的 CSS 資源是渲染阻塞的,所以這可以檢查出來。
  • 此外,在其中還有一個 <script> 標(biāo)籤指向 asset 文件夾中的 JavaScript 文件。它既不是延遲的也不是異步的,但它具有 type="module"。這些是自動延遲的,所以這也檢查出來了 - 面板中的 JavaScript 文件是非阻塞的。 </script>

附加練習(xí)

如果您正在處理某個項目,請記錄其初始加載性能並查看“網(wǎng)絡(luò)”面板。您可能會看到更多正在下載的資源。

  • 您有多少個渲染阻塞資源?所有這些都是必要的嗎?
  • 您知道項目的“入口”點在哪里以及阻塞資源如何在 <script> 部分中出現(xiàn)嗎?嘗試使用您的 npm build 變體構(gòu)建項目並蒐索它們。提示:- 如果您有一個純基於 webpack 的項目,請查找 webpack.config.js 文件。 HTML 入口點的路徑應(yīng)該在裡面。 </script>
  • 如果您使用 Vite,請查看 dist 文件夾 - 與學(xué)習(xí)項目相同
  • 如果您使用 Next.js App 路由器 - 請查看 .next/server/app

在“網(wǎng)絡(luò)”部分下,您可以找到“幀”和“計時”部分。

Initial load performance for React developers: investigative deep dive

這些非???。在“計時”部分,您可以看到我們之前討論過的所有指標(biāo)(FP、FCP、LCP),以及我們尚未討論的一些指標(biāo)。當(dāng)將鼠標(biāo)懸停在指標(biāo)上時,您可以看到它花費的確切時間。單擊它們將更新最底部的“摘要”選項卡,您將在其中找到有關(guān)此指標(biāo)的信息和了解更多信息的鏈接。 DevTools 現(xiàn)在都是關(guān)於教育人們的。

最後是部分。這是在記錄的時間軸期間在主線程中發(fā)生的事情。

Initial load performance for React developers: investigative deep dive

我們在這裡可以看到諸如“解析 HTML”或“佈局”之類的內(nèi)容以及它花費了多長時間。黃色部分與 JavaScript 相關(guān),它們有點沒用,因為我們使用的是帶有壓縮 JavaScript 的生產(chǎn)版本。但即使在這種狀態(tài)下,它也能讓我們大致了解 JavaScript 執(zhí)行與 HTML 解析和繪製佈局相比需要多長時間,例如。

當(dāng)網(wǎng)絡(luò)都打開並放大以佔據(jù)整個屏幕時,它對於性能分析尤其有用。

Initial load performance for React developers: investigative deep dive

從這裡,我可以看出我的服務(wù)器速度非常快,捆綁包也很快很小。沒有一個網(wǎng)絡(luò)任務(wù)是瓶頸;它們不需要任何大量時間,它們之間,瀏覽器只是在閒逛並做它自己的事情。因此,如果我想在這裡加快初始加載速度,我需要研究為什麼“解析 HTML”這麼慢 - 它是圖表上最長的任務(wù)。

或者,如果我們查看絕對數(shù)字 - 我不應(yīng)該在這裡做任何事情,從性能方面來說。整個初始加載時間少於200 毫秒,遠(yuǎn)低於Google 建議的閾值?但這正在發(fā)生,因為我是在本地運行此測試(因此沒有實際的網(wǎng)絡(luò)成本),在一臺非常快的筆記本電腦上,並且使用非?;镜姆?wù)器。

是時候模擬現(xiàn)實生活了。

探索不同的網(wǎng)絡(luò)條件

非常慢的服務(wù)器

首先,讓我們使服務(wù)器更逼真?,F(xiàn)在,第一個“藍(lán)色”步驟大約需要 50 毫秒,其中 40 毫秒只是在等待。

Initial load performance for React developers: investigative deep dive

在現(xiàn)實生活中,服務(wù)器將執(zhí)行某些操作,檢查權(quán)限,生成某些內(nèi)容,再次檢查權(quán)限(因為它有很多遺留代碼,並且三遍檢查丟失了),否則將很忙。

導(dǎo)航到學(xué)習(xí)項目中的 backend/index.ts 文件 (http://www.miracleart.cn/link/def14e8541708294d7558fdf2126ef27)。找到註釋掉的 // await sleep(500),並取消註釋它。這將使服務(wù)器在返回 HTML 之前延遲 500 毫秒 - 這對於舊的複雜服務(wù)器來說似乎足夠合理。

重新構(gòu)建項目 (npm run build),重新啟動它 (npm run start) 並重新運行性能記錄。

除了初始藍(lán)線之外,時間軸上沒有任何變化 - 與其餘內(nèi)容相比,它現(xiàn)在非常長。

Initial load performance for React developers: investigative deep dive

這種情況突出了在進(jìn)行任何性能優(yōu)化之前查看全局並識別瓶頸的重要性。 LCP 值約為 650 毫秒,其中約 560 毫秒用於等待初始 HTML。它的 React 部分約為 50 毫秒。即使我設(shè)法將其減半並將其減少到 25 毫秒,在整體情況中,它也只有 4%。而將其減半將需要大量的努力。更有效的策略可能是專注於服務(wù)器並找出它為什麼這麼慢。

模擬不同的帶寬和延遲

並非每個人都生活在 1 千兆位連接的世界中。例如,在澳大利亞,50 兆位/秒是高速互聯(lián)網(wǎng)連接之一,每月將花費您約 90 澳元。當(dāng)然,它不是 3G,全世界很多人都被困住了。但仍然,每次我聽到歐洲人吹噓他們的 1 千兆位/秒或 10 歐元的互聯(lián)網(wǎng)計劃時,我都會哭泣。

無論如何。讓我們模擬這個不太好的澳大利亞互聯(lián)網(wǎng),看看性能指標(biāo)會發(fā)生什麼。為此,清除性能選項卡中的現(xiàn)有記錄(重新加載和記錄按鈕附近的按鈕)。網(wǎng)絡(luò)設(shè)置面板應(yīng)該顯示出來:

Initial load performance for React developers: investigative deep dive

如果它沒有出現(xiàn)在您的 Chrome 版本中,則相同的設(shè)置應(yīng)該在“網(wǎng)絡(luò)”選項卡中可用。

在“網(wǎng)絡(luò)”下拉菜單中添加一個新的配置文件,使用以下數(shù)字:

  • 配置文件名稱:“平均互聯(lián)網(wǎng)帶寬”
  • 下載:50000(50 Mbps)
  • 上傳:15000(15 Mbps)
  • 延遲:40(一般互聯(lián)網(wǎng)連接的平均值)

Initial load performance for React developers: investigative deep dive

現(xiàn)在在下拉菜單中選擇該配置文件並再次運行性能記錄。

你看到了什麼?對我來說,它看起來像這樣。

LCP 值幾乎沒有變化 - 從 640 毫秒略微增加到 700 毫秒。初始藍(lán)色“服務(wù)器”部分沒有任何變化,這是可以解釋的:它只發(fā)送最基本的 HTML,因此下載它不應(yīng)該花費很長時間。

但是可下載資源和主線程之間的關(guān)係發(fā)生了巨大變化。

Initial load performance for React developers: investigative deep dive

我現(xiàn)在可以清楚地看到渲染阻塞 CSS文件的影響。 “解析 HTML”任務(wù)已經(jīng)完成,但瀏覽器正在閒置並等待 CSS - 在下載之前無法繪製任何內(nèi)容。將其與之前的圖片進(jìn)行比較,在之前的圖片中,資源幾乎是即時下載的,而瀏覽器正在解析 HTML。

之後,從技術(shù)上講,瀏覽器本可以繪製某些內(nèi)容 - 但沒有任何內(nèi)容,我們只在 HTML 文件中發(fā)送一個空 div。因此,瀏覽器繼續(xù)等待,直到下載並執(zhí)行 javascript 文件。

這個大約 60 毫秒的等待差距正是我看到的 LCP 的增加。

進(jìn)一步降低速度以查看它的進(jìn)展情況。創(chuàng)建一個新的網(wǎng)絡(luò)配置文件,將其命名為“低互聯(lián)網(wǎng)帶寬”,從“低互聯(lián)網(wǎng)帶寬”配置文件複製下載/上傳數(shù)字,並將延遲設(shè)置為 40 毫秒。

Initial load performance for React developers: investigative deep dive

並再次運行測試。

LCP 值現(xiàn)在已增加到近 500 毫秒。 JavaScript 下載大約需要 300 毫秒。相對而言,“解析 HTML”任務(wù)和 JavaScript 執(zhí)行任務(wù)的重要性正在減小。

Initial load performance for React developers: investigative deep dive

附加練習(xí)

如果您有自己的項目,請嘗試在其上運行此測試。

  • 下載所有關(guān)鍵路徑資源需要多長時間?
  • 下載所有 JavaScript 檔案需要多長時間?
  • 此下載在「解析 HTML」任務(wù)之後會導(dǎo)致多大的差距?
  • 在主執(zhí)行緒中,「解析 HTML」和 JavaScript 執(zhí)行任務(wù)相對於資源下載有多大?
  • 它如何影響 LCP 指標(biāo)?

資源列內(nèi)部發(fā)生的事情也很有趣。將滑鼠懸停在黃色 JavaScript 條上。您應(yīng)該在那裡看到類似這樣的內(nèi)容:

Initial load performance for React developers: investigative deep dive

這裡最有趣的部分是“發(fā)送請求並等待”,大約需要 40 毫秒。將滑鼠懸停在其餘的網(wǎng)路資源上 - 所有這些都將擁有它。那是我們的延遲,我們設(shè)定為 40 的網(wǎng)路延遲。許多事情都會影響延遲數(shù)字。網(wǎng)路連線的類型就是其中之一。例如,平均 3G 連線的頻寬為 10/1 Mbps,延遲在 100 到 300 毫秒之間。

要模擬這一點,請建立一個新的網(wǎng)路設(shè)定文件,將其命名為“平均 3G”,從“低網(wǎng)路頻寬”設(shè)定檔複製下載/上傳數(shù)字,並將延遲設(shè)定為 300 毫秒。

再次運行分析。所有網(wǎng)路資源的「發(fā)送請求並等待」都應(yīng)增加到約 300 毫秒。這將進(jìn)一步推動 LCP 數(shù)字:對我來說是1.2 秒

現(xiàn)在是有趣的部分:如果我將頻寬恢復(fù)到超高速但保持低延遲會發(fā)生什麼?讓我們嘗試此設(shè)定:

  • 下載:1000 Mbps
  • 上傳:100 Mbps
  • 延遲:300 毫秒

如果您的伺服器位於挪威某個地方,而客戶端是富有的澳洲人,則很容易發(fā)生這種情況。

這是結(jié)果:

Initial load performance for React developers: investigative deep dive

LCP 數(shù)字約為960 毫秒。它比我們之前嘗試過的最慢的網(wǎng)路速度還要差!在這種情況下,捆綁包大小並不重要,CSS 大小根本不重要。即使您將兩者都減半,LCP 指標(biāo)幾乎不會移動。高延遲勝過一切。

這讓我想到了每個人都應(yīng)該實現(xiàn)的第一個效能改進(jìn),如果他們還沒有實現(xiàn)的話。它被稱為「確保靜態(tài)資源始終透過 CDN 提供服務(wù)」。

CDN 的重要性

CDN(內(nèi)容分發(fā)網(wǎng)路)基本上是任何前端效能相關(guān)工作的第 0 步,甚至在開始考慮更花俏的東西(如程式碼分割或伺服器元件)之前。

任何 CDN(內(nèi)容分發(fā)網(wǎng)路)的主要目的是減少延遲並儘快將內(nèi)容交付給最終用戶。它們?yōu)榇藢嵤┝硕喾N策略。本文最重要的兩個是「分散式伺服器」和「快取」。

CDN 供應(yīng)商將在不同的地理位置擁有多個伺服器。這些伺服器可以儲存靜態(tài)資源的副本,並在瀏覽器請求它們時將它們傳送給使用者。 CDN 基本上是您原始伺服器周圍的一個軟層,可以保護(hù)它免受外部影響並最大限度地減少它與外部世界的互動。它有點像內(nèi)向者的 AI 助手,它可以在無需讓真人參與的情況下處理典型的對話。

在上面的範(fàn)例中,我們的伺服器位於挪威,客戶端位於澳大利亞,我們有這樣的圖片:

Initial load performance for React developers: investigative deep dive

有了中間的 CDN,圖片就會改變。 CDN 將在更靠近用戶的地方擁有一個伺服器,例如,也在澳洲某個地方。在某個時刻,CDN 將從原始伺服器接收靜態(tài)資源的副本。之後,來自澳洲或附近任何地方的用戶都將獲得這些副本,而不是來自挪威伺服器的原始副本。

它實現(xiàn)了兩個重要的事情。首先,原始伺服器上的負(fù)載減少了,因為用戶不再需要直接存取它。其次,用戶現(xiàn)在可以更快地獲得這些資源,因為他們不再需要跨越海洋來下載一些 JavaScript 檔案了。

Initial load performance for React developers: investigative deep dive

而我們上面模擬中的 LCP 值從960 毫秒下降到 640 毫秒?。

重複存取效能

到目前為止,我們只討論了首次訪問性能 - 從未訪問過您網(wǎng)站的人的性能。但希望該網(wǎng)站如此出色,以至於大多數(shù)首次訪客都會變成??汀;蛘咧辽偎麄冊诘谝淮渭虞d後不會離開,瀏覽幾個頁面,也許會購買一些東西。在這種情況下,我們通常期望瀏覽器會快取靜態(tài)資源(如 CSS 和 JS)- 即在本地保存它們的副本,而不是總是下載它們。

讓我們看看在這種情況下表現(xiàn)圖表和數(shù)字如何變化。

再次開啟學(xué)習(xí)項目。在開發(fā)工具中,將“網(wǎng)路”設(shè)定為我們之前創(chuàng)建的“平均 3G” - 具有高延遲和低頻寬,這樣我們就可以立即看到差異。並確保「停用網(wǎng)路快取」複選框未選取。

Initial load performance for React developers: investigative deep dive

首先,刷新瀏覽器以確保我們正在消除首次訪客的情況。然後刷新並測量性能。

如果您使用的是學(xué)習(xí)項目,最終結(jié)果可能會有些令人驚訝,因為它看起來像這樣:

Initial load performance for React developers: investigative deep dive

CSS 和 JavaScript 檔案在網(wǎng)路標(biāo)籤中仍然非常突出,我看到它們在「發(fā)送請求並等待」中大約有 300 毫秒 - 我們在「平均 3G」設(shè)定檔中設(shè)定的延遲設(shè)定。結(jié)果,LCP 並不像它可能的那麼低,而且當(dāng)瀏覽器只是等待阻塞 CSS 時,我有一個 300 毫秒的差距。

發(fā)生了什麼事?瀏覽器不應(yīng)該快取這些東西嗎?

使用 Cache-Control 頭控制瀏覽器快取

我們現(xiàn)在需要使用「網(wǎng)路」面板來了解發(fā)生了什麼。打開它並在那裡找到 CSS 文件。它應(yīng)該如下圖所示:

Initial load performance for React developers: investigative deep dive

這裡最有趣的是「狀態(tài)」列和「大小」。在「大小」中,它絕對不是整個 CSS 檔案的大小。它太小了。在「狀態(tài)」中,它不是我們通常的 200「一切正常」?fàn)顟B(tài),而是不同的東西 - 304 狀態(tài)。

這裡有兩個問題 - 為什麼是 304 而不是 200,以及為什麼根本發(fā)送了請求?為什麼快取不起作用?

首先,304 回應(yīng)。這是一個配置良好的伺服器為條件請求發(fā)送的回應(yīng) - 其中回應(yīng)根據(jù)各種規(guī)則而變化。此類請求經(jīng)常用於控制瀏覽器快取。

例如,當(dāng)伺服器接收到 CSS 檔案的請求時,它可以檢查上次修改檔案的時間。如果此日期與瀏覽器端快取檔案中的日期相同,則它將傳回帶有空白正文的 304(這就是為什麼它只有 223 B)。這表示瀏覽器可以安全地重新使用它已經(jīng)擁有的檔案。無需浪費頻寬並再次重新下載它。

這就是為什麼我們在效能圖片中看到很大的「發(fā)送請求並等待」數(shù)字 - 瀏覽器要求伺服器確認(rèn) CSS 檔案是否仍然是最新的。這就是為什麼那裡的“內(nèi)容下載”是 0.33 毫秒 - 伺服器返回“304 未修改”,瀏覽器只是重新使用了先前下載的檔案。

附加練習(xí)

  1. 在學(xué)習(xí)專案中,前往 dist/assets 資料夾並重新命名 CSS 檔案
  2. 前往 dist/index.html 檔案並更新重命名 CSS 檔案的路徑
  3. 刷新已開啟的頁面並開啟「網(wǎng)路」選項卡,您應(yīng)該會看到 CSS 檔案以新名稱、200 狀態(tài)和正確的大小出現(xiàn) - 它已再次下載。這被稱為“快取清除” - 一種強(qiáng)制瀏覽器重新下載它可能已快取的資源的方法。
  4. 再次刷新頁面 - 它已返回到 304 狀態(tài)並重新使用快取的檔案。

現(xiàn)在,對於第二個問題 - 為什麼根本發(fā)送了這個請求?

此行為由伺服器設(shè)定為回應(yīng)的 Cache-Control 標(biāo)頭控制。點擊“網(wǎng)頁”面板中的 CSS 檔案以查看請求/回應(yīng)的詳細(xì)資訊。在「標(biāo)頭」標(biāo)籤的「回應(yīng)標(biāo)頭」區(qū)塊中尋找「Cache-Control」值:

Initial load performance for React developers: investigative deep dive

在此標(biāo)頭內(nèi),可以以不同的組合組合多個指令,用逗號分隔。在我們的例子中,有兩個:

  • max-age 帶有一個數(shù)字 - 它控制此特定響應(yīng)將存儲多長時間(以秒為單位)
  • must-revalidate - 它指示瀏覽器如果響應(yīng)已過期,則始終向服務(wù)器發(fā)送新鮮版本的請求。如果響應(yīng)在緩存中存在的時間超過 max-age 值,則響應(yīng)將過期。

因此,基本上,此標(biāo)頭告訴瀏覽器:

  • 可以將此響應(yīng)存儲在您的緩存中,但過一段時間後要再次與我核實。
  • 順便說一句,您可以保留該緩存的時間正好是秒。祝你好運。

結(jié)果,瀏覽器總是與服務(wù)器核實,並且從不立即使用緩存。

但是,我們可以很容易地改變這一點 - 我們只需要將 max-age 數(shù)字更改為 0 到 31536000(一年,允許的最大秒數(shù))之間即可。為此,在您的學(xué)習(xí)項目中,轉(zhuǎn)到 backend/index.ts 文件,找到設(shè)置 max-age=0 的位置,並將其更改為 31536000(一年)。刷新頁面幾次,您應(yīng)該在“網(wǎng)絡(luò)”選項卡中看到 CSS 文件的以下內(nèi)容:

Initial load performance for React developers: investigative deep dive

請注意,現(xiàn)在“狀態(tài)”列已變灰,對於“大小”,我們看到“(內(nèi)存緩存)”。 CSS 文件現(xiàn)在從瀏覽器的緩存中提供服務(wù),並且一年內(nèi)將一直如此。刷新頁面幾次以查看它不會更改。

現(xiàn)在,對於處理緩存標(biāo)頭的全部要點:讓我們再次測量頁面的性能。不要忘記設(shè)置“平均 3G”配置文件設(shè)置並保持“禁用緩存”設(shè)置未選中。

結(jié)果應(yīng)該類似於:

Initial load performance for React developers: investigative deep dive

儘管延遲很高,“發(fā)送請求並等待”部分幾乎減少到零,“解析 HTML”和 JavaScript 評估之間的差距幾乎消失了,我們的 LCP 值又回到了 ~650 毫秒。

附加練習(xí)

  1. 將 max-age 值更改為 10(10 秒)
  2. 選中“禁用緩存”複選框並刷新頁面以刪除緩存。
  3. 取消選中復(fù)選框並再次刷新頁面 - 這次應(yīng)該從內(nèi)存緩存中提供服務(wù)。
  4. 等待 10 秒,然後再次刷新頁面。因為 max-age 只有 10 秒,所以瀏覽器將再次檢查資源,服務(wù)器將再次返回 304。
  5. 立即刷新頁面 - 它應(yīng)該再次從內(nèi)存中提供服務(wù)。

Cache-Control 和現(xiàn)代打包工具

上述信息是否意味著緩存是我們的性能靈丹妙藥,我們應(yīng)該盡可能積極地緩存所有內(nèi)容?絕對不是!除了其他一切之外,創(chuàng)建“不精通技術(shù)的客戶”和“需要通過電話解釋如何清除瀏覽器緩存”的組合的可能性將導(dǎo)致最資深的開發(fā)人員出現(xiàn)恐慌性發(fā)作。

有數(shù)百萬種優(yōu)化緩存的方法,數(shù)百萬種在Cache-Control 標(biāo)頭中的指令與其他可能或可能不會影響緩存持續(xù)時間的標(biāo)頭的組合,這也可能或可能不取決於服務(wù)器的實現(xiàn)。可能僅關(guān)於此主題本身就可以編寫幾本書的信息。如果您想成為緩存大師,請從https://web.dev/和 MDN 資源上的文章開始,然後按照麵包屑進(jìn)行操作。

不幸的是,沒有人能告訴你,“這是適用於所有內(nèi)容的五種最佳緩存策略”。充其量,答案可能是:“如果您有這個用例,結(jié)合這個、這個和這個,那麼這個緩存設(shè)置組合是一個不錯的選擇,但要注意這些問題”。這一切都?xì)w結(jié)於了解您的資源、構(gòu)建系統(tǒng)、資源更改的頻率、緩存的安全性以及錯誤操作的後果。

但是,有一個例外。一種例外,即存在明確的“最佳實踐”:使用現(xiàn)代工具構(gòu)建的網(wǎng)站的 JavaScript 和 CSS 文件。現(xiàn)代打包工具(如 Vite、Rollup、Webpack 等)可以創(chuàng)建“不可變”的 JS 和 CSS 文件。它們當(dāng)然不是真正“不可變”的。但是這些工具使用依賴於文件內(nèi)容的哈希字符串生成文件名稱。如果文件內(nèi)容髮生更改,則哈希會更改,文件名稱也會更改。結(jié)果,當(dāng)網(wǎng)站部署時,無論緩存設(shè)置如何,瀏覽器都將重新獲取文件的全新副本。緩存已“清除”,就像我們之前手動重命名 CSS 文件時一樣。

例如,查看學(xué)習(xí)項目中的 dist/assets 文件夾。 JS 和 CSS 文件都有 index-[hash] 文件名。記住這些名稱並運行 npm run build 幾次。名稱保持不變,因為這些文件的內(nèi)容沒有改變。

現(xiàn)在轉(zhuǎn)到 src/App.tsx 文件並在某個地方添加類似 console.log('bla') 的內(nèi)容。再次運行 npm run build 並檢查生成的文件。您應(yīng)該看到 CSS 文件名保持不變,但 JS 文件名已更改。當(dāng)此網(wǎng)站部署時,下次重複用戶訪問它時,瀏覽器將請求一個在其緩存中從未出現(xiàn)過的完全不同的 JS 文件。緩存已清除。

附加練習(xí)

查找項目的 dist 文件夾的等效項並運行您的構(gòu)建命令。

  • 文件名是什麼樣的?類似於哈希,還是普通的 index.js、index.css 等?
  • 當(dāng)您再次運行構(gòu)建命令時,文件名是否會更改?
  • 如果您在代碼中的某個位置進(jìn)行簡單的更改,有多少文件名會更改?

如果您的構(gòu)建系統(tǒng)就是這樣配置的 - 您很幸運。您可以安全地配置服務(wù)器以設(shè)置生成資產(chǎn)的最大 max-age 標(biāo)頭。如果您同樣對所有圖像進(jìn)行版本控制 - 更好的是,您還可以將圖像包含到列表中。

根據(jù)網(wǎng)站及其用戶及其行為,這可能會為您免費提供初始加載的相當(dāng)不錯的性能提升。

我簡單的用例真的需要了解所有這些嗎?

此時,您可能正在想類似這樣的事情,“你瘋了。我周末用Next.js 構(gòu)建了一個簡單的網(wǎng)站,並在2 分鐘內(nèi)將其部署到Vercel/Netlify/HottestNewProvider。當(dāng)然,這些現(xiàn)代工具會為我處理所有這些。”這很公平。我也這麼認(rèn)為。但後來我實際上檢查了一下,哇,我很驚訝?

我的兩個項目對 CSS 和 JS 文件都有 max-age=0 和 must-revalidate。事實證明,這是我的 CDN 提供商的默認(rèn)設(shè)置???♀?。當(dāng)然,他們有理由

以上是React 開發(fā)人員的初始負(fù)載效能:深入研究的詳細(xì)內(nèi)容。更多資訊請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Java vs. JavaScript:清除混亂 Java vs. JavaScript:清除混亂 Jun 20, 2025 am 12:27 AM

Java和JavaScript是不同的編程語言,各自適用於不同的應(yīng)用場景。 Java用於大型企業(yè)和移動應(yīng)用開發(fā),而JavaScript主要用於網(wǎng)頁開發(fā)。

JavaScript評論:簡短說明 JavaScript評論:簡短說明 Jun 19, 2025 am 12:40 AM

JavascriptconcommentsenceenceEncorenceEnterential gransimenting,reading and guidingCodeeXecution.1)單inecommentsareusedforquickexplanations.2)多l(xiāng)inecommentsexplaincomplexlogicorprovideDocumentation.3)

如何在JS中與日期和時間合作? 如何在JS中與日期和時間合作? Jul 01, 2025 am 01:27 AM

JavaScript中的日期和時間處理需注意以下幾點:1.創(chuàng)建Date對像有多種方式,推薦使用ISO格式字符串以保證兼容性;2.獲取和設(shè)置時間信息可用get和set方法,注意月份從0開始;3.手動格式化日期需拼接字符串,也可使用第三方庫;4.處理時區(qū)問題建議使用支持時區(qū)的庫,如Luxon。掌握這些要點能有效避免常見錯誤。

為什麼要將標(biāo)籤放在的底部? 為什麼要將標(biāo)籤放在的底部? Jul 02, 2025 am 01:22 AM

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

JavaScript與Java:開發(fā)人員的全面比較 JavaScript與Java:開發(fā)人員的全面比較 Jun 20, 2025 am 12:21 AM

JavaScriptIspreferredforredforwebdevelverment,而Javaisbetterforlarge-ScalebackendsystystemsandSandAndRoidApps.1)JavascriptexcelcelsincreatingInteractiveWebexperienceswebexperienceswithitswithitsdynamicnnamicnnamicnnamicnnamicnemicnemicnemicnemicnemicnemicnemicnemicnddommanipulation.2)

JavaScript:探索用於高效編碼的數(shù)據(jù)類型 JavaScript:探索用於高效編碼的數(shù)據(jù)類型 Jun 20, 2025 am 12:46 AM

javascripthassevenfundaMentalDatatypes:數(shù)字,弦,布爾值,未定義,null,object和symbol.1)numberSeadUble-eaduble-ecisionFormat,forwidevaluerangesbutbecautious.2)

什麼是在DOM中冒泡和捕獲的事件? 什麼是在DOM中冒泡和捕獲的事件? Jul 02, 2025 am 01:19 AM

事件捕獲和冒泡是DOM中事件傳播的兩個階段,捕獲是從頂層向下到目標(biāo)元素,冒泡是從目標(biāo)元素向上傳播到頂層。 1.事件捕獲通過addEventListener的useCapture參數(shù)設(shè)為true實現(xiàn);2.事件冒泡是默認(rèn)行為,useCapture設(shè)為false或省略;3.可使用event.stopPropagation()阻止事件傳播;4.冒泡支持事件委託,提高動態(tài)內(nèi)容處理效率;5.捕獲可用於提前攔截事件,如日誌記錄或錯誤處理。了解這兩個階段有助於精確控制JavaScript響應(yīng)用戶操作的時機(jī)和方式。

Java和JavaScript有什麼區(qū)別? Java和JavaScript有什麼區(qū)別? Jun 17, 2025 am 09:17 AM

Java和JavaScript是不同的編程語言。 1.Java是靜態(tài)類型、編譯型語言,適用於企業(yè)應(yīng)用和大型系統(tǒng)。 2.JavaScript是動態(tài)類型、解釋型語言,主要用於網(wǎng)頁交互和前端開發(fā)。

See all articles