Stay Hungry. Stay Foolish.

最近博客平台从原来的 Typecho 切换到了 Ghost 上,相比于 PHP 写的 Typecho,Nodejs 写成的 Ghost 在速度上要快不少,但是有的时候给人的感觉是还不够快,下面就介绍一点点配置优化的地方。

静态文件使用 Nginx 直接服务

Ghost 默认将所有静态文件由 Nodejs Server 提供,相对效率来说不如 Nginx,于是我们使用 Nginx 来处理静态文件。

  • 站点配置文件中添加:
location ^~ /content/images/ {
    root /var/www/ghost;
    access_log off;
    log_not_found off;
    expires max;
}
location ^~ /assets/ {
# 这边的 root 填写主题的绝对目录
    root /var/www/ghost/content/themes/dcc;
    access_log off;
    log_not_found off;
    expires max;
}

Nginx proxy cache 缓存

  • nginx.conf 中添加如下 cache 配置
proxy_cache_path /var/www/ghostcache levels=1:2 keys_zone=ghostcache:60m max_size=300m inactive=24h;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_methods GET HEAD;
  • 站点配置文件中添加:
location ^~ /ghost/ {
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_pass http://localhost:2368;
    add_header Cache-Control "no-cache, private, no-store, must-revalidate";
}
location / {
    proxy_cache ghostcache;
    proxy_cache_valid 60m;
    proxy_cache_valid 404 1m;
    proxy_cache_bypass $http_cache_control;
    proxy_ignore_headers Set-Cookie;
    proxy_hide_header Set-Cookie;
    proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
    proxy_ignore_headers Cache-Control;
    add_header X-Cache-Status $upstream_cache_status;
    proxy_hide_header X-powered-by;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://localhost:2368;
    expires 10m;
}

优化 Ghost 配置

  • 给出我的部分配置
{
    "url": "https://www.example.com",
    "server": { ... },
    "database": { ... },
    "mail": { ... },
    "useMinFiles": true,
    "process": "systemd",
    "paths": {
        "contentPath": "/var/www/ghost/content"
    },
    "bootstrap-socket": {
        "port": 8000,
        "host": "localhost"
    },
    "storage": {
        "active": "LocalFileStorage"
    },
        "scheduling": {
        "active": "SchedulingDefault"
    },
    "logging": {
        "level": "error",
        "rotation": {
            "enabled": true,
            "period": "1d",
            "count": 15
        },
        "transports": [
            "file",
            "stdout"
        ]
    },
    "privacy": {
        "useGravatar": false
    },
    "bootstrap-socket": {
        "port": 8000,
        "host": "localhost"
    },
    "spam": {
        "user_login": {
            "minWait": 600000,
            "maxWait": 604800000,
            "freeRetries": 4
        },
        "user_reset": {
            "minWait": 3600000,
            "maxWait": 3600000,
            "lifetime": 3600,
            "freeRetries": 4
        },
        "global_reset": {
            "minWait": 3600000,
            "maxWait": 3600000,
            "lifetime": 3600,
            "freeRetries": 4
        },
        "global_block": {
            "minWait": 3600000,
            "maxWait": 3600000,
            "lifetime": 3600,
            "freeRetries": 99
        },
        "private_block": {
            "minWait": 3600000,
            "maxWait": 3600000,
            "lifetime": 3600,
            "freeRetries": 99
        }
    },
    "caching": {
        "frontend": {
            "maxAge": 0
        },
        "301": {
            "maxAge": 31536000
        },
        "customRedirects": {
            "maxAge": 31536000
        },
        "favicon": {
            "maxAge": 86400
        },
        "sitemap": {
            "maxAge": 3600
        },
        "robotstxt": {
            "maxAge": 3600000
        }
    },
    "imageOptimization": {
        "resize": false
    },
    "compress": true
}
  • 重点介绍一下 qn-store 插件的使用

默认情况下 Ghost 会把用户上传的图片都存储在本机,实际上如果没有全站 cdn 的话,图片的加载会拖慢博客的速度,那么我们选择把图片传到七牛云

cd /var/www/ghost && ghost stop && sudo mkdir -p content/adapters/storage && cd content/adapters/storage
sudo git clone https://github.com/Minwe/qn-store.git && cd qn-store && sudo yarn
sudo find /var/www/ghost -type d -exec chmod 755 {} \;
sudo find /var/www/ghost -type f -exec chmod 664 {} \;
ghost setup linux-user systemd

在配置文件 config.production.json 中修改配置如下,然后执行 ghost start

    "storage": {
        "active": "qn-store",
        "qn-store": {
            "accessKey": "",
            "secretKey": "",
            "bucket": "",
            "origin": "",
            "uploadURL": "http://up.qiniup.com",
            "fileKey": {
                "hashAsBasename": false,
                "safeString": true,
                "prefix": "YYYY/MM/",
                "suffix": "",
                "extname": true
            }
        }
    },

其中 accessKeysecretKey 在七牛面板密钥管理处获得,bucket 即为存储空间名称,origin 为为空间外链域名,uploadURL 可在存储区域文档中找到

Pagespeed

pagespeed 安装

Pagespeed 是 Google 推出的一款用于加快网站加载速度的插件,Pagespeed 可以自动优化网页和关联资源(CSS,JavaScript,图片),缩短网页的加载时间,而无需修改现有内容或工作流程,实现加快网站的的速度。

主要特性:
图像优化:剥离元数据、动态调整,重新压缩 CSS 和 JavaScript 压缩、合并、级联、内联小资源内联;推迟图像和 JavaScript 加载;对 HTML 重写、压缩空格、去除注释等;提升缓存周期等等......

Pagespeed 有 Nginx 和 Apache 两个版本,我们安装 Nginx 版:

git clone https://github.com/apache/incubator-pagespeed-ngx.git pagespeed && cd pagespeed
wget -c https://dl.google.com/dl/page-speed/psol/1.13.35.2-x64.tar.gz && tar -zxf 1.13.35.2-x64.tar.gz && rm 1.13.35.2-x64.tar.gz

编译 nginx 时添加 --add-module=../pagespeed 即可。

pagespeed 配置

  • 在 nginx http 配置中引入 pagespeedadmin.conf
pagespeed UsePerVhostStatistics on;

pagespeed FileCachePath /var/www/ngx_pagespeed_cache;
pagespeed StatisticsPath /ngx_pagespeed_statistics;
pagespeed GlobalStatisticsPath /ngx_pagespeed_global_statistics;
pagespeed MessagesPath /ngx_pagespeed_message;
pagespeed ConsolePath /pagespeed_console;
pagespeed AdminPath /pagespeed_admin;
pagespeed GlobalAdminPath /pagespeed_global_admin;

pagespeed MessageBufferSize 100000;

pagespeed NumRewriteThreads 4;
pagespeed NumExpensiveRewriteThreads 4;

pagespeed ImageMaxRewritesAtOnce 2;
  • vhost 配置中引入 pagespeed.conf
pagespeed on;
pagespeed EnableCachePurge on;
pagespeed PurgeMethod PURGE;

pagespeed FileCacheSizeKb          102400;
pagespeed FileCacheCleanIntervalMs 3600000;
pagespeed FileCacheInodeLimit      500000;

pagespeed RespectVary on;
pagespeed LowercaseHtmlNames on;
pagespeed XHeaderValue "DCC";
pagespeed Disallow "*/ghost/*";

pagespeed JpegQualityForSaveData 50;
pagespeed WebpQualityForSaveData 50;
pagespeed EnableFilters resize_rendered_image_dimensions;
pagespeed WebpRecompressionQuality 75;

pagespeed PreserveUrlRelativity on;
pagespeed ImageResolutionLimitBytes 16777216;

pagespeed AvoidRenamingIntrospectiveJavascript on;
pagespeed ImageInlineMaxBytes 3072;
pagespeed CssImageInlineMaxBytes 0;
pagespeed MaxInlinedPreviewImagesIndex -1;
pagespeed MinImageSizeLowResolutionBytes 3072;
 
pagespeed RewriteLevel CoreFilters;
pagespeed EnableFilters collapse_whitespace,remove_comments; 

# pagespeed ForbidAllDisabledFilters true;

pagespeed EnableFilters elide_attributes;

pagespeed EnableFilters dedup_inlined_images;

# pagespeed EnableFilters make_google_analytics_async;
# pagespeed EnableFilters make_show_ads_async;

pagespeed EnableFilters responsive_images,resize_images;
pagespeed EnableFilters responsive_images_zoom;

pagespeed EnableFilters inline_google_font_css;

pagespeed FetchHttps enable;
pagespeed SslCertDirectory /etc/ssl/certs;

pagespeed EnableFilters inline_css;
pagespeed CssInlineMaxBytes 1024;

pagespeed EnableFilters move_css_to_head;
pagespeed EnableFilters move_css_above_scripts;

pagespeed EnableFilters combine_css;
pagespeed MaxCombinedCssBytes -1;

pagespeed CombineAcrossPaths off;

pagespeed EnableFilters combine_javascript;
pagespeed MaxCombinedJsBytes 122900;

pagespeed EnableFilters extend_cache;

pagespeed EnableFilters rewrite_css;
pagespeed EnableFilters rewrite_javascript;
pagespeed EnableFilters rewrite_javascript_external;

pagespeed DisableFilters inline_images;
pagespeed DisableFilters lazyload_images;
pagespeed DisableFilters inline_preview_images;
pagespeed DisableFilters prioritize_critical_css;
pagespeed CriticalImagesBeaconEnabled false;
# pagespeed FinderPropertiesCacheExpirationTimeMs 7200000; 

pagespeed EnableFilters rewrite_images;
pagespeed EnableFilters recompress_images;
pagespeed EnableFilters convert_png_to_jpeg;
pagespeed EnableFilters convert_jpeg_to_webp;
pagespeed DisableFilters convert_to_webp_animated;
pagespeed EnableFilters convert_to_webp_lossless;
pagespeed EnableFilters resize_mobile_images;

pagespeed EnableFilters rewrite_css,sprite_images;

pagespeed EnableFilters insert_dns_prefetch;

pagespeed InPlaceResourceOptimization on;

location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" { add_header "" ""; }
location ~ "^/pagespeed_static/" { }
location ~ "^/ngx_pagespeed_beacon$" { }
location /ngx_pagespeed_statistics { allow 127.0.0.1; allow 103.107.106.74; deny all; }
location /ngx_pagespeed_global_statistics { allow 127.0.0.1; allow 103.107.106.74; deny all; }
location /ngx_pagespeed_message { allow 127.0.0.1; allow 103.107.106.74; deny all; }
location /pagespeed_console { allow 127.0.0.1; allow 103.107.106.74; deny all; }
location ~ ^/pagespeed_admin { allow 127.0.0.1; allow 103.107.106.74; deny all; }
location ~ ^/pagespeed_global_admin { allow 127.0.0.1; allow 103.107.106.74; deny all; }

pagespeed Statistics on;
pagespeed StatisticsLogging on;
pagespeed LogDir /var/log/pagespeed;