-
Step 1 · Turn on HTTPS: issue the certificate and force the redirect
Free certificate + auto-renewal + a site-wide redirect
HTTPS is the default now, not a bonus: browsers flag pages as "not secure", and search engines prefer the https version.
If you run a hosting panel (least work): Site → SSL → Let's Encrypt → request → enable "force HTTPS". Free, 90-day validity, renewed for you by the panel.
Plain Nginx:
# Issue with acme.sh and renew from crontab curl https://get.acme.sh | sh acme.sh --issue -d yourdomain -w /www/wwwroot/yourdomainThree things to verify:
- Every asset loads over https (an
http://image or script gets blocked, and the console reports mixed content) - All http URLs redirect to https with a 301, not a 302
- Renewal is automated. Check it monthly with:
echo | openssl s_client -connect yourdomain:443 2>/dev/null | openssl x509 -noout -dates
Why an issuance fails, most often: the domain doesn't resolve to this machine, port 80 isn't open, or you've requested the same domain more than 5 times within 24 hours (wait until tomorrow).
Checklist
- HTTPS loads with no certificate warning
- http 301-redirects to https automatically
- Certificate renewal is automated
- Every asset loads over https (an
-
Step 2 · Add the CDN: acceleration domain + origin config
CNAME to the CDN, point the origin at your server, cache by directory first
A CDN caches your static files on edge nodes so visitors fetch from somewhere near them — faster, and it saves your origin's bandwidth.
Four configuration steps:
- Add an acceleration domain in the CDN console (e.g.
cdn.yourdomain), business type "static acceleration" - Origin config: origin address is your site's domain or IP; origin protocol https, since you already have a certificate
- DNS: CNAME
cdn.yourdomainto the domain the CDN gives you - Point the site's static asset paths at the CDN domain — change the
assets/prefix in your HTML, or substitute it globally in Nginx or your build step
One regional caveat: domains using mainland-China CDN nodes need an ICP filing. Without one you're limited to overseas nodes, and most of the speed advantage goes away with them.
Origin authentication: add a check at the origin (for example, only allow the CDN's origin IPs) so nobody bypasses the CDN and hits your server directly.
Verify it's live:
curl -I https://cdn.yourdomain/assets/css/style.css— look forX-Cache: HIT(or your vendor's hit header) and anAgeabove 0.Checklist
- curl shows a CDN cache-hit header
- Hitting the origin directly is refused or rate-limited
- All page assets load from the CDN domain
- Add an acceleration domain in the CDN console (e.g.
-
Step 3 · Cache rules: what to cache, for how long, and how to purge
Don't cache HTML; cache assets long, with versioned filenames
Wrong cache rules are worse than none: visitors see a three-day-old page and you never find out.
Rules worth copying:
| Resource | Cache time | Why |
|---|---|---|
|*.html| 0 (no cache) or 5 minutes | Content updates must go live immediately |
|/data/*.json| 1–5 minutes | Data files should refresh fairly quickly |
|assets/js/css| 7 days – 1 year | Safe once filenames are versioned |
| Images | 30 days | Rarely change |Long caching requires versioned filenames:
style.css?v=20260927orstyle.a1b2c3.css. Otherwise you ship new CSS and browsers keep using the old file.Purging (do this after every redesign):
- CDN console → cache purge → enter a URL or a directory (if directory purge is supported, purge
/assets/) - Purging has a quota — don't purge the whole site over a one-character change
- In an emergency, use prefetch / pre-warm to push new content onto the nodes
Debugging chant: a change didn't take effect → ① purge the CDN → ② check the
Ageresponse header (above 0 means you're still being served stale) → ③ hard-reload the browser (Ctrl+F5).Checklist
- HTML is not long-cached by the CDN
- Static asset filenames carry a version
- After a redesign you purged and verified it took effect
- CDN console → cache purge → enter a URL or a directory (if directory purge is supported, purge
-
Step 4 · Acceptance: speed, security headers, indexing unaffected
Compare before and after, and confirm crawlers still get through
Speed (only a before/after comparison means anything):
- Run PageSpeed Insights once and look at LCP and TTFB
- Ping from several regions, or use a multi-location speed test
- Target: TTFB under 200 ms on regional nodes, LCP under 2.5 s
Security headers (a few lines in Nginx):
add_header X-Content-Type-Options nosniff; add_header Referrer-Policy strict-origin-when-cross-origin; add_header X-Frame-Options SAMEORIGIN;Indexing must not regress — the easiest place to break things:
- Origin must be correct: the CDN has to pull current content, not serve a months-old snapshot
- Don't cache robots.txt and sitemap.xml for long (an hour or less), or crawlers get stale copies
- Don't block crawler user agents: some CDNs' "security protection" mistakes major crawlers for bots — add them to the CDN's UA allowlist
- Simulate a crawler with
curl -A 'Mozilla/5.0 (compatible; Baiduspider/2.0)' …and confirm a 200 with current content
Finish with a self-check: run
bash scripts/seo-check.shand confirm canonical, sitemap and HTTPS are all still intact.Cost: CDN traffic for a personal site is cheap (a few dollars a month), but traffic spikes and hotlink abuse are the real risk — set usage alerts.
Checklist
- TTFB and LCP improved versus before the CDN
- A simulated crawler request returns 200 with current content
- CDN usage alerts are enabled