Node.js之HTTP/2服務器推送

譯者按: 盆友們,是時候擁抱新一代HTTP協議了!javascript

Node.js 8.4.0已經開始支持HTTP/2,執行node命令時,加上--expose-http2選項就可使用了。css

在這篇博客中,咱們會介紹如何使用HTTP/2進行服務器推送(server push),另外,咱們還寫了一個簡單的Node.js示例。html

關於HTTP/2

HTTP/2是新一代HTTP協議,支持**多路複用(MultiPlexing)、header壓縮、服務器推送(server push)**等特性,有效減小了時延。對HTTP/2感興趣的話,能夠查看 Introduction to HTTP/2前端

HTTP/1 VS HTTP/2

HTTP/2服務器推送容許服務器在瀏覽器請求資源以前推送資源,減小頁面加載時間。這裏,咱們不妨對比一下HTTP/1和HTTP/2。java

HTTP/1

客戶端發送請求給服務器,服務器返回請求的資源,一般是HTML文件,HTML文件包含一些資源連接(好比.js, .css等)。瀏覽器解析HTML文件,獲取資源連接,而後分別請求這些資源。node

下面的圖片展現了這個過程,注意:timeline中有3個獨立的請求,bundle1.js和bundle2.js的請求的initiator是(index)Parser。git

HTTP/1是這樣工做的,咱們已經這樣作不少年了,那爲何要改變呢?問題在於,用戶須要等待瀏覽器解析HTML文件,獲取連接而後請求資源。這會延緩前端渲染,增長頁面加載時間。將一些資源嵌入HTML是一個解決方法,可是那會使得第一次請求變得很大很慢。github

HTTP/2

下面的圖片顯示了當服務器啓用HTTP/2以後的網站加載過程。由timeline和initiator可知,多路複用減小了請求個數,並且bundle1.js和bundle2.js在第一次請求時就推送給前端了。web

Node.js示例

使用內置的http2模塊,咱們能夠建立一個http2服務器。有趣的一點在於,當index.html被請求時,咱們會主動推送其餘資源:bundle1.js和bundle2.js。這樣的話,bundle1.js和bundle2.js能夠在瀏覽器請求它們以前就推送過去了。瀏覽器

const http2 = require('http2')
const server = http2.createSecureServer(
  { cert, key },
  onRequest
)

function push (stream, filePath) {
  const { file, headers } = getFile(filePath)
  const pushHeaders = { [HTTP2_HEADER_PATH]: filePath }

  stream.pushStream(pushHeaders, (pushStream) => {
    pushStream.respondWithFD(file, headers)
  })
}

function onRequest (req, res) {
  // Push files with index.html
  if (reqPath === '/index.html') {
    push(res.stream, 'bundle1.js')
    push(res.stream, 'bundle2.js')
  }

  // Serve file
  res.stream.respondWithFD(file.fileDescriptor, file.headers)
}

複製代碼

完整的示例能夠查看GitHub倉庫:RisingStack/http2-push-example

HTTP/2 & Node.js

Node.js啓用HTTP/2特性能夠幫助咱們優化客戶端與服務端的交互性能。使用服務器推送,咱們能夠在瀏覽器請求資源以前,將資源推送給瀏覽器,這樣能夠減小頁面加載時間,提升用戶體驗。

相關文章
相關標籤/搜索