JavaScript >> Javascript 文檔 >  >> Node.js

使用 Node 和 Express 通過 HTTP/2 服務器推送優化您的應用程序

HTTP/2 是網絡的新標準。它具有許多強大的功能,可以使 Web 更快並簡化開發。例如,由於多路復用,無需連接文件,或者服務器推送可以在瀏覽器知道它需要文件之前發送文件。

這篇文章不會涵蓋 HTTP/2 的所有優點。您可以在線閱讀有關它們的信息。無需在此處詳述所有細節和重複文本。相反,我們將專注於服務器推送並使用 Express 和 spdy 在 Node.js 中實現它 圖書館。

服務器推送——是的!

服務器推送的工作方式是將多個資產和資源捆綁到單個 HTTP/2 調用中。在後台,服務器將發出 PUSH_PROMISE。客戶端(包括瀏覽器)可以使用或不使用它,這取決於主 HTML 文件是否需要它。如果是,它需要它,然後客戶端將匹配收到的推送承諾,使它們看起來像一個常規的 HTTP/2 GET 調用。顯然,如果匹配,則不會進行新的調用,但會使用客戶端已經存在的資產。有關服務器推送優勢的更多信息的一些好文章。

  • 服務器推送有什麼好處?
  • 宣布支持 HTTP/2 服務器推送
  • 使用 HTTP 2.0 服務器推送進行創新

這是一篇實用的文章,重點介紹在 Node.js 中實現 HTTP/2 服務器推送。更準確地說,我們將使用單個路由 /pushy 實現 Node 和 Express 服務器 它推送一個 JavaScript 文件。如前所述,我們將使用 spdy 圖書館。

HTTP/2 和 Node.js

關於spdy的選擇的幾句話 Node 庫:截至目前,Node.js 有兩種主要的 HTTP/2 實現:

  • http2
  • spdy

兩者都非常類似於核心httphttps 模塊意味著如果您不使用 Express,則幾乎沒有區別。然而,spdy 庫支持 HTTP/2 和 Express 而 http2 圖書館目前不支持 Express。這是使用 spdy 的充分理由 因為讓我們面對現實吧,Express 是 Node Web 應用程序事實上的標準框架。這就是原因,我選擇了 spdy .名稱spdy 是從 Google SPDY 協議演變成 HTTP/2 的。

HTTPS 密鑰和證書

首先,您需要生成密鑰和證書才能使用 HTTPS 加密,因為這是 HTTP/2 在您的瀏覽器(Firefox、Safari、Chrome 或 Edge)中工作的唯一方式。繼續搜索“ssl key generation”或按照以下步驟操作(因為我不會將我的密鑰和證書提交到該項目的 GitHub 存儲庫):

$ mkdir http2-node-server-push 
$ cd http2-node-server-push
$ openssl genrsa -des3 -passout pass:x -out server.pass.key 2048

然後運行這個:

$ openssl rsa -passin pass:x -in server.pass.key -out server.key

觀察:

writing RSA key

擺脫 RSA:

$ rm server.pass.key
$ openssl req -new -key server.key -out server.csr

回答問題:

Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:California
A challenge password []:
...

最後運行:

$ openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt

最後,您應該有三個 SSL 文件:

  • server.crt
  • server.csr
  • server.key

您將閱讀 server.keyserver.crt 在你的 Node.js 服務器腳本中。

[旁注]

閱讀博客文章很好,但觀看視頻課程更好,因為它們更具吸引力。

許多開發人員抱怨 Node.js 上缺乏負擔得起的高質量視頻材料。觀看 YouTube 視頻會讓人分心,花 500 美元購買 Node 視頻課程很瘋狂!

去看看 Node University,它有關於 Node 的免費視頻課程:node.university。

[旁注結束]

項目結構

現在是創建 package.json 的好時機 文件和安裝依賴:

npm init -y
npm i [email protected] [email protected] [email protected] --save
npm i [email protected] --save-dev

項目文件夾將如下所示:

 /http2-node-server-push
   /node_modules
  - index.js
  - package.json
  - server.crt
  - server.csr
  - server.key

隨意將這兩個 npm 腳本添加到 scripts package.json 簡化啟動命令(使用 node-dev 進行自動重新加載):

    "start": "./node_modules/.bin/node-dev .",
    "start-advanced": "./node_modules/.bin/node-dev index-advanced.js"

現在我們已經準備好使用 Node、Express 和 spdy 實現一個簡單的服務器推送了。

使用 Node.js 和 Express.js 實現服務器推送 HTTP/2 服務器

首先,導入依賴項。創建 index.js 在與 package.json 相同的文件夾中 (參見上面的項目結構)。

我正在使用新的 ES6/ES2015 語法 const 聲明我的模塊。如果您不熟悉這種類型的聲明,請參閱
每個忙碌的 JavaScript 開發人員必須知道的 10 大 ES6 功能 .

const http2 = require('spdy')
const logger = require('morgan')
const express = require('express')
const app = express()
const fs = require('fs')

接下來,我們將應用 morgan logger 來查看服務器的請求是什麼:

app.use(logger('dev'))

現在,有一個主頁,我們告訴它轉到 /pushy 這將是我們的服務器推送頁面。

app.get('/', function (req, res) {
  res.send(`hello, http2!
go to /pushy`)
})

使用res.push輕鬆實現服務器推送 這是來自 spdy。我們傳遞瀏覽器將用於匹配推送承諾與資產的文件名。因此,/main.jsres.push() 必須與您在 HTML 中請求的內容相匹配。

第二個參數是一個對象。可選,設置推送的資產信息:

app.get('/pushy', (req, res) => {
  var stream = res.push('/main.js', {
    status: 200, // optional
    method: 'GET', // optional
    request: {
      accept: '*/*'
    },
    response: {
      'content-type': 'application/javascript'
    }
  })
  stream.on('error', function() {
  })
  stream.end('alert("hello from push stream!");')
  res.end('<script src="/main.js"></script>')
})

如您所見,stream 有方法 onend .前者將允許使用 error 監聽事件 或 finish .後者是我們完成的時候。 main.js 腳本將顯示一個警告框(webdev circa 1990)。

或者,您可以使用 res.write() 然後是 res.end() 最後如果你有多個數據塊,因為 end() write 時會自動關閉響應 保持開放。 (目前的實現中沒有展示這種方法。)

最後,讓我們通過首先加載 SSL 數據(例如密鑰和證書)來啟動服務器,然後使用 spdy(http2 var) 來啟動服務器。

var options = {
  key: fs.readFileSync('./server.key'),
  cert: fs.readFileSync('./server.crt')
}

http2
  .createServer(options, app)
  .listen(8080, ()=>{
    console.log(`Server is listening on https://localhost:8080.
You can open the URL in the browser.`)
  }
)

這個實現的要點:都是關於流的。不是您可能在樹林中找到的那種,而是曾經開發人員用來將數據從源傳輸到目標的管道。如果您對流一無所知,或者 Node 和 Express 中的 http 請求和響應是流,請查看 You Don't Know Node .

運行和區分 HTTP/2 服務器推送

使用 node index.js 運行它 或 npm stat .轉到 https://localhost:3000/pushy 並查看警報框。繁榮!我們甚至沒有這方面的文件,如果您查看服務器的終端日誌:

GET /pushy 200 4.918 ms - -

這只是一個請求,而不是兩個(一個用於 HTML,一個用於 JS,就像沒有服務器推送的情況一樣)。

讓我們檢查一下服務器推送時的瀏覽器行為。在 Chrome 中打開 DevTools(或類似工具,如果您不使用 Chrome)並轉到 Network 選項卡。你會看到我們的 main.js 沒有問候欄,這意味著沒有等待 TTFB 時間(解釋)。


另外,您是否看到請求是由 Push 發起的(Initiator 列)?在非服務器推送 HTTP/2 或 HTTP/1 中,會有一個文件名,例如 index.html .

任務完成。我們使用 Express 和 spdy 輕鬆發送 JavaScript 資源,該資源後來被服務器使用,因為在 HTML 中我們有 <script> .

沒有什麼能阻止您將資產作為文件並在您的 Node 腳本中使用 fs 讀取它們 .事實上,這就是我為 Express 實現的 HTTP/2 靜態資產服務器推送中間件的實現,我將在下一篇文章中介紹(你可以在這裡偷看)。

總結

HTTP/2 有許多很棒的特性,服務器推送可能是最受關注的特性之一。服務器推送的好處是,當瀏覽器請求頁面時,服務器會立即發送所需的資產(圖像、樣式表、腳本),而無需等待客戶端請求(可能會因渲染而延遲)。

spdy 為 Node 開發人員提供了一種在 Express 應用程序中啟用推送的簡單方法。您克隆本文的源代碼以播放或用作您的樣板 (GitHub) 以創建您的資產的服務器推送。


Tutorial JavaScript 教程
  1. JSON 數組轉換為 Javascript 數組

  2. 將聲音添加到 UI

  3. 我們如何測試半設計 React 組件

  4. 使用 ReactPress 插件輕鬆將 React 應用程序嵌入 WordPress

  5. Mirage JS 深入探討:了解時序、響應和直通(第 3 部分)

  6. 像專業人士一樣使用對象解構😎

  7. 第 1 部分:React App 表現得像多頁 - Div id root 在新頁面加載時刷新。還是SPA嗎?

  1. React Hook:獲取滾動條寬度

  2. jsTree:如何從 jstree 獲取所有節點?

  3. lil-http-terminator,一個小巧的 JS 模塊,可以優雅地關閉你的 HTTP 服務器

  4. Qlik ❤ D3

  5. 使用 fetch api 在 ajax 調用上顯示 css 微調器

  6. 使用 React 構建表單,簡單的方法(使用 Typescript)

  7. React 動畫:一個簡單的組件如何影響你的性能

  1. ✂️ 代碼拆分 - 什麼、何時以及為什麼

  2. 使用 lax.js 創建一個瘋狂的輸入交互。 🤪

  3. 通過 GitHub Actions 將 Angular 應用程序部署到 Firebase

  4. 如何使用 PubSub 將 React 添加到 Angular 應用程序。