简体   繁体   中英

Slow loading web page served by Node.js HTTP server

I'm trying to create an HTTP server using Node.js where I can stream video files using video.js player. But it's taking a long time loading the web page.

I've tried to encode HTML codes Javascript files and CSS files using gzip, but it didn't improve the loading speed.

Here is my code:

const http = require('http');
const fs = require('fs');
const url = require('url');
const path = require('path');
const zlib = require('zlib');
const mime = require('mime');

http.createServer((req, res) => {
    let uri = url.parse(req.url).pathname;
    // Serve index page for root path
    if (uri !== '/') {
        let filename = path.join("./", uri);
        fs.exists(filename, exists => {
            if (!exists) {
                res.writeHead(404);
                res.end();
            } else {
                let stat = fs.statSync(filename);
                let headers = {
                    'Accept-Ranges': 'bytes',
                    'Content-Type' = mime.getType(filename),
                    'Content-Length': stat.size,
                    'Vary': 'Accept-Encoding'
                };
                // Handle `Accept-Ranges` header
                let range = req.headers.range;
                let stream;
                if (range) {
                    let parts = range.replace(/bytes=/, '').split('-');
                    let start = parseInt(parts[0]);
                    let end = parts[1] ? parseInt(parts[1]) : stat.size - 1;
                    let chunk_size = end - start + 1;
                    stream = fs.createReadStream(filename, {start, end});
                    headers['Content-Length'] = chunk_size;
                    headers['Content-Range'] = `bytes ${start}-${end}/${stat.size}`;
                } else {
                    stream = fs.createReadStream(filename);
                }
                stream.on('error', err => {
                    res.writeHead(500);
                    res.end();
                });

                // gzip encode javascript and css files.
                if (/\.(js)|(css)$/.test(filename.toLowerCase())) {
                    let gzip = zlib.createGzip();
                    gzip.on('error', err => {
                        throw err;
                    });
                    headers['Content-Encoding'] = 'gzip';
                    res.writeHead(200, headers);
                    stream.pipe(gzip).pipe(res);
                } else {
                    if (range) {
                        res.writeHead(206, headers);
                    } else {
                        res.writeHead(200, headers);
                    }
                    stream.pipe(res);
                }
            }
        });
    } else {
        let page = `<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Video</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, minimum-scale=1.0">
        <link rel="shortcut icon" href="favicon.ico">
        <link rel="stylesheet" type="text/css" href="assets/css/video-js.min.css">
        <script src="assets/js/video.min.js"></script>
    </head>
    <body>
        <div id="video_area">
            <video id="video" class="video-js vjs-big-play-centered">
                <source src="video.mkv" type="video/webm"/>
                <track kind="subtitles" lang="en" src="en.vtt" default/>
            </video>
        </div>
        <script>
            window.player = videojs('video', {
                controls: true,
                autoplay: false,
                preload: 'auto',
                fluid: true,
                playbackRates: [0.5, 1, 1.5, 2]
            });
        </script>
    </body>
</html>`;
        let headers = {
            'Accept-Ranges': 'bytes',
            'Content-Encoding': 'gzip',
            'Content-Length': Buffer.byteLength(page),
            'Content-Type': 'text/html'
        };
        res.writeHead(200, headers);
        zlib.gzip(page, (err, data) => {
            if (err) {
                log.e(err);
                throw err;
            }
            res.end(data);
        });
    }
}).listen(80);

This is a screenshot I captured from my Google Chrome's DevTools.

屏幕截图

First of all make sure the video autoplay is set to false and preload="none"

In your code add async

http.createServer(async(req, res) 

now put html in a function and in your else block execute that function with await

else{
    await htmlFunction()
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM