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

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

在 AI 驅(qū)動的代碼生成蓬勃發(fā)展的今天,編寫 React 代碼的重要性正在下降?,F(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://m.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)該包含什么是一個復(fù)雜的問題。理想情況下,一切都是為了讓用戶立即看到完整的體驗。但是同樣 - 什么也沒有,因為它需要盡可能快,因為它是一條“關(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)。這是用戶第一次有機會在屏幕上看到某些東西。是否會發(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)站速度的初步印象。

直到這一刻,用戶只是在盯著空白屏幕咬指甲。根據(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)用于屏幕上的 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é)點模塊使用,以便在構(gòu)建中運行它并在生產(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://m.miracleart.cn/link/def14e8541708294d7558fdf2126ef27

首先安裝所有依賴項:

<code>npm install</code>

構(gòu)建項目:

<code>npm run build</code>

啟動服務(wù)器:

<code>npm run start</code>

您應(yīng)該在“http://m.miracleart.cn/link/66e8d052ec2230c66bd11ee6b5a0e3c8

探索必要的 DevTools

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

此外,在本文中執(zhí)行任何其他操作之前,請確保已啟用“禁用緩存”復(fù)選框。它應(yīng)該位于最頂部的“網(wǎng)絡(luò)”面板中。

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

本地性能完美無缺,這并不奇怪 - 一切都“在我的機器上運行”。

還會有如下指標(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ì)的信息,有時還會找到解釋該特定主題的鏈接。并非所有這些都可以采取行動,但它是一個開始學(xué)習(xí)性能并了解可以改進(jìn)它的不同事物的絕佳工具。僅僅閱讀這些報告和相關(guān)鏈接就可以花費數(shù)小時。

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

探索性能面板

首次加載時,“性能”面板應(yīng)如下所示:

Initial load performance for React developers: investigative deep dive

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

在面板頂部找到并選中“屏幕截圖”復(fù)選框,然后單擊“記錄并重新加載”按鈕,當(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ā)生的事情的屏幕截圖,并且您將能夠選擇并放大到特定范圍以仔細(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ù)器更逼真。現(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://m.miracleart.cn/link/def14e8541708294d7558fdf2126ef27)。找到注釋掉的 // await sleep(500),并取消注釋它。這將使服務(wù)器在返回 HTML 之前延遲 500 毫秒 - 這對于舊的復(fù)雜服務(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)帶寬”配置文件復(fù)制下載/上傳數(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)致多大的差距?
  • 在主線程中,“解析 HTML”和 JavaScript 執(zhí)行任務(wù)相對于資源下載有多大?
  • 它如何影響 LCP 指標(biāo)?

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

Initial load performance for React developers: investigative deep dive

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

要模擬這一點,請創(chuàng)建一個新的網(wǎng)絡(luò)配置文件,將其命名為“平均 3G”,從“低互聯(lián)網(wǎng)帶寬”配置文件復(fù)制下載/上傳數(shù)字,并將延遲設(shè)置為 300 毫秒。

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

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

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

如果您的服務(wù)器位于挪威某個地方,而客戶端是富有的澳大利亞人,則很容易發(fā)生這種情況。

這是結(jié)果:

Initial load performance for React developers: investigative deep dive

LCP 數(shù)字約為960 毫秒。它比我們之前嘗試過的最慢的互聯(lián)網(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)絡(luò))基本上是任何前端性能相關(guān)工作的第 0 步,甚至在開始考慮更花哨的東西(如代碼分割或服務(wù)器組件)之前。

任何 CDN(內(nèi)容分發(fā)網(wǎng)絡(luò))的主要目的是減少延遲并盡快將內(nèi)容交付給最終用戶。它們?yōu)榇藢嵤┝硕喾N策略。本文最重要的兩個是“分布式服務(wù)器”和“緩存”。

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

在上面的示例中,我們的服務(wù)器位于挪威,客戶端位于澳大利亞,我們有這樣的圖片:

Initial load performance for React developers: investigative deep dive

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

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

Initial load performance for React developers: investigative deep dive

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

重復(fù)訪問性能

到目前為止,我們只討論了首次訪問性能 - 從未訪問過您網(wǎng)站的人的性能。但希望該網(wǎng)站如此出色,以至于大多數(shù)首次訪問者都會變成???。或者至少他們在第一次加載后不會離開,瀏覽幾個頁面,也許會購買一些東西。在這種情況下,我們通常期望瀏覽器緩存靜態(tài)資源(如 CSS 和 JS)- 即在本地保存它們的副本,而不是總是下載它們。

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

再次打開學(xué)習(xí)項目。在開發(fā)工具中,將“網(wǎng)絡(luò)”設(shè)置為我們之前創(chuàng)建的“平均 3G” - 具有高延遲和低帶寬,這樣我們就可以立即看到差異。并確?!敖镁W(wǎng)絡(luò)緩存”復(fù)選框未選中。

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)絡(luò)選項卡中仍然非常突出,我看到它們在“發(fā)送請求并等待”中大約有 300 毫秒 - 我們在“平均 3G”配置文件中設(shè)置的延遲設(shè)置。結(jié)果,LCP 并不像它可能的那樣低,并且當(dāng)瀏覽器只是等待阻塞 CSS 時,我有一個 300 毫秒的差距。

發(fā)生了什么?瀏覽器不應(yīng)該緩存這些東西嗎?

使用 Cache-Control 頭控制瀏覽器緩存

我們現(xiàn)在需要使用“網(wǎng)絡(luò)”面板來了解發(fā)生了什么。打開它并在那里找到 CSS 文件。它應(yīng)該如下所示:

Initial load performance for React developers: investigative deep dive

這里最有趣的是“狀態(tài)”列和“大小”。在“大小”中,它絕對不是整個 CSS 文件的大小。它太小了。在“狀態(tài)”中,它不是我們通常的 200“一切正常”狀態(tài),而是不同的東西 - 304 狀態(tài)。

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

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

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

這就是為什么我們在性能圖片中看到很大的“發(fā)送請求并等待”數(shù)字 - 瀏覽器要求服務(wù)器確認(rèn) CSS 文件是否仍然是最新的。這就是為什么那里的“內(nèi)容下載”是 0.33 毫秒 - 服務(wù)器返回“304 未修改”,瀏覽器只是重新使用了之前下載的文件。

附加練習(xí)

  1. 在學(xué)習(xí)項目中,轉(zhuǎn)到 dist/assets 文件夾并重命名 CSS 文件
  2. 轉(zhuǎn)到 dist/index.html 文件并更新重命名 CSS 文件的路徑
  3. 刷新已打開的頁面并打開“網(wǎng)絡(luò)”選項卡,您應(yīng)該看到 CSS 文件以新名稱、200 狀態(tài)和正確的大小出現(xiàn) - 它已再次下載。這被稱為“緩存清除” - 一種強制瀏覽器重新下載它可能已緩存的資源的方法。
  4. 再次刷新頁面 - 它已返回到 304 狀態(tài)并重新使用緩存的文件。

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

此行為由服務(wù)器設(shè)置為響應(yīng)的 Cache-Control 標(biāo)頭控制。單擊“網(wǎng)絡(luò)”面板中的 CSS 文件以查看請求/響應(yīng)的詳細(xì)信息。在“標(biāo)頭”選項卡的“響應(yīng)標(biāo)頭”塊中查找“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. 選中“禁用緩存”復(fù)選框并刷新頁面以刪除緩存。
  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)??赡軆H關(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 文件?,F(xiàn)代打包工具(如 Vite、Rollup、Webpack 等)可以創(chuàng)建“不可變”的 JS 和 CSS 文件。它們當(dāng)然不是真正“不可變”的。但是這些工具使用依賴于文件內(nèi)容的哈希字符串生成文件名稱。如果文件內(nèi)容發(fā)生更改,則哈希會更改,文件名稱也會更改。結(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)站部署時,下次重復(fù)用戶訪問它時,瀏覽器將請求一個在其緩存中從未出現(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)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請聯(lián)系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

功能強大的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)用戶操作的時機和方式。

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