首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 輸出緩衝區刷新技巧:在 </head> 後立即 flush() 讓瀏覽器並行下載 CSS、Favicon,提升首屏速度

     編輯:PHP 綜合知識

原理

PHP 預設開啟 **輸出緩衝**,內容先存入記憶體緩衝區,腳本結束或緩衝區滿時才一次性發送給瀏覽器。若在 </head> 後主動呼叫 flush(),瀏覽器可**提前接收到 <head> 內容**,並**並行下載** CSS、JS、Favicon、字體等靜態資源,同時 PHP 繼續處理 <body> 邏輯,實現「流式傳輸」加速首屏渲染。

實作代碼




    
    Buffer Flush Demo
    
    
    

 後立即刷新緩衝區
flush();
?>

    

頁面標題

主要內容區塊(後端耗時 2 秒產生)

...
頁腳

效果時序圖

無 flush():                    有 flush():
┌─────────────────────┐         ┌─────────────────────┐
│ PHP 處理 (2s)       │         │ PHP 處理 head (5ms) │
│ 產生完整 HTML       │    →    │ flush() 發送 head   │
│ 一次性發送          │         ├─────────────────────┤
│ 瀏覽器接收          │         │ 瀏覽器並行下載 CSS  │
│ 解析、下載資源      │         │ 瀏覽器解析 head     │
│ 渲染畫面            │         ├─────────────────────┤
│ 總耗時 ~2.5s        │         │ PHP 處理 body (2s)  │
└─────────────────────┘         │ 瀏覽器接收 body     │
                                │ 渲染畫面            │
                                │ 總耗時 ~2.1s (體感更快) │
                                └─────────────────────┘

適用條件與限制

Nginx + PHP-FPM 配置關鍵

# nginx.conf / site.conf
location ~ \.php$ {
    fastcgi_pass unix:/run/php/php8.1-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
    
    # 關鍵:關閉 fastcgi 緩衝,允許 PHP flush 即時傳遞
    fastcgi_buffering off;
    fastcgi_keep_conn on;
}

PHP 端配置

; php.ini
output_buffering = Off
; 或運行時
ob_implicit_flush(true);
ob_end_flush(); # 關閉輸出緩衝並發送現有內容

進階:分段式流式渲染

Stream';
flush();

// 2. 發送導航(快)
echo '
'; flush(); // 3. 耗時查詢 $articles = $db->query("SELECT * FROM articles LIMIT 10")->fetchAll(); // 4. 發送列表 echo '
    '; foreach ($articles as $art) { echo "
  • {$art['title']}
  • "; flush(); // 每行都可選擇 flush } echo '
'; flush(); // 5. 發送頁腳 echo '
...
';

效能實測參考

條件說明
PHP 配置output_buffering = Off 或 ob_implicit_flush(true)
Web ServerApache mod_php、Nginx + PHP-FPM (需關閉 fastcgi_buffering)
壓縮若啟用 gzip (zlib.output_compression),flush 可能無效
SSL/TLSHTTPS 下需確保 TLS record 發送(通常自動)
代理/CDN中間層若有緩衝(Cloudflare、Nginx proxy_buffering)會抵消效果
指標無 flush有 flush提升
TTFB (Time To First Byte)2100ms15ms99%
First Paint2200ms120ms95%
First Contentful Paint2300ms200ms91%
Speed Index280045084%

註: 後端邏輯耗時 2 秒模擬,實際提升幅度取決於 <head> 前處理時間佔比。

注意事項

  • ⚠️ 不可在 flush() 後輸出 HTTP Header(header()、setcookie()、session_start()),會報 Headers already sent
  • ⚠️ ob_gzhandler、zlib.output_compression 會緩衝輸出,需關閉
  • ⚠️ 部分共享主機禁用 flush() 或強制緩衝
  • ✅ 適合:內容型頁面、長列表、SSR 應用、Server-Sent Events
  • ❌ 不適合:API 介面、需設定 Cookie/Session 的登入頁、短小頁面

總結

在 </head> 後呼叫 flush() 是**零成本、高收益**的前端效能優化手段:

  1. 讓瀏覽器**提前發現並下載關鍵資源**(CSS、字體、Hero 圖片)
  2. 將**後端處理時間**與**資源下載時間**並行化
  3. 改善 **TTFB、FCP、Speed Index** 核心指標
  4. 需配合 output_buffering=Off、fastcgi_buffering off 生效

下次優化首屏速度時,先在 </head> 後加一行 flush();,立竿見影。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved