3

New to Node.js I do understand that createReadStream() function is better for the performance than readFile(), because createReadStream() reads and writes data in chucks while readFile() first reads the whole content. Thus if the file is large, readFile() function might take longer before data can be processed futher. Thus I choose to create server using createReadStream() function as following.

    // Create a server with fs.createReadStream(), better performance and less memory usage.
    http.createServer( function (request, response) {
      // Parse the request containing file name
      var pathname = url.parse(request.url).pathname;

      // Create a readable stream.
      var readerStream = fs.createReadStream(pathname.substr(1));

      // Set the encoding to be UTF8.
      readerStream.setEncoding('UTF8');

      // Handle stream events --> data, end and error
      readerStream.on('data', function(chunk) {
        // Page found
        // HTTP Status: 200 : OK
        // Content Type: text/plain
        response.writeHead(200, {'Content-type': 'text/html'});

        // Write the content of the file to response body.
        response.write(chunk);

        console.log('Page is being streamed...');
      });

      readerStream.on('end', function() {
        console.log('Page is streamed and emitted successfully.');
      });

      readerStream.on('error', function(err) {
        // HTTP Status: 404 : NOT FOUND
        // Content Type: text/plain
        response.writeHead(404, {'Content-type': 'text/html'});

        console.log('Page streaming error: ' + err);
      });

      console.log('Code ends!');

    }).listen(8081);

    // Console will print the message
    console.log('Server running at http://127.0.0.1:8081/');

My .html or .txt file contains three short lines of text. After starting my server I visit my web page by going to http://127.0.0.1:8081/index.html. Everything works fine and the content of index.html is echoed on the browser.

But on the tab of the browser, the loader icon keeps turning like it keeps loading for about 1 minute.

Is that normal with Node.js server? Does the icon just keep turning, but costs nothing to the server? Or do I miss something and icon is not supposed to keep turning?

Zach
  • 539
  • 1
  • 4
  • 22
O Connor
  • 4,236
  • 15
  • 50
  • 91

1 Answers1

3

It doesn't look like you are ending your response. The browser probably thinks the request isn't finished and thus continues to "load".

If you look at the Network tab in the developer console you might see the request hasn't finished.

You should be sending response.end()

This method signals to the server that all of the response headers and body have been sent; that server should consider this message complete. The method, response.end(), MUST be called on each response.

I believe you should be calling response.end() in both the readerStream.on('end' and readerStream.on('error' callbacks after you write the head. This will tell the browser the request is finished and it can stop the loading action.

Andrew Lohr
  • 5,380
  • 1
  • 26
  • 38
  • Thanks! it is the solution! I do call response.end() in three callbacks readerStream.on('data'), readerStream.on('end') and readerStream.on('error'). – O Connor Oct 05 '18 at 15:15