Last active
January 9, 2023 19:43
-
-
Save sabrina-zeidan/08b8ab1cc6a57be2fa895222d3fb5fe5 to your computer and use it in GitHub Desktop.
Serve WebP without plugin straight from the server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
upstream php { | |
{{#each fastcgi_servers}} | |
server {{this}}; | |
{{/each}} | |
} | |
# SZ START | |
# Check if client is capable of handling webp | |
map $http_accept $webp_suffix { | |
default ""; | |
"~*webp" ".webp"; | |
} | |
# SZ END | |
server { | |
listen {{port}}; | |
root "{{root}}"; | |
index index.php index.html index.htm; | |
# | |
# Generic restrictions for things like PHP files in uploads | |
# | |
include includes/restrictions.conf; | |
# | |
# Gzip rules | |
# | |
include includes/gzip.conf; | |
# | |
# WordPress Rules | |
# | |
# SZ START | |
# Serve WebP straight from the server. Not in the browsers as plugins do. Your WebPs should be already there. This is to SERVE WebP in compatible browsers, not create | |
# instead of png, jpg and jpeg formats | |
location ~* ^(/wp-content/.+)\.(png|jpe?g)$ { | |
set $base $1.$2; # Capture image path and file extension | |
set $webp_uri $base$webp_suffix; # URI of the WebP version (filename.jpeg.webp) | |
set $webp_old_uri $base.$2$webp_suffix; # "URI of the original file | |
set $root "C:\Users\Sabrina\Local Sites\start\app\public"; # path to the /wp-content from server | |
root $root; | |
add_header Vary Accept; | |
if ( !-f $root$webp_uri ) { # Check if WebP version exists | |
add_header WebP_404 $root$webp_uri; # if there is no WebP version -- just add a header WebP_404 with the value of the path where WebP file was requested from -- for debugging | |
} | |
try_files $webp_uri $webp_old_uri $uri =404; # redirect to WebP version if all is good | |
} | |
# Possible improvement: To compare size of the WebP version and original before serving WebP | |
# Mind that the benefit of WebP is not only the size, but also -- that browsers are able to decode this format quicker, so this makes sense only in case WebP version is significantly larger than original | |
# Better possible improvement: set up webp generation on server; check filesize after webp is created, compare to original, if significantly larger ( > 30-40%) -- delete WebP, create a file to indicate it was deleted for a reason and shouldn't be recreated again | |
# To generate WebP automatically on server it's convenient to use Lua for that (install through OpenResty releases https://github.com/openresty/lua-nginx-module#installation) | |
# How-to in detail #https://requestmetrics.com/web-performance/nginx-image-optimization | |
# Filesize with Lua https://gist.github.com/maugre/4d0da857ceaac48d4e0c | |
# SZ END | |
{{#unless site.multiSite}} | |
include includes/wordpress-single.conf; | |
{{else}} | |
include includes/wordpress-multi.conf; | |
{{/unless}} | |
# | |
# Forward 404's to WordPress | |
# | |
error_page 404 = @wperror; | |
location @wperror { | |
rewrite ^/(.*)$ /index.php?q=$1 last; | |
} | |
# | |
# Static file rules | |
# | |
location ~* \.(?:css|js)$ { | |
access_log off; | |
log_not_found off; | |
add_header Cache-Control "no-cache, public, must-revalidate, proxy-revalidate"; | |
} | |
location ~* \.(?:jpg|jpeg|gif|png|ico|xml)$ { | |
access_log off; | |
log_not_found off; | |
expires 5m; | |
add_header Cache-Control "public"; | |
} | |
location ~* \.(?:eot|woff|woff2|ttf|svg|otf) { | |
access_log off; | |
log_not_found off; | |
expires 5m; | |
add_header Cache-Control "public"; | |
# allow CORS requests | |
add_header Access-Control-Allow-Origin *; | |
} | |
# | |
# PHP-FPM | |
# | |
location ~ \.php$ { | |
try_files $uri =404; | |
fastcgi_split_path_info ^(.+\.php)(/.+)$; | |
fastcgi_param QUERY_STRING $query_string; | |
fastcgi_param REQUEST_METHOD $request_method; | |
fastcgi_param CONTENT_TYPE $content_type; | |
fastcgi_param CONTENT_LENGTH $content_length; | |
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | |
fastcgi_param SCRIPT_NAME $fastcgi_script_name; | |
fastcgi_param PATH_INFO $fastcgi_path_info; | |
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; | |
fastcgi_param REQUEST_URI $request_uri; | |
fastcgi_param DOCUMENT_URI $document_uri; | |
fastcgi_param DOCUMENT_ROOT $document_root; | |
fastcgi_param SERVER_PROTOCOL $server_protocol; | |
fastcgi_param GATEWAY_INTERFACE CGI/1.1; | |
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; | |
fastcgi_param REMOTE_ADDR $remote_addr; | |
fastcgi_param REMOTE_PORT $remote_port; | |
fastcgi_param SERVER_ADDR $server_addr; | |
fastcgi_param SERVER_PORT $server_port; | |
fastcgi_param SERVER_NAME $host; | |
fastcgi_param HTTPS $fastcgi_https; | |
fastcgi_param REDIRECT_STATUS 200; | |
fastcgi_index index.php; | |
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | |
fastcgi_pass php; | |
fastcgi_buffer_size 64k; | |
fastcgi_buffers 32 32k; | |
fastcgi_read_timeout 1200s; | |
proxy_buffer_size 64k; | |
proxy_buffers 32 32k; | |
proxy_busy_buffers_size 256k; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# In case hosting doesn't let you edit conf files or allows with very limited functionality. Well, that sucks. | |
# WPEngine allows clients to add a few bits of nginx conf, but not map directive (first bit of the code above where we check if client's browser supports WebP. | |
# So here is what can be done (this is how WebP Express does it, and anyone else can too): | |
# Contact their support and ask them to add the following lines to Before-In-Location field in their system for the specific site | |
# You might also ask them to remember to reloaded the server configuration and purge caches (I had to do so to get it work) | |
location ~* ^/wp-content/.*\.(png|jpe?g|svg)$ { | |
add_header Vary Accept; | |
expires 365d; | |
} | |
location ~* ^/wp-content/.*\.webp$ { | |
expires 365d; | |
if ($whattodo = AB) { | |
add_header Vary Accept; | |
} | |
} | |
if ($http_accept ~* "webp"){ | |
set $whattodo A; | |
} | |
if (-f $request_filename.webp) { | |
set $whattodo "${whattodo}B"; | |
} | |
if ($whattodo = AB) { | |
rewrite ^(.*) $1.webp last; | |
} | |
if ($whattodo = A) { # if there is no WebP version -- do what -- ideally, generate WebP on server side | |
} |
Author
sabrina-zeidan
commented
Jan 9, 2023
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment