首頁 web前端 js教程 Chunk-Busters:不要跨越溪流!

Chunk-Busters:不要跨越溪流!

Dec 02, 2024 am 05:00 AM

⚠️ 如果您有光敏性,您可能想跳過此操作。
請參閱下面的靜態圖片,這些燈將開始快速閃爍!

Chunk-Busters: Don’t cross the Streams!

互聯網如何運作?

記住標題…我們在這裡討論的是流。

我可以談論協定、資料包、排序、acks 和 nacks…但我們在這裡談論流,正如你可能猜對了(我相信你=D)流…它要么是二進制,要么是字串。

是的,字串在發送之前會被壓縮…但是對於我們在前後端開發中通常關心的內容…字串和二進位。

在下面的範例中,我將使用 JS 流。

雖然 Node 有自己的遺留實現,但我們有辦法處理相同程式碼的流,無論是在前面還是後面。

其他語言有自己處理流的方式,但正如你所看到的......處理它的實際程式碼部分並不復雜(並不是說沒有發生複雜的事情)。

範例問題

您的前端必須使用多個來源的資料。

雖然您可以透過其 IP/連接埠單獨存取每個來源,但您可以將它們放在 API 閘道後面以便於使用和控制。

回購協議

檢查連結中的儲存庫,了解如何自己運行它,以便您可以使用它。

https://github.com/Noriller/chunk-busters

影片

後續影片版本:

https://youtu.be/QucaOfFI0fM

v0 - 簡單的實現

您擁有來源,您可以取得、等待和渲染。沖洗並重複。

await fetch1();
handleResult(1);
await fetch2();
handleResult(2);
...
await fetch9();
handleResult(9);
登入後複製
登入後複製

你可能會認為沒有人會真正這麼做......

在這個例子中,很明顯出了問題,但陷入這個問題並不難。

顯而易見:它很慢。你必須觸發並等待每個請求,如果速度很慢…你必須等待。

v1 - 渴望版本

您知道您不想單獨等待每個請求......因此您觸發所有請求,然後等待它們完成。

await Promise.all([
  fetch1(),
  fetch2(),
  ...
  fetch9(),
]);
handleAllResults(results);
登入後複製
登入後複製

這就是你可能會做的事情,所以這很好,對吧?

我的意思是,除非您有一個請求速度很慢……這意味著即使所有其他請求都已完成……您仍然必須等待該請求完成。

v2 - 更聰明、更熱心的版本

你知道你可能有一些較慢的請求,所以你仍然觸發所有請求並等待,但當它們到來時,你已經在可能的情況下對結果做了一些事情,所以當最後一個請求到達時,其他請求已經完成。

await fetch1();
handleResult(1);
await fetch2();
handleResult(2);
...
await fetch9();
handleResult(9);
登入後複製
登入後複製

這一定是最好的解決方案,對吧?

嗯……有什麼奇怪的嗎?

v3 - 我在騙你…這就是 v1 該的樣子

還記得 v1 嗎?是的...它應該是這樣的:

事實證明,在 http/1 中同一個端點可以擁有的連線數量是有限制的,不僅如此…它還依賴瀏覽器,並且每個瀏覽器可能有不同的限制。

您可能會認為只使用 http/2 就到此為止了…但即使這是一個很好的解決方案,您仍然需要在前端處理多個端點。

有沒有好的解決方案?

v4 - 進入流!

讓我們回顧一下 v0,但使用流......

你很聰明,所以你可能已經預料到了這一點,因為警告有點破壞了它......但是,是的......你之前看到的並不是後端生成的所有數據。

無論如何…當我們取得時我們就會渲染。

await Promise.all([
  fetch1(),
  fetch2(),
  ...
  fetch9(),
]);
handleAllResults(results);
登入後複製
登入後複製

如果我們點擊即將到來的串流,我們就可以對它到來的資料塊做一些事情。 (是的!就像 Chat GPT 之類的一樣。)

即使 v0 是處理這個問題最糟糕的方法,但透過使用流可以大大改善它。即使總等待時間相同,您也可以透過顯示某些內容來欺騙使用者。

再次是 v5 - v1,但是帶有流!

http/1 問題仍然是一個問題,但同樣,您已經可以看到事情的來龍去脈。

是的…我不能再拖延了…所以…

v6 - 一個 API 來統治它們!

或…也許我可以?

你看,前端必須管理太多......如果我們可以將其卸載到後端,那麼您就可以擁有一個端點來處理所有來源。

這解決了前端的複雜性和 http/1 問題。

await Promise.all([
  fetch1().then(handleResult),
  fetch2().then(handleResult),
  ...
  fetch9().then(handleResult),
]);
登入後複製


// usually we do this:
await fetch(...).then((res) => {
  // this json call accumulate all the response
  // that later is returned for you to use
  return res.json()
})
登入後複製

v7 - 最後......一個 API、多個來源和串流媒體。

我們呼叫一個 API,它將呼叫所有來源、串流資料、處理數據,並將其傳遞到前端,而前端又會在資料到來時呈現資料。

用於此的程式碼正面和背面基本上相同:

await fetchAll();
handleAllResults(results);
登入後複製

是的……就是這樣(最基本、最簡單的例子)。

我們將字串加入到緩衝區中,解析它,檢查是否有可用的區塊,使用它,然後忘記它。這意味著您可以接收/消耗 TB 級的資料…一次一大塊,而 RAM 很少。

我知道你在想什麼...這很愚蠢......這也是瘋狂......

MOOOOOOOOM 我想要 Websocket!

不,親愛的,我們家裡有網路套接字!

家裡的 Websocket:下一個?

v8 - 如果它不起作用,那才是愚蠢的

你很聰明,你認為如果來源仍在產生資料......那麼也許我們可以更新一些變數......

透過這種方式,您可以保持一個連線用於獲取更多資料或更改其產生的內容。

是的......我想你可以做到這一點......並且在你的堅持下我做了這個例子。 =D

仍然......這是一個愚蠢的想法,我不知道它在哪裡/是否可以在真實的生產環境中使用。也許如果你回到 MPA 和 Ajax 之間那個尷尬的 JS 階段,在這個階段你有足夠的互動性,但沒有足夠的連接到同一伺服器(某些瀏覽器的限制只有 2 個!),那麼也許?

除此之外,不知道。如果您確實有……請告訴我。

在上面的範例中,注意中間的面板,尤其是「進度邊框」:你可以看到它不斷更新。如果您開啟網路選項卡,您會看到 GET 連線在結束之前從未關閉。您還會看到多個其他請求,這些請求改變了那個仍然存在的連接正在執行的操作…所有這些都使用普通的 http/1。

接下來是什麼?

字串與 JSON

這個例子是我能做的最基本的例子。我什至使用簡單的字串而不是 JSON,因為它更容易解析。

要使用 JSON,您必須累積字串(出於某種原因,我們必須對後端回應進行 JSON.stringify)。

然後檢查在哪裡打破它,然後解析該值或邊解析邊解析。

對於第一個,請考慮 NDJSON:而不是 JSON 數組,您可以用換行符號分隔對象,然後您可以“更輕鬆地”找到中斷的位置,然後 JSON.parse 每個對象並使用該對象。

對於後者,你可以邊解析邊解析:你知道你在一個數組中,現在它是一個對象,好的第一個鍵,現在它是鍵的值,下一個鍵,跳過那個,下一個鍵......等等……手動製作並不是一件簡單的事情,但這就像在等待時從等待然後渲染到渲染的跳轉,這一切都是關於……除了……規模更小。

錯誤處理

人們喜歡託管範例,這個您需要自己運行...我希望現在不將範例託管在某個地方的原因已經清楚,但另一個原因是我們不希望這裡出現任何錯誤,如果您要這樣做的話加入網路錯誤高於一切......好吧......

應該要處理錯誤,但它們確實增加了另一層複雜性。

你應該使用它嗎?

也許...你可以說取決於...

有些地方串流是答案,但在大多數情況下......await json 就足夠了(更不用說更容易了)。

但是學習流程可以解決一些問題,無論是在前端或後端。

在前端,你總是可以用它來「欺騙」使用者。您可以在某些內容出現時顯示它,然後在出現時顯示更多內容,而不是到處顯示旋轉器,即使這需要一段時間。只要您不阻止用戶與其互動...您甚至可以製作比僅顯示旋轉器「更慢」的東西感覺就像它比任何東西都快實際上更快.

在後端,您可以節省 RAM,因為您可以解析每個資料塊,無論是來自前端、資料庫還是中間的任何其他資料。根據需要處理數據並發送數據,而不必等待整個有效負載,否則會引發 OOM(記憶體不足)錯誤。 GB 甚至 TB 的數據…當然,為什麼不呢?

尾奏

React 慢嗎?整個範例前端是用 React 完成的,除了所有閃爍的「燈」發生的「主要」事情之外,還有很多其他事情發生。

是的......如果你走得夠快,範例就無法跟上並開始凍結。但由於每分鐘很容易進行數千個渲染……我確實認為這對於大多數應用程式來說已經足夠了。

並且,您始終可以提高性能:對於“進度邊框”,如果您需要在渲染中保存一些內容,我使用了延遲值來使其更加平滑......我可以為“燈光”完成此操作以及其他性能增強和標題,但它只會讓“燈”在很多時候停止閃爍(這不會成為一個很好的演示),而且標題中的“電動”下劃線也不會那麼有趣。

在這個例子中,所有這些「改進」都不是理想的,但對於正常的應用程式...你可以讓它處理很多事情。如果您確實需要更多東西,那麼在這種情況下請使用其他解決方案。

結論

將流添加到您的武器庫中......它可能不是萬能的解決方案,但有一天它肯定會派上用場。

如果你想用它做點什麼並且需要幫助,那麼…也許可以打電話給我。 =P

以上是Chunk-Busters:不要跨越溪流!的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
<🎜>掩蓋:探險33-如何獲得完美的色度催化劑
2 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1677
14
CakePHP 教程
1430
52
Laravel 教程
1333
25
PHP教程
1278
29
C# 教程
1257
24
Python vs. JavaScript:學習曲線和易用性 Python vs. JavaScript:學習曲線和易用性 Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

JavaScript和Web:核心功能和用例 JavaScript和Web:核心功能和用例 Apr 18, 2025 am 12:19 AM

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

JavaScript在行動中:現實世界中的示例和項目 JavaScript在行動中:現實世界中的示例和項目 Apr 19, 2025 am 12:13 AM

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

了解JavaScript引擎:實施詳細信息 了解JavaScript引擎:實施詳細信息 Apr 17, 2025 am 12:05 AM

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python vs. JavaScript:開發環境和工具 Python vs. JavaScript:開發環境和工具 Apr 26, 2025 am 12:09 AM

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

C/C在JavaScript口譯員和編譯器中的作用 C/C在JavaScript口譯員和編譯器中的作用 Apr 20, 2025 am 12:01 AM

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。1)C 用于解析JavaScript源码并生成抽象语法树。2)C 负责生成和执行字节码。3)C 实现JIT编译器,在运行时优化和编译热点代码,显著提高JavaScript的执行效率。

Python vs. JavaScript:比較用例和應用程序 Python vs. JavaScript:比較用例和應用程序 Apr 21, 2025 am 12:01 AM

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。

從網站到應用程序:JavaScript的不同應用 從網站到應用程序:JavaScript的不同應用 Apr 22, 2025 am 12:02 AM

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

See all articles