Optimizing Nginx Configuration: Modern MIME Types and Gzip Compression Best Practices


3 views

Nginx's default mime.types file hasn't kept pace with modern web standards. While it includes legacy types like application/x-javascript, it's missing current standards such as:

# Missing modern MIME types
application/javascript
application/json
application/manifest+json
application/wasm

To modernize your Nginx setup, create a custom mime.types file in your Nginx config directory:

# /etc/nginx/conf/mime.types
types {
    # Override legacy JS type
    application/javascript    js mjs;
    
    # JSON and related types
    application/json          json;
    application/manifest+json webmanifest;
    
    # WebAssembly support
    application/wasm          wasm;
    
    # Keep existing types
    include /etc/nginx/mime.types;
}

The optimal gzip configuration should cover these modern content types:

gzip_types
    text/plain
    text/css
    text/xml
    text/javascript
    application/javascript
    application/json
    application/xml
    application/rss+xml
    application/atom+xml
    application/manifest+json
    image/svg+xml;

Here's a production-ready HTTP block configuration:

http {
    include /etc/nginx/conf/mime.types;
    default_type application/octet-stream;
    
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/javascript
        application/json
        application/xml
        application/rss+xml
        application/atom+xml
        application/manifest+json
        image/svg+xml;
    
    gzip_min_length 256;
    gzip_disable "msie6";
    
    # Additional performance tweaks
    sendfile on;
    tcp_nopush on;
    keepalive_timeout 65;
}

For legacy browser support (mainly IE 8-10), you might need to include fallbacks:

map $http_accept $js_mime_type {
    default         application/javascript;
    "~*application/x-javascript" application/x-javascript;
}

Verify your configuration with:

nginx -t
curl -I -H "Accept-Encoding: gzip" http://yoursite.com/main.js

Check for these response headers:

Content-Type: application/javascript
Content-Encoding: gzip

Nginx's default mime.types file serves as a foundation for proper content-type headers, but it contains some outdated entries that need updating for modern web development. The most notable examples are JavaScript and JSON files still using legacy types:

# Default (outdated) mapping
application/x-javascript              js;

# Modern standards should use:
application/javascript                js;
application/json                      json;

To implement modern standards while maintaining backward compatibility, create a custom mime.types file or modify the existing one:

types {
    # Updated JavaScript and JSON types
    application/javascript            js;
    application/json                  json;
    
    # Keep all other default types
    include /etc/nginx/mime.types;
}

Modern web applications benefit from compressing more than just traditional text files. Here's an optimized gzip_types configuration:

gzip_types text/plain text/css text/xml 
           application/javascript application/json 
           application/xml application/xhtml+xml 
           application/rss+xml application/atom+xml 
           image/svg+xml;

When configuring gzip compression, consider these factors:

  • Text-based formats compress best (typically 60-80% reduction)
  • Already compressed formats (JPEG, PNG, etc.) shouldn't be gzipped
  • Modern browsers support brotli compression (consider adding brotli_types)

Here's a production-ready configuration snippet combining these optimizations:

http {
    # Custom MIME types with modern standards
    types {
        application/javascript    js;
        application/json          json;
        include /etc/nginx/mime.types;
    }
    
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types text/plain text/css text/xml application/javascript 
               application/json application/xml application/xhtml+xml 
               application/rss+xml application/atom+xml image/svg+xml;
    gzip_min_length 256;
    gzip_disable "msie6";
    
    # Brotli compression if available
    brotli on;
    brotli_types text/plain text/css text/xml application/javascript 
                 application/json application/xml application/xhtml+xml 
                 application/rss+xml application/atom+xml image/svg+xml;
}

After making changes, verify your MIME types and compression:

# Test configuration
nginx -t

# Check response headers
curl -I https://yoursite.com/script.js | grep -i "content-type\|content-encoding"