成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何選擇

calx / 2521人閱讀

摘要:注意值得注意的是,一旦接收到所有幀并且原始消息有效載荷已被重建,客戶端將僅被通知關(guān)于新消息。實(shí)驗(yàn)表明,在之后創(chuàng)建了第二個(gè)幀。以下值目前正在使用中代表繼續(xù)幀。

這一次,我們將深入到通信協(xié)議的世界中,對(duì)比并討論它們的屬性并構(gòu)建部件。我們將提供WebSockets和HTTP / 2的快速比較。 最后,我們分享一些關(guān)于如何選擇網(wǎng)絡(luò)協(xié)議。

概述

如今,擁有豐富動(dòng)態(tài)用戶界面的復(fù)雜網(wǎng)絡(luò)應(yīng)用程序被視為理所當(dāng)然。這并不奇怪 - 互聯(lián)網(wǎng)自成立以來(lái)已經(jīng)走過(guò)了很長(zhǎng)的一段路。

最初,互聯(lián)網(wǎng)并不是為支持這種動(dòng)態(tài)和復(fù)雜的網(wǎng)絡(luò)應(yīng)用程序而構(gòu)建的。它被認(rèn)為是HTML頁(yè)面的集合,彼此鏈接以形成包含信息的“web”概念。一切都基本上圍繞HTTP的所謂的請(qǐng)求/響應(yīng)范式而建立??蛻舳思虞d一個(gè)頁(yè)面,然后什么都不會(huì)發(fā)生,直到用戶點(diǎn)擊并導(dǎo)航到下一頁(yè)。

大約在2005年,AJAX被引入,許多人開始探索在客戶端和服務(wù)器之間建立雙向連接的可能性。盡管如此,所有HTTP通信都是由客戶端引導(dǎo)的,這需要用戶交互或定期輪詢從服務(wù)器加載新數(shù)據(jù)。

使HTTP成為“雙向”

使服務(wù)器“主動(dòng)”向客戶端發(fā)送數(shù)據(jù)的技術(shù)已經(jīng)存在了相當(dāng)長(zhǎng)的一段時(shí)間。例如“Push”和“Comet”等等。

服務(wù)器向客戶端發(fā)送數(shù)據(jù)的最常見竅門之一稱為長(zhǎng)輪詢。通過(guò)長(zhǎng)輪詢,客戶端打開一個(gè)HTTP連接到服務(wù)器,該服務(wù)器保持打開狀態(tài)直到發(fā)送響應(yīng)。只要服務(wù)器有新的數(shù)據(jù)需要發(fā)送,它就會(huì)將其作為響應(yīng)發(fā)送出去。

我們來(lái)看看一個(gè)非常簡(jiǎn)單的長(zhǎng)輪詢片段的樣子:

(function poll(){
   setTimeout(function(){
      $.ajax({ 
        url: "https://api.example.com/endpoint", 
        success: function(data) {
          // Do something with `data`
          // ...

          //Setup the next poll recursively
          poll();
        }, 
        dataType: "json"
      });
  }, 10000);
})();

這基本上是自動(dòng)執(zhí)行的功能,自動(dòng)運(yùn)行第一次。 它設(shè)置十(10)秒的間隔,并在每次異步Ajax調(diào)用服務(wù)器之后,回調(diào)再次調(diào)用ajax。

其他技術(shù)涉及Flash或XHR多部分請(qǐng)求和所謂的htmlfiles。

所有這些解決方案都有相同的問(wèn)題:它們承載HTTP的開銷,這并不能使它們非常適合低延遲的應(yīng)用程序。在瀏覽器或任何其他具有實(shí)時(shí)組件的在線游戲中考慮多人第一人稱射擊游戲。

WebSockets的引入

WebSocket規(guī)范定義了在Web瀏覽器和服務(wù)器之間建立“套接字”連接的API。 簡(jiǎn)而言之:客戶端和服務(wù)器之間存在持久連接,并且雙方可以隨時(shí)開始發(fā)送數(shù)據(jù)。

客戶端通過(guò)稱為WebSocket握手的過(guò)程建立WebSocket連接。該過(guò)程從客戶端向服務(wù)器發(fā)送常規(guī)HTTP請(qǐng)求開始。此請(qǐng)求中包含Upgrade頭信息,通知服務(wù)器客戶端希望建立WebSocket連接。

我們來(lái)看看如何在客戶端打開WebSocket連接:

// 創(chuàng)建一個(gè)加密連接的WebSocket
var socket = new WebSocket("ws://websocket.example.com");

這個(gè)scheme只是開始打開websocket.example.com的WebSocket連接的過(guò)程。

以下是初始請(qǐng)求頭的簡(jiǎn)化示例:

GET ws://websocket.example.com/ HTTP/1.1
Origin: http://example.com
Connection: Upgrade
Host: websocket.example.com
Upgrade: websocket

如果服務(wù)器支持WebSocket協(xié)議,它將同意Upgrade,并將通過(guò)響應(yīng)中的Upgrade頭進(jìn)行通信。

我們來(lái)看看如何在Node.JS中實(shí)現(xiàn)這個(gè)功能:

// We"ll be using the https://github.com/theturtle32/WebSocket-Node
// WebSocket implementation
var WebSocketServer = require("websocket").server;
var http = require("http");

var server = http.createServer(function(request, response) {
  // process HTTP request. 
});
server.listen(1337, function() { });

// create the server
wsServer = new WebSocketServer({
  httpServer: server
});

// WebSocket server
wsServer.on("request", function(request) {
  var connection = request.accept(null, request.origin);

  // This is the most important callback for us, we"ll handle
  // all messages from users here.
  connection.on("message", function(message) {
      // Process WebSocket message
  });

  connection.on("close", function(connection) {
    // Connection closes
  });
});

連接建立后,服務(wù)器通過(guò)Upgrade進(jìn)行回復(fù):

HTTP/1.1 101 Switching Protocols
Date: Wed, 25 Oct 2017 10:07:34 GMT
Connection: Upgrade
Upgrade: WebSocket

連接建立后,open事件將在客戶端的WebSocket實(shí)例上觸發(fā):

var socket = new WebSocket("ws://websocket.example.com");

// Show a connected message when the WebSocket is opened.
socket.onopen = function(event) {
  console.log("WebSocket is connected.");
};

現(xiàn)在握手已經(jīng)完成,初始HTTP連接被替換為使用相同底層TCP / IP連接的WebSocket連接。此時(shí),任何一方都可以開始發(fā)送數(shù)據(jù)。

借助WebSocket,您可以隨心所欲地傳輸盡可能多的數(shù)據(jù),而不會(huì)產(chǎn)生與傳統(tǒng)HTTP請(qǐng)求相關(guān)的開銷。數(shù)據(jù)通過(guò)WebSocket作為消息傳輸,每個(gè)消息由一個(gè)或多個(gè)包含您要發(fā)送的數(shù)據(jù)(有效負(fù)載)的幀組成。 為了確保消息在到達(dá)客戶端時(shí)能夠被正確地重建,每個(gè)幀都以4-12字節(jié)的有效負(fù)載數(shù)據(jù)作為前綴。 使用這種基于幀的消息傳遞系統(tǒng)有助于減少傳輸?shù)姆怯行лd荷數(shù)據(jù)量,從而顯著減少延遲。

注意:值得注意的是,一旦接收到所有幀并且原始消息有效載荷已被重建,客戶端將僅被通知關(guān)于新消息。

WebSocket URLs

我們之前簡(jiǎn)要提到過(guò),WebSockets引入了一個(gè)新的URL方案。實(shí)際上,他們引入了兩個(gè)新的方案:ws://和wss://。

網(wǎng)址具有特定schema語(yǔ)法。WebSocket URL特別之處在于它們不支持錨(#sample_anchor)。

對(duì)于HTTP風(fēng)格的URL,相同的規(guī)則適用于WebSocket風(fēng)格的URL。ws未加密,默認(rèn)端口為80,而wss需要TLS加密并且端口443為默認(rèn)端口。

成幀協(xié)議

讓我們更深入地了解組幀協(xié)議。 這是RFC為我們提供的內(nèi)容:

      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-------+-+-------------+-------------------------------+
     |F|R|R|R| opcode|M| Payload len |    Extended payload length    |
     |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
     |N|V|V|V|       |S|             |   (if payload len==126/127)   |
     | |1|2|3|       |K|             |                               |
     +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
     |     Extended payload length continued, if payload len == 127  |
     + - - - - - - - - - - - - - - - +-------------------------------+
     |                               |Masking-key, if MASK set to 1  |
     +-------------------------------+-------------------------------+
     | Masking-key (continued)       |          Payload Data         |
     +-------------------------------- - - - - - - - - - - - - - - - +
     :                     Payload Data continued ...                :
     + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
     |                     Payload Data continued ...                |
     +---------------------------------------------------------------+

從RFC指定的WebSocket版本開始,每個(gè)數(shù)據(jù)包前只有一個(gè)標(biāo)頭。不過(guò),這是一個(gè)相當(dāng)復(fù)雜的標(biāo)題。以下是其解釋的構(gòu)建塊:

fin(1比特):指示該幀是否構(gòu)成消息的最終幀。大多數(shù)情況下,消息適合于一個(gè)幀,并且該位總是被設(shè)置。實(shí)驗(yàn)表明,F(xiàn)irefox在32K之后創(chuàng)建了第二個(gè)幀。

rsv1,rsv2,rsv3(每個(gè)1位):除非擴(kuò)展協(xié)商定義了非零值的含義,否則必須為0。如果接收到非零值并且沒(méi)有任何協(xié)商的擴(kuò)展定義這種非零值的含義,則接收端點(diǎn)必須失敗連接。

opcode(4位):說(shuō)明幀代表什么。以下值目前正在使用中:

0x00:代表繼續(xù)幀。
0x01:代表文本幀。
0x02:代表二進(jìn)制幀。
0x08:該幀終止連接。
0x09:這個(gè)幀是一個(gè)ping。
0x0a:這個(gè)幀是一個(gè)pong。
(正如您所看到的,有足夠的值未被使用;它們已被保留供將來(lái)使用)。

掩碼(1位):指示連接是否被屏蔽。就目前而言,從客戶端到服務(wù)器的每條消息都必須被屏蔽,并且規(guī)范會(huì)在未被屏蔽的情況下終止連接。

payload_len(7比特):有效載荷的長(zhǎng)度。 WebSocket幀包含以下長(zhǎng)度括號(hào):
0-125表示有效載荷的長(zhǎng)度。 126表示以下兩個(gè)字節(jié)表示長(zhǎng)度,127表示接下來(lái)的8個(gè)字節(jié)表示長(zhǎng)度。所以有效負(fù)載的長(zhǎng)度在?7位,16位和64位括號(hào)內(nèi)。

屏蔽鍵(32位):從客戶端發(fā)送到服務(wù)器的所有幀都被幀中包含的32位值屏蔽。

有效載荷:最可能被掩蓋的實(shí)際數(shù)據(jù)。它的長(zhǎng)度是payload_len的長(zhǎng)度。

為什么WebSocket基于框架而不是基于流?我不知道,只是和你一樣,我很想了解更多,所以如果你有一個(gè)想法,請(qǐng)隨時(shí)在下面的回復(fù)中添加評(píng)論和資源。另外,關(guān)于這個(gè)主題的討論可以在HackerNews上找到。

關(guān)于幀的數(shù)據(jù)

如上所述,數(shù)據(jù)可以分成多個(gè)幀。傳輸數(shù)據(jù)的第一幀有一個(gè)操作碼,表示正在傳輸什么類型的數(shù)據(jù)。 這是必要的,因?yàn)樵谝?guī)范開始時(shí)JavaScript幾乎不存在對(duì)二進(jìn)制數(shù)據(jù)的支持。0x01表示utf-8編碼的文本數(shù)據(jù),0x02是二進(jìn)制數(shù)據(jù)。大多數(shù)人會(huì)傳輸JSON,在這種情況下,您可能想要選擇文本操作碼。當(dāng)你發(fā)射二進(jìn)制數(shù)據(jù)時(shí),它將在瀏覽器特定的Blob中表示。

通過(guò)WebSocket發(fā)送數(shù)據(jù)的API非常簡(jiǎn)單:

socket.onopen = function(event) {
  socket.send("Some message"); // Sends data to server.
};

當(dāng)WebSocket接收數(shù)據(jù)時(shí)(在客戶端),message事件被觸發(fā)。此事件包含一個(gè)稱為data的屬性,可用于訪問(wèn)消息的內(nèi)容。

// Handle messages sent by the server.
socket.onmessage = function(event) {
  var message = event.data;
  console.log(message);
};

您可以使用Chrome DevTools中的Network選項(xiàng)卡輕松瀏覽WebSocket連接中每個(gè)幀中的數(shù)據(jù):

碎片

有效載荷數(shù)據(jù)可以分成多個(gè)獨(dú)立的幀。接收端應(yīng)該緩沖它們直到fin位置位。所以你可以通過(guò)11個(gè)6(頭部長(zhǎng)度)包+每個(gè)1字節(jié)的字符串傳輸字符串“Hello World”。控制包不允許使用碎片。但是,規(guī)范要求您能夠處理交錯(cuò)控制幀。這是在TCP包以任意順序到達(dá)的情況下。

合并幀的邏輯大致如下:

接收第一幀

記得操作碼

將幀有效載荷連接在一起,直到fin位被設(shè)置

斷言每個(gè)包的操作碼都是零

分段的主要目的是在消息啟動(dòng)時(shí)允許發(fā)送未知大小的消息。通過(guò)分段,服務(wù)器可以選擇合理大小的緩沖區(qū),并且當(dāng)緩沖區(qū)滿時(shí),將一個(gè)片段寫入網(wǎng)絡(luò)。分片的次要用例是多路復(fù)用,其中一個(gè)邏輯信道上的大消息接管整個(gè)輸出信道是不可取的,因此多路復(fù)用需要自由將消息分成更小的片段以更好地共享輸出渠道。

什么是心跳?

在握手之后的任何時(shí)候,客戶端或服務(wù)器都可以選擇向?qū)Ψ桨l(fā)送ping命令。當(dāng)收到ping時(shí),收件人必須盡快發(fā)回pong。這是一個(gè)心跳。您可以使用它來(lái)確??蛻舳巳蕴幱谶B接狀態(tài)。

ping或pong只是一個(gè)常規(guī)幀,但它是一個(gè)控制幀。 ping具有0x9的操作碼,并且pongs具有0xA的操作碼。當(dāng)你得到一個(gè)ping之后,發(fā)回一個(gè)與ping完全相同的Payload Data的pong(對(duì)于ping和pongs,最大有效載荷長(zhǎng)度是125)。你也可能在沒(méi)有發(fā)送ping的情況下得到一個(gè)pong。如果發(fā)生,請(qǐng)忽略它。

心跳非常有用。有些服務(wù)(如負(fù)載均衡器)會(huì)終止空閑連接。另外,接收方不可能看到遠(yuǎn)端是否已經(jīng)終止。只有在下一次發(fā)送時(shí)你才會(huì)意識(shí)到出了問(wèn)題。

處理錯(cuò)誤

您可以通過(guò)監(jiān)聽錯(cuò)誤事件來(lái)處理發(fā)生的任何錯(cuò)誤。

它看起來(lái)像這樣:

var socket = new WebSocket("ws://websocket.example.com");

// Handle any error that occurs.
socket.onerror = function(error) {
  console.log("WebSocket Error: " + error);
};
關(guān)閉連接

要關(guān)閉連接,客戶端或服務(wù)器應(yīng)發(fā)送包含操作碼0x8的數(shù)據(jù)的控制幀。一旦接收到這樣的幀,對(duì)方發(fā)送一個(gè)關(guān)閉幀作為響應(yīng)。第一個(gè)同伴然后關(guān)閉連接。 然后放棄關(guān)閉連接后收到的任何其他數(shù)據(jù)。

這是您如何啟動(dòng)從客戶端關(guān)閉WebSocket連接的方式:

// Close if the connection is open.
if (socket.readyState === WebSocket.OPEN) {
    socket.close();
}

另外,為了在關(guān)閉完成后執(zhí)行任何清理,您可以將事件偵聽器附加到關(guān)閉事件:

// Do necessary clean up.
socket.onclose = function(event) {
  console.log("Disconnected from WebSocket.");
};

服務(wù)器必須偵聽關(guān)閉事件以便在需要時(shí)處理它:

connection.on("close", function(reasonCode, description) {
    // The connection is getting closed.
});
WebSockets和HTTP/2對(duì)比

盡管HTTP/2具有很多功能,但并不能完全取代現(xiàn)有推送/流媒體技術(shù)的需求。

關(guān)于HTTP/2的第一件重要事情是,它不能代替所有的HTTP。 動(dòng)詞,狀態(tài)代碼和大部分標(biāo)題將保持與今天相同。HTTP/2是關(guān)于提高數(shù)據(jù)在線路上傳輸方式的效率。

現(xiàn)在,如果我們比較HTTP / 2和WebSocket,我們可以看到很多相似之處:

正如我們上面看到的那樣,HTTP/2引入了服務(wù)器推送,它使服務(wù)器能夠主動(dòng)發(fā)送資源到客戶端緩存。但是,它并不允許將數(shù)據(jù)推送到客戶端應(yīng)用程序本身。服務(wù)器推送只能由瀏覽器處理,并且不會(huì)在應(yīng)用程序代碼中彈出,這意味著應(yīng)用程序沒(méi)有API來(lái)獲取這些事件的通知。

這是Server-Sent Events(SSE)變得非常有用的地方。SSE是一種允許服務(wù)器在建立客戶端 - 服務(wù)器連接后將數(shù)據(jù)異步推送到客戶端的機(jī)制。只要有新的“大塊”數(shù)據(jù)可用,服務(wù)器就可以決定發(fā)送數(shù)據(jù)。它可以被認(rèn)為是一種單向發(fā)布 - 訂閱模式。它還提供了一個(gè)標(biāo)準(zhǔn)的JavaScript客戶端API,名為EventSource,在大多數(shù)現(xiàn)代瀏覽器中實(shí)現(xiàn),作為W3C的HTML5標(biāo)準(zhǔn)的一部分。請(qǐng)注意,不支持EventSource API的瀏覽器可以很容易地被polyfilled。

由于SSE基于HTTP,因此它非常適合HTTP/2,并且可以結(jié)合使用以實(shí)現(xiàn)最佳效果:HTTP/2基于多路復(fù)用流處理高效傳輸層,SSE將API提供給應(yīng)用程序以啟用推。

為了充分理解Streams和Multiplexing是什么,我們首先看看IETF的定義:“stream”是在HTTP / 2連接中在客戶端和服務(wù)器之間交換的一個(gè)獨(dú)立的雙向幀序列。其主要特征之一是單個(gè)HTTP/2連接可以包含多個(gè)同時(shí)打開的流,其中來(lái)自多個(gè)流的端點(diǎn)交織幀。

我們必須記住SSE是基于HTTP的。這意味著在HTTP/2中,不僅可以將多個(gè)SSE流交織到單個(gè)TCP連接上,還可以通過(guò)多個(gè)SSE流(服務(wù)器到客戶端推送)和多個(gè)客戶端請(qǐng)求(客戶端到服務(wù)器)。由于HTTP/2和SSE,現(xiàn)在我們有一個(gè)純粹的HTTP雙向連接和一個(gè)簡(jiǎn)單的API,讓應(yīng)用程序代碼注冊(cè)到服務(wù)器推送。將SSE與WebSocket進(jìn)行比較時(shí),缺乏雙向功能通常被認(rèn)為是一個(gè)主要缺陷。 由于HTTP/2,這不再是這種情況。這為跳過(guò)WebSocket并堅(jiān)持使用基于HTTP的信號(hào)提供了機(jī)會(huì)。

WebSocket還是HTTP/2

WebSockets肯定會(huì)在HTTP / 2 + SSE的控制下生存下去,主要是因?yàn)樗且环N已經(jīng)被很好地采用的技術(shù),并且在非常具體的使用情況下,它比HTTP/2具有優(yōu)勢(shì),因?yàn)樗呀?jīng)以較少的開銷構(gòu)建用于雙向能力(例如頭)。

假設(shè)你想構(gòu)建一個(gè)Massive Multiplayer在線游戲,需要來(lái)自連接兩端的大量消息。在這種情況下,WebSockets的性能會(huì)好很多。

通常,只要需要客戶端和服務(wù)器之間的真正低延遲,近實(shí)時(shí)的連接,就使用WebSocket。請(qǐng)記住,這可能需要重新考慮如何構(gòu)建服務(wù)器端應(yīng)用程序,以及將焦點(diǎn)轉(zhuǎn)移到事件隊(duì)列等技術(shù)上。

如果您的使用案例需要顯示實(shí)時(shí)市場(chǎng)新聞,市場(chǎng)數(shù)據(jù),聊天應(yīng)用程序等,依靠HTTP/2 + SSE將為您提供高效的雙向溝通??渠道,同時(shí)獲得留在HTTP世界的好處:

當(dāng)考慮到與現(xiàn)有Web基礎(chǔ)架構(gòu)的兼容性時(shí),WebSocket通常會(huì)成為痛苦的源頭,因?yàn)樗鼘TTP連接升級(jí)到與HTTP無(wú)關(guān)的完全不同的協(xié)議。

規(guī)模和安全性:Web組件(防火墻,入侵檢測(cè),負(fù)載平衡器)是以HTTP為基礎(chǔ)構(gòu)建,維護(hù)和配置的,這是大型/關(guān)鍵應(yīng)用程序在彈性,安全性和可伸縮性方面更喜歡的環(huán)境。

另外,您必須考慮瀏覽器支持??纯碬ebSocket:

實(shí)際上相當(dāng)不錯(cuò),不是嗎?

然而,HTTP/2的情況并不相同:

僅TLS(不是很糟糕)

部分支持IE 11,但僅限于Windows 10

僅在Safari中支持OSX 10.11+

如果您可以通過(guò)ALPN進(jìn)行協(xié)商,則僅支持HTTP/2(您的服務(wù)器需要明確支持)

SSE支持的更好:

只有IE / Edge不提供支持。(好吧,Opera Mini既不支持SSE也不支持WebSocket,所以我們可以將其完全排除在外)。 在IE / Edge中有一些體面的polyfills用于SSE支持。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/107748.html

相關(guān)文章

  • JavaScript 工作原理深入理解 WebSockets 帶有 SSE 機(jī)制的HTTP/

    摘要:幀協(xié)議讓我們深入了解下幀協(xié)議。目前可用的值該幀接續(xù)前面一幀的有效載荷。該幀包含二進(jìn)制數(shù)據(jù)。幀有以下幾類長(zhǎng)度表示有效載荷的長(zhǎng)度。數(shù)據(jù)分片有效載荷數(shù)據(jù)可以被分成多個(gè)獨(dú)立的幀。接收端會(huì)緩沖這些幀直到位有值。 原文請(qǐng)查閱這里,略有改動(dòng),本文采用知識(shí)共享署名 3.0 中國(guó)大陸許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請(qǐng)查閱這里。 這是 JavaScript 工作原...

    lijinke666 評(píng)論0 收藏0
  • JavaScript如何工作: 深入探索 websocket HTTP/2SSE +如何選擇

    摘要:數(shù)據(jù)作為消息通過(guò)傳輸,每個(gè)消息由一個(gè)或多個(gè)幀組成,其中包含正在發(fā)送的數(shù)據(jù)有效負(fù)載。幀數(shù)據(jù)如上所述,數(shù)據(jù)可以被分割成多個(gè)幀。但是,規(guī)范希望能夠處理交錯(cuò)的控制幀。 文章底部分享給大家一套 react + socket 實(shí)戰(zhàn)教程 這是專門探索 JavaScript 及其所構(gòu)建的組件的系列文章的第5篇。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你! 如果你錯(cuò)過(guò)了前面的章...

    cuieney 評(píng)論0 收藏0
  • 程序員練級(jí)攻略(2018):前端基礎(chǔ)底層原理

    摘要:下面我們從前端基礎(chǔ)和底層原理開始講起。對(duì)于和這三個(gè)對(duì)應(yīng)于矢量圖位圖和圖的渲染來(lái)說(shuō),給前端開發(fā)帶來(lái)了重武器,很多小游戲也因此蓬勃發(fā)展。這篇文章受眾之大,后來(lái)被人重新整理并發(fā)布為,其中還包括中文版。 showImg(https://segmentfault.com/img/bVbjM5r?w=1142&h=640); 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你! 這...

    widuu 評(píng)論0 收藏0
  • 前端每周清單第 38 期: Node 9 發(fā)布,Kotlin 與 React,Netflix 架構(gòu)解

    摘要:發(fā)布本周正式發(fā)布,包含了一系列的特性提升與問(wèn)題修復(fù),同時(shí)也在不斷致力于將打造地更為輕巧與高性能。當(dāng)然,姜振勇老師還會(huì)介紹的多種服務(wù),包括大數(shù)據(jù)網(wǎng)絡(luò)和安全,展現(xiàn)彈性安全和高可擴(kuò)展性的全方位能力。 showImg(http://upload-images.jianshu.io/upload_images/1647496-2ce7598e6987d9af.jpg?imageMogr2/aut...

    Carbs 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<