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

高度可擴展系統中的性能優化策略

譯文 精選
開發
在優化數字應用程序時,我們采用預取(Prefetching)、記憶化(Memoization)、并行獲取(Concurrent Fetching)和延遲加載(Lazy Loading)等技術來提升性能和用戶體驗。

譯者 | 劉汪洋

審校 | 重樓

在現代數字化環境下,單純構建一個具備基本功能的系統已無法滿足更高的應用需求。我們需要開發在高負載環境下能夠穩定且高效擴展的系統。

眾多開發者和架構師的實踐證明,系統可擴展性的提升往往伴隨著獨特的挑戰。即使是微小的效率問題,在放大到百萬倍的負載下,也可能導致系統陷入癱瘓。那么,怎樣才能確保你的應用程序在任何負載下都能快速響應呢?

本文將詳細介紹構建可擴展系統時的性能優化策略。我們會探討一些適用于各種代碼庫的通用策略,無論是前端還是后端,也不論使用何種編程語言。這些策略不僅限于理論層面;它們已在全球一些最具挑戰性的技術環境中經過實際應用和驗證。作為 Facebook 團隊的一員,我親自參與了將這些優化技術應用于多個項目中,包括 Facebook 的輕量級廣告創建體驗和 Meta 商務套件。

因此,無論你是在打造下一個大型社交網絡、企業級軟件套件,還是僅僅想要優化個人項目,我們在此討論的策略都將成為你工具箱中的寶貴資產。現在,讓我們開始探索吧。

預取

預取是一種基于預測用戶行為的性能優化技術。設想用戶正在與應用程序交互,系統能夠預測用戶的下一步操作,并提前獲取相關數據。這種方法能夠創造一種無縫體驗:當數據被需要時,它幾乎能夠即刻被獲取,從而使應用程序顯得更加迅速和響應靈敏。主動在需求出現之前獲取數據能夠顯著提升用戶體驗,但如果過度使用,可能會導致資源浪費,如帶寬、內存甚至處理能力的浪費。Facebook 在其需要依賴機器學習的復雜操作中大量使用預取,例如在“好友建議”功能中。

何時進行預取?

預取涉及在用戶明確表達需求之前,主動向服務器發送請求以檢索數據。盡管這看起來很有吸引力,但開發者必須確保在效率和資源使用之間取得平衡。

A.優化服務器響應時間(后端代碼優化)

在實施預取之前,首先應確保服務器響應時間已經得到優化。后端代碼優化可以通過以下方式實現更佳的服務器響應時間:

  • 精簡數據庫查詢,以縮短檢索時間。
  • 確保復雜操作能夠并發執行。
  • 減少重復的 API 調用,避免重復獲取相同的數據。
  • 剔除不必要的計算過程,以避免減慢服務器響應。

B.確認用戶意圖

預取的核心是對用戶下一步操作的預測。然而,預測有時可能不準確。如果系統為用戶從未訪問的頁面或功能預獲取數據,就會造成資源的浪費。因此,開發者應采用機制來評估用戶意圖,例如跟蹤用戶行為模式或檢查用戶的活躍參與度,以確保數據僅在有高概率被使用的情況下被獲取。

如何實現預取

預取可以在任何編程語言或框架中實現。以 React 為例,來展示預取的實現方法。

考慮一個簡單的 React 組件。該組件一旦完成渲染,就會觸發一個 AJAX 調用來預先獲取數據。當用戶點擊該組件中的按鈕時,第二個組件會使用這些預先獲取的數據:

import React, { useState, useEffect } from 'react';
import axios from 'axios';

function PrefetchComponent() {
  const [data, setData] = useState(null);
  const [showSecondComponent, setShowSecondComponent] = useState(false);
  // 組件渲染完成后立即預取數據
  useEffect(() => {
    axios.get('https://api.example.com/data-to-prefetch')
      .then(response => {
        setData(response.data);
      });
  }, []);
  return (
    <div>
    <button onClick={() => setShowSecondComponent(true)}>
Show Next Component
  </button>
{showSecondComponent && <SecondComponent data={data} />}
  </div>
 );
}
function SecondComponent({ data }) {
  // 在這個組件中使用預取的數據
  return (
    <div>
    {data ? <div>Here is the prefetched data: {data}</div> : <div>Loading...</div>}
</div>
);
}
export default PrefetchComponent;

在上述代碼示例中,PrefetchComponent組件在渲染之后立刻進行數據獲取。當用戶點擊按鈕時,SecondComponent組件會展示,使用的是之前預先獲取的數據。

記憶化

在計算機科學中,“不要重復自己”原則是優秀編碼習慣的核心。此原則也是性能優化的有效手段,正是記憶化技術的基礎。記憶化建立在這樣一個觀點上:重復執行某些操作可能會消耗大量資源,尤其是當這些操作的結果不經常發生變化時。那么,為什么要重復執行已經完成的工作呢?

記憶化通過緩存計算結果來提升應用程序的性能。當同一計算再次被請求時,系統會先檢查結果是否已在緩存中。如果已緩存,就直接從緩存中提取結果,省去了實際計算的步驟。從本質上講,記憶化涉及到對之前結果的存儲(由此得名)。這對于計算成本高且經常被同樣的輸入調用的函數來說尤為有效。這就好比一個學生解決了一個復雜的數學問題,并在書的邊緣記下了答案。如果未來的考試中出現了同樣的問題,學生可以簡單地查看書邊的筆記,而不必重新解決這個問題。

何時使用記憶化?

記憶化并非適用于所有情況。在某些場景下,記憶化可能會導致更多的內存消耗。因此,正確識別何時使用這種技術至關重要:

  • 數據變化不頻繁時: 對于那些輸入一致時返回結果也一致的函數,尤其是計算密集型的函數,使用記憶化是理想選擇。這確保了在隨后相同的調用中不會浪費一次計算的努力。
  • 數據不太敏感時: 在考慮使用記憶化時,安全性和隱私問題也是不可忽視的重要因素。雖然緩存所有內容看似誘人,但并不總是安全的。例如,支付信息、密碼及其他個人詳細信息這類數據永遠不應緩存。然而,像社交媒體帖子的點贊數和評論數這類較為無害的數據,可以安全地進行記憶化以提升性能。

如何實現記憶化

在 React 中,我們可以利用 useCallback 和useMemo等鉤子來實現記憶化。讓我們來看一個簡單的例子:

import React, { useState, useCallback, useMemo } from 'react';

function ExpensiveOperationComponent() {
    const [input, setInput] = useState(0);
    const [count, setCount] = useState(0);
    // 模擬一個計算開銷很大的操作
    const expensiveOperation = useCallback((num) => {
        console.log('Computing...');
        // 模擬耗時長的計算
        for(let i = 0; i < 1000000000; i++) {}
        return num * num;
    }, []);

    const memoizedResult = useMemo(() => expensiveOperation(input), [input, expensiveOperation]);

    return (
        <div>
            <input value={input} onChange={e => setInput(e.target.value)} />
            <p>Result of Expensive Operation: {memoizedResult}</p>
            <button onClick={() => setCount(count + 1)}>Re-render component</button>
            <p>Component re-render count: {count}</p>
        </div>
    );
}

export default ExpensiveOperationComponent;

在這個示例中,expensiveOperation函數模擬了一個計算密集型任務。我們使用useCallback鉤子來確保在每次組件渲染時,這個函數不會被重新定義。此外,useMemo鉤子被用來存儲expensiveOperation的結果,這樣,即使組件重新渲染,如果輸入沒有變化,就不會重復執行這個計算。

并行獲取

并行數據獲取是指同時獲取多個數據集,而非逐個獲取。這就好比在超市結賬時,有多個收銀員同時服務,而不僅僅是一個:顧客能更快得到服務,排隊時間縮短,整體效率得到提升。在數據處理領域,鑒于很多數據集之間互不相關,因此并行獲取能顯著加快頁面加載速度,尤其適用于檢索復雜數據所需時間較長的場景。

何時使用并行獲取?

  • 當各數據集獨立且獲取過程復雜時: 若所需獲取的數據集之間無依賴關系,并且檢索每個數據集耗時較長,此時并行獲取能有效提高處理速度。
  • 后端應用廣泛,前端使用需謹慎: 盡管在后端,通過提升服務器響應速度,并行獲取能發揮顯著效果,但在前端使用時需格外小心。過多的并行請求可能會加重客戶端負載,影響用戶體驗。
  • 優先處理網絡請求: 若數據獲取涉及多個網絡請求,最佳做法是優先處理一個主要請求,并在前端展示,同時在后臺并行處理其他請求。這樣做可確保最重要的數據首先被獲取,同時其他次要數據也在后臺并行地進行加載。

如何使用并行獲取

在 PHP 中,隨著現代擴展和工具的發展,實現并行處理變得更為簡便。以下是一個使用concurrent {}代碼塊的基本示例:

<?php
use Concurrent\TaskScheduler;
require 'vendor/autoload.php';

// 假設這些是一些從各種來源獲取數據的函數
function fetchDataA() {
    // 模擬延遲
    sleep(2);
    return "Data A";
}

function fetchDataB() {
    // 模擬延遲
    sleep(3);
    return "Data B";
}

$scheduler = new TaskScheduler();

$result = concurrent {
    "a" => fetchDataA(),
    "b" => fetchDataB(),
};

echo $result["a"];  // Outputs: Data A
echo $result["b"];  // Outputs: Data B
?>

在此示例中,fetchDataA 和 fetchDataB 分別代表兩個數據檢索函數。通過運用concurrent {}代碼塊,這兩個函數可同時執行,從而縮短了獲取這兩個數據集的總耗時。

延遲加載

延遲加載是一種設計模式,其核心思想是僅在真正需要時才加載數據或資源。與預先加載所有內容不同,延遲加載只載入初始視圖所需的必要內容,隨后根據需求加載額外資源。這類似于一家餐廳僅在顧客點特定菜品時才開始烹飪,而非預先準備所有菜肴。例如,在網頁中,模態框的數據只有在用戶點擊按鈕打開模態框時才被加載。通過這種方式,可以將數據的獲取推遲到實際需要的時刻。

如何實現延遲加載

有效實現延遲加載的關鍵在于,要確保在數據獲取過程中向用戶提供清晰的反饋,以優化用戶體驗。常見的做法是在數據檢索時展示一個旋轉的加載動畫,這樣用戶就能明白他們的請求正在被處理,即便數據暫時還不可用。

React 中的延遲加載示例

以下是一個 React 組件中實現延遲加載的示例。此組件只在用戶點擊按鈕以查看模態框內容時獲取數據:

import React, { useState } from 'react';

function LazyLoadedModal() {
    const [data, setData] = useState(null);
    const [isLoading, setIsLoading] = useState(false);
    const [isModalOpen, setIsModalOpen] = useState(false);

    const fetchDataForModal = async () => {
        setIsLoading(true);
        
        // 模擬一次 AJAX 獲取數據的調用
        const response = await fetch('https://api.example.com/data');
        const result = await response.json();

        setData(result);
        setIsLoading(false);
        setIsModalOpen(true);
    };

    return (
        <div>
            <button onClick={fetchDataForModal}>
                Open Modal
            </button>

            {isModalOpen && (
                <div className="modal">
                    {isLoading ? (
                        <p>Loading...</p>  // 這里可以使用旋轉圈或加載動畫
                    ) : (
                        <p>{data}</p>
                    )}
                </div>
            )}
        </div>
    );
}

export default LazyLoadedModal;

在這個例子中,只有當用戶點擊“打開模態框”按鈕后,才會開始獲取模態框的數據。在此之前,不會發起不必要的網絡請求。一旦開始獲取數據,便會顯示加載信息(或旋轉器),以示用戶請求正在處理。

結論

在當今快速的數字時代,響應時間的每一毫秒都十分重要。用戶尋求快速響應,而企業無法承受讓用戶等待的后果。性能優化已成為提供優質數字體驗的必要條件,而不僅僅是一種優化。

通過預取、記憶化、并行獲取和延遲加載等技術,開發者能有效提升應用性能。雖然這些策略在應用和方法上有所不同,但它們共同的目標是確保應用程序能夠盡可能高效和快速地運行。

重要的一點是,不存在一勞永逸的解決方案或“銀彈”。每個應用程序都有其獨特之處,性能優化應結合對應用程序需求的深入理解、對用戶期望的認識,以及正確技術的有效應用。這是一個持續改進和學習的過程。

譯者介紹

劉汪洋,51CTO社區編輯,昵稱:明明如月,一個擁有 5 年開發經驗的某大廠高級 Java 工程師,擁有多個主流技術博客平臺博客專家稱號。

原文標題:Performance Optimization Strategies in Highly Scalable Systems,作者:Hemanth Murali

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

2022-06-16 08:00:00

元數據數據中心數據架構

2023-05-10 10:30:02

性能優化Tomcat

2009-09-08 09:45:23

App Engine性

2024-10-10 14:01:34

2009-03-16 09:16:13

行為擴展WCF.NET

2019-01-04 13:30:58

系統 優化 數據

2024-05-10 13:14:41

技巧云原生應用

2024-05-16 13:33:27

系統服務器網絡

2021-07-16 23:01:03

SQL索引性能

2025-01-15 08:05:06

MySQLLEFT JOIN數據庫

2023-02-09 09:08:44

PaSca圖結構數據處理

2023-07-13 12:27:04

2010-05-05 11:48:27

Oracle設計開發階

2024-09-04 14:28:20

Python代碼

2021-07-26 18:23:23

SQL策略優化

2024-12-20 16:56:00

Python面向對象編程

2024-07-23 08:08:18

2010-04-25 23:39:42

2023-10-11 13:46:26

緩存Web應用程序

2017-01-05 19:29:10

公共云云存儲微軟
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产www成人 | 美女张开腿露出尿口 | 欧美一区二区三区视频 | 国产一区二区三区四 | 成人在线小视频 | 国产一区二区三区免费 | 亚洲天堂一区二区 | 欧美激情在线精品一区二区三区 | 女女爱爱视频 | 爱草视频 | 成人免费影院 | 美日韩精品 | 久草在线 | 久久国内 | 国产激情在线观看 | 精品国产乱码久久久久久88av | 久久黄网 | 91视频www.| 亚洲综合中文字幕在线观看 | 亚洲精品2区| 九九久久免费视频 | 久久一视频 | 黄网站在线观看 | 婷婷国产一区 | 成人片网址 | 欧美国产91 | 99热热热| 成人黄色三级毛片 | 午夜视频一区 | 黄色骚片 | 日本一区二区视频 | 日日干夜夜操天天操 | 国产999精品久久久久久 | 国产在线小视频 | 亚洲国产精品日韩av不卡在线 | 亚洲精品一区二区三区中文字幕 | 欧美videosex性极品hd | 久久国产亚洲 | 久久久一区二区三区四区 | 国内精品久久久久久 | 国产伦精品一区二区三毛 |