How to Minify HTML Output in Nginx for Faster Page Loads


10 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"}}'