title: Fetch Request VS. WebSocket Which one is faster?
body: <p>I'm sending a same data in both <code>Fetch</code> and <code>WebSocket</code> but :</p>
  <ul>
  <li>HTTP takes <code>29</code> seconds to transfer around <code>200 MB</code>.</li>
  <li>WebSocket takes <code>6</code> seconds to transfer around <code>200 MB</code>.</li>
  </ul>
  <h3>Question</h3>
  <p>Why <code>WebSocket</code> is faster than <code>HTTP</code>?
  It's related to encoding or technology or something else...?</p>
  <h3>Fetch</h3>
  <pre><code> async function postData(url = '', data) {
          const response = await fetch(url, {
              method: 'POST',
              mode: 'no-cors',
              cache: 'no-cache',
              credentials: 'same-origin',
              headers: {
                  'Content-Type': 'application/octet-stream'
              },
              redirect: 'follow',
              referrerPolicy: 'no-referrer',
              body: data
          });
          return response; //.arrayBuffer();
      }
  
      postData('http://localhost:3800/buffer', arrU8)
          .then(data =&gt; {
              console.log(data);
          });
  </code></pre>
  <p><code>arrU8</code> is an <code>Uint8Array</code> by length : 185578200</p>
  <h3>WebSocket</h3>
  <pre><code>  function connect() {
          return new Promise(function (resolve, reject) {
              var ws = new WebSocket('ws://127.0.0.1:8081/echo');
              ws.onopen = function () {
                  resolve(ws);
              };
              ws.onerror = function (err) {
                  reject(err);
              };
              ws.onclose = function (evt) {
                  console.log(&quot;CLOSE SOCKET&quot;, new Date().toLocaleString());
              };
              ws.onmessage = function (evt) {
                  console.log(&quot;RESPONSE SOCKET: &quot; + &quot;RECEIVED&quot; /* evt.data */, new Date().toLocaleString());
              };
          });
      }
  
      connect().then(function (ws) {
          // onopen
          ws.binaryType = 'arraybuffer';
          ws.send(arrU8);
          ws.close();
      }).catch(function (err) {
          // onerror
          console.log(&quot;ERROR: &quot; + evt.data, new Date().toLocaleString());
      });
  </code></pre>
  <h2>Server Side is wrote by GO</h2>
  <h4>HTTP</h4>
  <pre><code>func process(w http.ResponseWriter, r *http.Request) {
  
      if r.URL.Path != &quot;/buffer&quot; {
          http.Error(w, &quot;404 not found.&quot;, http.StatusNotFound)
          return
      }
  
      switch r.Method {
      case &quot;GET&quot;:
  
          fmt.Fprintf(w, &quot;GET request is received: %s \n&quot;, r.URL)
      case &quot;POST&quot;:
  
          body, err := ioutil.ReadAll(r.Body)
          if err != nil {
              http.Error(w, err.Error(), http.StatusInternalServerError)
              return
          }
          log.Println(&quot;Data length received = &quot;, len(body))
  
          fmt.Fprintf(w, &quot;Data length = %v \n&quot;, len(body))
  
      default:
          fmt.Fprintf(w, &quot;Sorry, only GET and POST methods are supported.&quot;)
      }
  }
  </code></pre>
  <h4>WebSocket</h4>
  <pre><code>package main
  
  import (
      &quot;flag&quot;
      &quot;log&quot;
      &quot;net/http&quot;
      &quot;text/template&quot;
  
      &quot;github.com/gorilla/websocket&quot;
  )
  
  var addr = flag.String(&quot;addr&quot;, &quot;localhost:8081&quot;, &quot;http service address&quot;)
  var upgrader = websocket.Upgrader{} // use default options
  func main() {
  
      log.Println(&quot;Launching WebSocket server...&quot;, *addr)
      flag.Parse()
      log.SetFlags(log.LstdFlags | log.Lmicroseconds)
      http.HandleFunc(&quot;/echo&quot;, echo)
      http.HandleFunc(&quot;/&quot;, home)
      log.Fatal(http.ListenAndServe(*addr, nil))
  }
  
  func echo(w http.ResponseWriter, r *http.Request) {
  
      // To fix 403 error temporarily. It's unsafe:
      upgrader.CheckOrigin = func(r *http.Request) bool { return true }
  
      c, err := upgrader.Upgrade(w, r, nil)
      if err != nil {
          log.Print(&quot;upgrade:&quot;, err)
          return
      }
      defer c.Close()
      for {
          mt, message, err := c.ReadMessage()
          if err != nil {
              log.Println(&quot;read:&quot;, err)
              break
          }
          log.Println(&quot;recv: message type:&quot;, mt)
          log.Printf(&quot;recv: bytes count: %v&quot;, len(message))
          // // // Disable echo and log
          // log.Printf(&quot;recv: %s&quot;, message)
          // err = c.WriteMessage(mt, message)
          // if err != nil {
          //  log.Println(&quot;write:&quot;, err)
          //  break
          // }
      }
  }
  
  func home(w http.ResponseWriter, r *http.Request) {
      homeTemplate.Execute(w, &quot;ws://&quot;+r.Host+&quot;/echo&quot;)
  }
  </code></pre>