How to Minify HTML Output in Nginx for Faster Page Loads


2 views

Minifying HTML removes unnecessary whitespace, comments, and redundant tags, reducing file size and improving load times. While tools like Gulp or Webpack handle this during build time, on-the-fly minification is useful for dynamic content or legacy systems.

Nginx's built-in ngx_http_sub_module can perform simple minification:


server {
    listen 80;
    server_name example.com;
    
    # Enable sub_filter
    sub_filter_once off;
    sub_filter_types text/html;
    sub_filter '\n' '';
    sub_filter '\r' '';
    sub_filter '\t' '';
    sub_filter '  ' ' ';
    
    location / {
        proxy_pass http://backend;
    }
}

This removes line breaks, tabs, and reduces double spaces. However, it's basic and won't handle complex cases.

For better results, use Nginx with Lua (requires ngx_http_lua_module):


server {
    listen 80;
    server_name example.com;
    
    location / {
        proxy_pass http://backend;
        header_filter_by_lua_block {
            local res = ngx.arg[1]
            if string.find(res, "text/html") then
                ngx.arg[1] = string.gsub(res, ">%s+<", "><")
                ngx.arg[1] = string.gsub(ngx.arg[1], "%s+", " ")
            end
        }
    }
}

Compile Nginx with this module for comprehensive minification:


./configure --add-module=/path/to/ngx_http_minify_module
make && make install

Configuration example:


http {
    minify on;
    minify_types text/html;
}

Benchmark different approaches:

  • Basic sub_filter: ~5% size reduction
  • Lua solution: ~10-15% reduction
  • ngx_http_minify_module: 15-25% reduction

Remember to test with actual traffic - the CPU overhead might outweigh benefits for high-traffic sites.

For static sites, consider generating minified versions during deployment:


find /var/www -name '*.html' -exec minify --html {} -o {} \;

Combine with Nginx's try_files for zero-runtime overhead.


Minifying HTML output can significantly reduce page size and improve load times. While most focus on minifying CSS/JS, HTML minification is often overlooked despite being crucial for performance-critical applications. Nginx doesn't include built-in HTML minification, but we can implement it efficiently.

Nginx's sub_filter module can handle basic minification:

http {
    server {
        location / {
            proxy_pass http://backend;
            sub_filter '\n' '';
            sub_filter '\t' '';
            sub_filter '  ' ' ';
            sub_filter_once off;
            sub_filter_types text/html;
        }
    }
}

For more comprehensive minification, use OpenResty (Nginx + Lua):

location / {
    proxy_pass http://backend;
    header_filter_by_lua_block {
        local res = ngx.location.capture("/minify", {
            method = ngx.HTTP_POST,
            body = ngx.arg[1]
        })
        ngx.arg[1] = res.body
    }
}

location = /minify {
    internal;
    content_by_lua_block {
        local html = ngx.req.get_body_data()
        -- Remove comments
        html = html:gsub('<!--.-?-->', '')
        -- Collapse whitespace
        html = html:gsub('%s+', ' ')
        html = html:gsub('%s*(%S)='', '%1='')
        ngx.print(html)
    }
}

The ngx_http_minify_module provides comprehensive minification:

./configure --add-module=/path/to/ngx_http_minify_module
make && make install

Then in nginx.conf:

location / {
    minify on;
    minify_types text/html;
    proxy_pass http://backend;
}

When implementing on-the-fly minification:

  • Enable gzip compression (compression works better on minified content)
  • Consider caching minified output
  • Benchmark CPU impact for high-traffic sites

If managing this seems complex, many CDNs offer automatic minification:

# Cloudflare example
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/ZONE_ID/settings/minify" \
-H "Authorization: Bearer API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"value":{"html":"on"}}'