成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何利用預取技術提升Web性能:減少加載時間,優化用戶體驗

譯文 精選
開發 前端
我們都曾遭遇過這樣的煩惱:漫長的加載界面之后,卻只等來了毫無反應的網頁。隨處可見的加載圖標不停旋轉,但一切似乎都停滯不前。

譯者 | 劉濤

審校 | 重樓

我們都曾遭遇過這樣的煩惱:漫長的加載界面之后,卻只等來了毫無反應的網頁。隨處可見的加載圖標不停旋轉,但一切似乎都停滯不前。讓我為你描繪一個更生動的畫面:

這種情況通常發生的原因是,網站試圖在你一落地頁面就預取所有必要的數據。可能是正在處理某個API請求,或者多個API在順序預取數據,導致頁面加載延遲。

結果如何?用戶體驗簡直糟糕到極點。你可能會想:"這么大的公司怎么會不注重用戶體驗?真是令人失望。"因此,用戶往往會選擇離開網站,這不僅影響了網站的關鍵指標,還可能導致收入受到損失。

但是,如果我們能提前預取這些重量級頁面的數據,讓用戶一進入頁面就能立即與之交互,會怎樣呢?

這就是預取(Prefetching)概念的由來,也正是我們在這篇博文中將深入探討的內容。

目錄

  • 預取技術:解決方案
  • 預取技術如何提升用戶體驗
  • 問題剖析
  • 解決方案一:在父組件中預取數據
  • 解決方案二:頁面加載時預取數據
  • React中如何實現預取
  • 過度預取也可能導致性能下降
  • 總結

預取技術:解決方案

針對上述問題,我們的目標是在頁面加載至網站之前,就預取該頁面所需的數據,如此一來,用戶在頁面加載時便無需再次預取數據。這種技術被稱作預取。從技術層面來講,其定義如下:

預取是一種提前預取所需數據的方法,使主要組件無需等待數據即可加載,從而提升用戶體驗。

這可以改善用戶體驗,增強客戶對你網站的信

預取是一種簡而優雅的解決方案,相較于標準流程,它更加以用戶為中心。要實施預取,我們需要了解用戶在網站上的行為。例如,最常訪問的頁面,或哪些組件在小交互(如懸停)時預取數據。

完成對這些場景的分析后,就可以對其合理應用預取技術。然而,作為開發人員,我們應該謹慎使用這個概念。過度預取也可能降低網站速度,因為你試圖為未來場景預取大量數據,這可能會阻塞主頁面的數據預取

預取技術如何提升用戶體驗

讓我們來看幾個預取技術有益的場景:

  1. 為登陸頁面上最常訪問的鏈接提前加載數據/頁面。例如,假設你有一個"聯系我們"鏈接,此鏈接為用戶最常查看,且加載時包含大量數據。與其在"聯系我們"頁面加載時才預取數據,不如在主頁就開始預取,這樣用戶就無需在"聯系我們"頁面上等待。
  2. 預取表格數據,用于后續頁面。
  3. 在父組件中預取數據,并將其加載到子組件中。
  4. 預取數據在彈出窗口中顯示。

這些都是在應用中實現預取的方法,它們有助于提升用戶體驗。

在本文中,我們將討論最后一個場景:"預取數據在彈出窗口中顯示"。這是一個預取技術能夠帶來明顯好處,為用戶提供更流暢體驗的典型示例

問題剖析

讓我為你詳細闡述這個問題。請想象以下場景:

  1. 你有一個用于展示特定信息的組件。
  2. 這個組件內部有一個元素,當鼠標懸停在其上時會顯示一個彈出窗口或工具提示。
  3. 這個彈出窗口在加載時需要預取數據。

現在,設想用戶將鼠標懸停在該元素上,隨后等待數據被預取并顯示在彈出窗口中。在這段等待的時間里,用戶會看到一個骨架加載器(Skeleton Loader)。

這個場景大致如下(此為動圖,需要下載anigif.ocx控件觀看):

每當用戶將鼠標懸停在圖片上時,他們必須等待很長時間,這真的很令人沮喪:(此為動圖,需要下載anigif.ocx控件觀看)

要解決此問題,有兩種解決方案可供你參考,以幫助你著手并根據自身需求優化解決方案。

解決方案一:在父組件中預取數據

這個解決方案允許你在彈出窗口出現之前便已預取數據,而非在組件加載時預取。

當鼠標懸停在某個元素(如圖片)上時,彈出窗口會顯現。我們能夠在這個元素的父組件上實現鼠標進入時預取數據。鑒于此,在實際需要懸停顯示的組件(如圖片)之前,我們就已經準備好彈出窗口所需的數據,并將這些數據傳遞給彈出窗口組件。

這種解決方案并不能完全消除加載狀態,不過它能夠顯著降低用戶看到加載狀態的概率。(此為動圖,需要下載anigif.ocx控件觀看)

解決方案二:頁面加載時預取數據

這個解決方案受到了類似x.com(可能是指Facebook的前身或類似的大型網站)的數據加載策略的啟發,即在彈出窗口組件中,它們在主頁面加載時部分預取數據,并在組件掛載時預取剩余的數據。(此為動圖,需要下載anigif.ocx控件觀看)

正如你從上面的動態圖中所看到的,用戶的個人資料詳細信息在彈出窗口中查看。仔細觀察,你會發現與關注者相關的詳細信息是稍后預取的。

當你需要在彈出窗口中顯示大量數據,但一次性預取所有數據可能對彈出窗口掛載或主頁面加載造成較大負擔時,采取這種技術就顯得非常高效。

一個更好的解決方案是,在主頁面上部分加載所需的數據,并在組件掛載時加載剩余的數據。

在這個例子中,我們在鼠標進入圖片的父元素時預取了彈出窗口的數據。現在想象一下,一旦彈出窗口的數據加載完成,你還需要預取額外的詳細信息。因此,基于上述x.com的方法,我們可以在彈出窗口加載時預取額外的數據。這樣做的結果是:

在這里,我們采取以下步驟:

當鼠標進入圖片的父組件時,我們預取渲染彈出窗口所必需的主要數據。

這給我們足夠的時間來預取主要數據。

在彈出窗口加載時,我們預取另一組數據,即相冊數量。當用戶閱讀姓名和郵箱等信息時,下一組數據已經準備就緒,隨時可以展示。

通過這種方式,我們可以做一些小而巧妙的優化,最大限度地減少用戶盯著屏幕上的加載動畫發呆的時間。

React中如何實現預取

在本部分中,我們將簡要介紹如何實現上述預取示例應用程序。

項目設置

要開始創建支持預取功能的應用,請按照以下步驟操作:

你可以使用 Vite.js(這是我使用的工具)或 Create React App 來創建你的應用程序在終端中使用以下命令:

yarn create vite prefetch-example --template react-ts

當你用VS Code打開prefetch-example文件夾后,應該會看到如下的文件夾結構。

現在讓我們深入了解一下我們將為這個應用構建的組件。

現在讓我們深入了解這個應用程序所構建的組件。

組件

在此示例中,我們將使用3個組件:

  • PopoverExample
  • UserProfile
  • UserProfileWithFetching

PopoverExample 組件

讓我們從第一個組件開始,即PopoverExample。這個組件在界面上展示了一個圖像頭像(avatar),并在其右側顯示了一些文本。它的布局應該類似于這樣:(此為動圖,需要下載anigif.ocx控件觀看)

該組件的目的是作為一個示例,模擬現實生活中的場景。在這個組件中,當用戶將鼠標懸停在圖片上時,會加載一個彈出窗口組件。

以下是該組件的代碼:

import { useState } from "react";
import { useFloating, useHover, useInteractions } from "@floating-ui/react";
import ContentLoader from "react-content-loader";
import UserProfile from "./UserProfile";
import UserProfileWithFetching from "./UserProfileWithFetching";export const MyLoader = () => (
 <ContentLoader
 speed={2}
 width={340}
 
 height={84}
 viewBox="0 0 340 84"
 backgroundColor="#d1d1d1"
 foregroundColor="#fafafa"
 >
 <rect x="0" y="0" rx="3" ry="3" width="67" height="11" />
 <rect x="76" y="0" rx="3" ry="3" width="140" height="11" />
 <rect x="127" y="48" rx="3" ry="3" width="53" height="11" />
 <rect x="187" y="48" rx="3" ry="3" width="72" height="11" />
 <rect x="18" y="48" rx="3" ry="3" width="100" height="11" />
 <rect x="0" y="71" rx="3" ry="3" width="37" height="11" />
 <rect x="18" y="23" rx="3" ry="3" width="140" height="11" />
 <rect x="166" y="23" rx="3" ry="3" width="173" height="11" />
 </ContentLoader>
);
export default function PopoverExample() {
 const [isOpen, setIsOpen] = useState(false);
 const [isLoading, setIsLoading] = useState(false);
 const [data, setData] = useState({});
const { refs, floatingStyles, context } = useFloating({
 open: isOpen,
 onOpenChange: setIsOpen,
 placement: "top",
 });
const hover = useHover(context);
const { getReferenceProps, getFloatingProps } = useInteractions([hover]);
const handleMouseEnter = () => {
 if (Object.keys(data).length === 0) {
 setIsLoading(true);
 fetch("https://jsonplaceholder.typicode.com/users/1")
 .then((resp) => resp.json())
 .then((data) => {
 setData(data);
 setIsLoading(false);
 });
 }
 };
return (
 <div
 id="hover-example"
 style={{
 display: "flex",
 flexDirection: "row",
 alignItems: "center",

 textAlign: "left",
 }}
 onMouseEnter={handleMouseEnter}
 >
 <span
 style={{
 padding: "1rem",
 }}
 >
 <img
 ref={refs.setReference}
 {...getReferenceProps()}
 style={{
 borderRadius: "50%",
 }}
 src="https://cdn.jsdelivr.net/gh/alohe/avatars/png/vibrent_5.png"
 />
 </span>
 <p>
 Lorem Ipsum is simply dummy text of the printing and typesetting
 industry. Lorem Ipsum has been the industry's standard dummy text ever
 since the 1500s, when an unknown printer took a galley of type and
 scrambled it to make a type specimen book. It has survived not only five
 centuries, but also the leap into electronic typesetting, remaining
 essentially unchanged. It was popularised in the 1960s with the release
 of Letraset sheets containing Lorem Ipsum passages, and more recently
 with desktop publishing software like Aldus PageMaker including versions
 of Lorem Ipsum.
 </p>
 {isOpen && (
 <div
 className="floating"
 ref={refs.setFloating}
 style={{
 ...floatingStyles,
 backgroundColor: "white",

 color: "black",
 padding: "1rem",
 fontSize: "1rem",
 }}
 {...getFloatingProps()}
 >
 {isLoading ? (
 <MyLoader />
 ) : (
 <UserProfile hasAdditionalDetails {...data} />
 )}
 {/* <UserProfileWithFetching /> */}
 </div>
 )}
 </div>
 );
}

程序運行的過程,讓我逐步解釋:

  • 我們有一個名為“hover-example”的父文件div,其中包含一張圖像和一些文本。
  • 接下來,我們有條件地渲染了一個具有“floating”類名的 div文件。這便是實際的彈出組件,當你將鼠標懸停在圖像上時,它就會開啟。我們使用了floating-ui庫及其基本的懸停示例來實現彈出窗口的懸停效果。
  • 在彈出窗口中,我們有條件地加載UserProfile組件和骨架加載器。當我們正在預取用戶資料的數據時,這個骨架加載器便會顯現。稍后我會更為詳盡地闡釋這一點。
  • 在 MyLoader 組件中,我們采用了react-content-loader庫。該庫還設有一個網站,能夠幫助你創建加載器。

UserProfile 組件

既然我們已經定義了 Popover 示例,那么此刻便是深入探究 UserProfile 組件細節的時候了

這個組件出現在Popover組件內部。目的是加載從JSON占位符API預取nameemailphonewebsite詳細信息。

為了演示預取示例,我們必須確保UserProfile組件僅作為展示組件存在;也就是說,它內部不包含任何明確預取邏輯。

關于這個組件的關鍵點是,數據的取發生在父組件PopoverExample中。在這個組件,當鼠標進入該組件(即觸發mouseenter事件)時,我們開始取數據。這是我們之前討論過的解決方案#1。

這為用戶在將鼠標懸停在圖像上之前提供了充足的時間來取數據。以下是相關代碼:

import { useEffect, useState } from "react";
import { MyLoader } from "./PopoverExample";
export default function UserProfileWithFetching() {
 const [isLoading, setIsLoading] = useState(false);
 const [data, setData] = useState<Record<string, string>>({});
useEffect(() => {
 setIsLoading(true);
 fetch("https://jsonplaceholder.typicode.com/users/1")
 .then((resp) => resp.json())
 .then((data) => {
 setData(data);
 setIsLoading(false);
 });
 }, []);
if (isLoading) return <MyLoader />;
return (
 <div id="user-profile">
 <div id="user-name">name: {data.name}</div>
 <div id="user-email">email: {data.email}</div>
 <div id="user-phone">phone: {data.phone}</div>
 <div id="user-website">website: {data.website}</div>
 </div>
 );
}

此應用程序的完整代碼可在此處找到。

過度預取也可能導致性能下降

一點建議:預取過多并不是一個好主意,原因如下:

  • 可能會降低應用速度
  • 如果預取策略不當,會損害用戶體驗
    預取需要基于用戶行為預測:只有當你能通過數據分析預測用戶的下一步操作時,預取才是有意義的。比如,如果你能通過用戶的歷史訪問記錄預測他們經常訪問的頁面,那么在這些頁面上進行預取就是一個好主意。
    因此,請記住要始終策略性地應用預取技術。

總結

在這篇文章中,了解到實現預取可以顯著提升的Web應用程序的速度和響應性,從而提高用戶滿意度。

為了進一步閱讀,請參考以下文章:

原文標題:How to Boost Web Performance with Prefetching – Improve User Experience by Reducing Load Time,作者:Keyur Paralkar

責任編輯:華軒 來源: 51CTO
相關推薦

2023-09-11 16:54:17

谷歌開發

2013-12-10 13:33:20

桌面虛擬化

2012-04-18 09:22:40

Chrome for

2010-03-18 20:19:16

2011-01-13 16:11:13

silverlightwebasp.net

2023-12-12 08:00:00

2019-03-06 10:25:30

Web圖片優化命令

2015-03-21 06:11:48

透視寶云智慧

2020-04-15 16:10:51

公有云云計算度量體系

2021-01-12 10:16:42

CSS 容器優化滾動

2025-03-10 00:00:50

2015-08-07 10:11:47

Web用戶設計要點

2024-09-25 10:45:21

數據飛輪

2024-06-17 08:26:23

性能ViewPager頁面

2009-03-24 15:18:39

智能化應用交付行為分析

2010-05-18 10:09:38

前端優化

2011-04-21 09:59:48

WEBjavascript

2013-07-24 15:33:57

紅帽

2024-04-17 08:23:50

WebView技巧優化

2024-08-12 15:40:54

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久久久国产一级毛片 | 精品国产精品 | 久久视频免费观看 | 日韩成人在线免费观看 | 午夜99 | 91精品国产欧美一区二区成人 | 成人精品免费视频 | 国产日韩欧美精品 | 欧美日韩国产精品一区 | 国产日韩欧美精品一区二区 | 久久国产成人 | 九九综合九九 | 最近中文字幕第一页 | 午夜精品久久久久久久久久久久久 | 一区二区三区在线看 | 九九热视频这里只有精品 | av天天看| 欧美午夜精品 | 日韩在线一区二区三区 | 99精品视频免费观看 | 日韩一区二区三区在线视频 | 中文一区| 亚洲精品电影在线观看 | 免费看91 | 成人激情视频在线播放 | 日韩精品免费一区二区在线观看 | 噜噜噜噜狠狠狠7777视频 | 桃色五月| h视频在线播放 | 九九九精品视频 | 国产一区| 日本免费视频在线观看 | a欧美| 国产精品日韩一区二区 | 精品一区二区三区在线观看国产 | 国产98色在线 | 国产午夜亚洲精品不卡 | 久久久精品国产 | 天天综合国产 | 天天插天天搞 | 色香婷婷 |