Comparing Fetch Request and WebSocket: Determining the Quickest Option

When sending the same data in both Fetch and WebSocket, there is a noticeable speed difference:

  • HTTP takes 29 seconds to transfer around 200 MB.
  • WebSocket takes 6 seconds to transfer around 200 MB.

An Interesting Observation:

Why does WebSocket outperform HTTP? Is it due to encoding, technology, or something else?

Investigating Fetch:

 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 => {
            console.log(data);
        });

arrU8 is an Uint8Array with a length of 185578200

Delving into WebSocket:

  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("CLOSE SOCKET", new Date().toLocaleString());
            };
            ws.onmessage = function (evt) {
                console.log("RESPONSE SOCKET: " + "RECEIVED" /* evt.data */, new Date().toLocaleString());
            };
        });
    }

    connect().then(function (ws) {
        // onopen
        ws.binaryType = 'arraybuffer';
        ws.send(arrU8);
        ws.close();
    }).catch(function (err) {
        // onerror
        console.log("ERROR: " + evt.data, new Date().toLocaleString());
    });

The Server Side Utilizes GO Language:

Looking at HTTP:

func process(w http.ResponseWriter, r *http.Request) {

    if r.URL.Path != "/buffer" {
        http.Error(w, "404 not found.", http.StatusNotFound)
        return
    }

    switch r.Method {
    case "GET":

        fmt.Fprintf(w, "GET request is received: %s \n", r.URL)
    case "POST":

        body, err := ioutil.ReadAll(r.Body)
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        log.Println("Data length received = ", len(body))

        fmt.Fprintf(w, "Data length = %v \n", len(body))

    default:
        fmt.Fprintf(w, "Sorry, only GET and POST methods are supported.")
    }
}

Unveiling WebSocket:

package main

import (
    "flag"
    "log"
    "net/http"
    "text/template"

    "github.com/gorilla/websocket"
)

var addr = flag.String("addr", "localhost:8081", "http service address")
var upgrader = websocket.Upgrader{} // use default options
func main() {

    log.Println("Launching WebSocket server...", *addr)
    flag.Parse()
    log.SetFlags(log.LstdFlags | log.Lmicroseconds)
    http.HandleFunc("/echo", echo)
    http.HandleFunc("/", 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("upgrade:", err)
        return
    }
    defer c.Close()
    for {
        mt, message, err := c.ReadMessage()
        if err != nil {
            log.Println("read:", err)
            break
        }
        log.Println("recv: message type:", mt)
        log.Printf("recv: bytes count: %v", len(message))
        // // // Disable echo and log
        // log.Printf("recv: %s", message)
        // err = c.WriteMessage(mt, message)
        // if err != nil {
        //  log.Println("write:", err)
        //  break
        // }
    }
}

func home(w http.ResponseWriter, r *http.Request) {
    homeTemplate.Execute(w, "ws://"+r.Host+"/echo")
}

Answer №1

Using Websocket can offer quicker transmission of data over time due to the ability to maintain an open connection with the server.

Contrastingly, HTTP requires a 2-way handshake each time a connection needs to be established to send data.

This is mainly because HTTP is unable to transmit all the necessary information in one session, hence requiring multiple handshakes.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Generate an interactive table: one segment featuring a title or tag - its corresponding rows and columns that change dynamically, followed by another similar segment

I'm attempting to generate a dynamic table with the following structure upon clicking a button (I can't include an image, so here is a sample code to illustrate what I'm aiming for, but I need everything to be dynamic in the actual scenario) ...

Optimal method for translating date string data from JSON to the user interface

Let's take a look at this JSON response: { data: { nestedData: { someMoreNestedData: { someArray: [ { someWhereThereIsADate: '2018-10-26' } ] }, w ...

The AJAX request is failing to delete the record

I am attempting to remove a record from the database using an Ajax call in my MVC application. Below is the code for the function that initiates the Ajax call. <script> function deleteRow(item, mdkey) { var r = confirm("Are you sure you ...

The xhr.upload event listener is triggered when the xhr.responseText is empty after loading

const request = new XMLHttpRequest(); request.open('put', url, false); request.upload.addEventListener('load', function(e) { alert(request.responseText); }, false); Why is the responseText property of the XMLHttpRequest object empt ...

What could be the reason for the malfunction of basic javascript code?

HTML: <p id="demo"></p> Here is the script in JavaScript: document.getElementById("demo").innerHTML = 5 + 6; After adding a separate JavaScript file called myScript.js to contain the code, nothing is being displayed as expected. I linked th ...

Using getStaticProps in Next.js to retrieve menu data and seamlessly integrate it into the layout

I have integrated Sanity.io as a backend for my project, specifically managing the data for my main menu in parent/children object arrays. While I am able to successfully fetch this data, I prefer to utilize getStaticProps to ensure that my site remains c ...

Is it necessary to compile Jade templates only once?

I'm new to exploring jade in conjunction with express.js and I'm on a quest to fully understand jade. Here's my query: Express mentions caching jade in production - but how exactly does this process unfold? Given that the output is continge ...

Sorting through an array of objects using criteria from a separate array of objects

Currently, I am faced with the task of filtering an array of objects based on criteria from another array. Essentially, I am looking to refine a list based on filters selected by the user. To illustrate, let's consider my initial list of results: [ ...

Having trouble displaying the image in my administrative tool

I am currently developing an admin application that will showcase uploaded product images stored in a database. The images are saved as object IDs in MongoDB. However, the image container in the admin app shows the count of images stored in the database bu ...

Incorporating an SVG with CSS styling from a stylesheet

After exploring various articles and questions on the topic, I am yet to find a definitive solution. I have an external file named icon.svg, and my objective is to utilize it across multiple HTML files with different fill colors and sizes for each instanc ...

Access the DOM using $(this) after integrating the plugin

I have limited knowledge when it comes to jquery plugins. I am currently using a plugin from which allows me to execute a function after n seconds of a keypress event. However, I am facing an issue when trying to pass the current DOM element to the functi ...

Replace the empty slots in the array with an underscore

Is it possible to use underscorejs to populate missing elements in an array? For example: fillGaps([1,2,3,6,7,22,23,24]) => [1,2,3,'...',6,7,'...',22,23,24] ...

What exactly does the jquery ajax success callback cover?

Is the value of testvar in function AjaxRequest going to increase on success? function AjaxRequest(){ var testvar = 0; for(i=0;i<d.length;i++){ $.ajax({ success: function(a){ testvar++; } ...

List of COM ports accessible with Serialport npm

I am encountering an issue with a specific part of my program and although I have identified the problem, I am unable to find a solution on my own. Therefore, I am reaching out for your assistance. It seems like the problem does not lie within the serialp ...

Retrieve data from TypeScript file (.ts) and use it in an HTML document

Recently I started learning Typescript and HTML as I work on building an Angular2 application. At the moment, I have a TypeScript file that resembles the following structure: import {Http, Headers} from 'angular2/http'; import {Component} from & ...

The newly released Firefox 70 seems to be having trouble loading most pages correctly, with many displaying a JavaScript error reading "NS_ERROR_FILE_NOT_FOUND"

Recently upgraded to the latest version of Firefox 70.0 and received the "Firefox is up to date" message with no issues. However, I am experiencing difficulties as around 70% of the web pages are not displaying properly. The browser only shows some parts ...

What is the best way to incorporate a function within a $.click (jquery) event that utilizes an id directly from the clicked element?

It seems that my title may not be very clear, but I have a jQuery code snippet that is causing some issues. The problem stems from the fact that when I click on an image with the class 'slideimg', I expect a function named slideDo to be executed, ...

The challenge of setting a property in a Struct (specifically in Nashorn, Kafka Connect transformer) resulting in a TypeError

I am currently using Kafka Connect version 6.1.1 and attempting to utilize Sergey34's kafka-connect-transformers library to modify my Kafka messages before sending them to BigQuery via the BigQuerySink. Within my connector.properties file, I have set ...

Tips on using Visual Studio Code to troubleshoot Angular 4 unit tests

I am working on an Angular 4 project with Material design in Visual Studio Code. The setup is done using angular/cli. Currently, I have been writing unit tests using Karma and Jasmine. However, when trying to debug the tests by setting breakpoints, it doe ...

Executing the npm run test command with the unsafe-perm flag within the lifecycle phase

My React/Redux app is working fine, but whenever I run the command below: npm run test An error occurs as shown below: 6 info lifecycle [email protected]~test: [email protected] 7 verbose lifecycle [email protected]~test: unsafe-perm in li ...