惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
Microsoft Security Blog
Microsoft Security Blog
B
Blog
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
爱范儿
爱范儿
博客园_首页
博客园 - 聂微东
量子位
V
Visual Studio Blog
aimingoo的专栏
aimingoo的专栏
T
The Blog of Author Tim Ferriss
J
Java Code Geeks
小众软件
小众软件
大猫的无限游戏
大猫的无限游戏
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
Netflix TechBlog - Medium
F
Fortinet All Blogs
The Cloudflare Blog
T
Tailwind CSS Blog
G
Google Developers Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
月光博客
月光博客
腾讯CDC

Cloudflare

爱上 cloudflare 了 我想问问现在 Cloudflare 能不能正常登陆? cfui:基于 go 的 cloudflared web UI 为了在 CF 上实现低延迟的效果,打开页面后每半分钟发送一个请求对赛博菩萨有多大伤害?我不想遭报应 Cloudflare 的 5 秒盾/Turnstile 真的无敌吗? CapSolver 这类 api 到底靠不靠谱? https://dash.cloudflare.com 登录不进去 Cloudflare 宣布裁员逾 1100 人 这两天大家能正常登录 cf 吗? cloudflare tunnel 会阻止 openai sdk 的请求,只允许 curl 请求,如何解决 Cloudflare WARP 现在还稳吗 cloudflare worker 懂行的 开启 Cloudflare 的 DNS 代理之后, frp 就无法正常工作 cloudflare worker 能指定出口 ip 的国家吗? Cloudflare 支持使用自定义域名发邮件了 [送码]做了个 Cloudflare 监控 App - FlareKit,送点兑换码 转移到 Cloudflare Registrar 的域名疑似被盗 为什么已经把 cloudflare 上的 Cache Rules 设置为绕过缓存,还是会被限制上传大小? vibe 了一个 gotify/server 的 cloudflare worker 版本 求助: cf 上面的域名被封了 被 CF 拦截了部分页面, Error 451 错误 CF 的 ai 反爬 robots.txt 似乎部分情况下跟 Pages 机制冲突? Cloudflare 收购了 Astro 最近发现 CF WARP 在 Win & Linux 上国内能直连,安卓不行 Cloudflare Radar《2025 年度回顾》,挺有意思 白嫖 worker AI 的进 刚注册的新域名放到了 cloudflare 一周后发现访问量逐渐增加,是爬虫吗 历时 20 多天, Cloudflare 弄丢的数据找回来了 cloudflare worker 直连访问太慢了,求个替代 难道没人觉得 cloudflare 改版后,很难用吗? Cloudflare 发表 12/5 的故障报告
一套能让免费 CloudFlare 建的站部分访问延迟变低(几乎瞬间...
shendaowu · 2026-06-03 · via Cloudflare

效果

  • 我让 AI 写的简单页面 LCP 100 ms 左右。首个请求完成也就二三十毫秒。

缺陷

  • 首次访问别想了,该卡还是卡。
  • 部分解决 Edge 上的一个导致延迟大的问题比较复杂。解决方法在后面。
  • 只对可预测性比较强的网站效果更好。可预测性不强的网站想要快代价很可能比较大,具体方法在后面。
  • 如果网站更新了,用户刷新两次才能获得最新内容。

代价

  • 比较复杂。
  • 网站有一定概率会彻底崩,而且比较难恢复。
  • 可能会消耗更多的流量。

主要技术

  • Service Worker
  • SWR

方法

简单说就是用 service worker 实现一个 SWR 缓存策略。

真传一句话,下面假传万卷书。

service worker 我理解就是一个运行在浏览器的类似代理的东西,可以任意修改特定网站所有的请求的响应。SWR 我理解就是如果没缓存,就先访问服务器获取内容,然后返回响应;如果有缓存,就直接返回缓存,然后再访问服务器更新缓存。这段我写的时候没有参考任何资料,都是凭记忆写的。在意的话自己搜搜。

虽然看起来挺简单的,但实际实现的时候还是会遇到一些比较恶心的问题。比如如果 service worker 安装过程比较耗时的话,可能导致一些页面无法缓存,最好是在 service worker 的激活事件里显式缓存一下。否则可能导致第三次访问的时候才能快速打开。

缺陷详解

我相信在这种条件下让首次访问也快是不可能的。不过我也没啥根据,基本就是直觉,我倒是希望首次也快。可能不同的网站互相缓存可以部分提升。不过 service worker 是不能跨域的,用 service worker 应该是不行。

在 edge 上就算使用了缓存,五分钟以上不访问之后再次访问还是偶尔会出现一两秒的延迟。解决方法是在所有页面中添加一个隐藏的框架,框架的内容就是网站内的一个页面,比如说 /keepalive ,然后每隔一段时间刷新这个框架的内容。这样如果页面开着的话,基本就不会出现卡顿的情况了。我测试半分钟效果不错。另外在 service worker 中添加一点代码,如果请求的 pathname 部分是 /keepalive ,就直接用代码返回响应,不要经过服务器。我试过了,效果一样。我基本可以确定这种刷新不会导致太多的服务器请求。DNS 请求应该是免不了了,我在 CF 的 DNS 请求页面看了,不访问的时候基本没有 DNS 请求,持续刷新的过程中五分钟十次请求。据说那个十次是假的,不知道真假。如果在 service worker 中直接返回响应的话,理论上应该是不会有 web 服务器流量的。但是由于 cloudflare 好像是没有监控静态页面流量的功能,所以我就不管了。Wireshark 我不太会用,不想学。谁要是能帮我分析一下我谢谢你。我问过微软的客服的,看起来微软没有解决这个问题的意思,微软客服大概说 chrome 用了缓存能瞬间打开是链接复用之类的机制比较激进,edge 没那么激进。我有点怀疑 edge 就是没优先用缓存的 dns 映射(这个词可能不准确),chrome 可能直接用缓存的 dns 记录了。就说是 chrome 可能对 dns 映射用的是 SWR 策略。

我想做的是一个类似解谜游戏的网站,实际不是游戏,具体我不想说。我预测大部分用户都会一关一关访问,所以在首页预载第一关,在第一关预载第二关,以此类推效果应该非常不错。这部分代码里没有。我之前试过,但是没有跟解决 edge 问题的代码一起测试,我估计是没什么问题。如果用户访问行为不好预测的话,并且网站页面不多的话,直接暴力预载所有内容可能也不错。网站内容多的话可能就不行了。预载访问量排前几个的?

如果更新了需要刷新两次才能看到最新内容是 SWR 策略决定的。我试过让 AI 实现检测到更新在页面上显示一个通知,但实际搞下来我感觉太复杂了,放弃了。你要是有勇气可以试试。

代价详解

复杂就不多解释了,前面那么多字应该有点体现了。而且我可能还没有把所有坑都踩遍。

service worker 出问题很危险,可能会导致全站无法访问。而且有一些坑。比如如果 service worker 的脚本浏览器缓存时间比较长的话,用户的浏览器可能无法及时更新。解决方法挺复杂。我建议能跑就尽量别改 service worker 的代码。如果有新的需要改 service worker 的需求,如果价值不大就别实现了,保命要紧。反正我就打算这么干了。

cloudflare 一般情况下好像不会给出完整的响应,而是通过对比一个请求头判断浏览器缓存是否过时了,过时了才发完整的请求。我不知道 SWR 会不会利用这个机制。

弯路

刚开始我是想通过浏览器缓存很长时间的 HTML 加动态加载各个页面对应的 js 文件动态修改页面内容来实现的,后来好像被 AI 提醒 service worker 更好就用了后者。

临时 Demo

https://sdwpub.cc.cd/

过一段时间很可能会失效。

在 edge 上测试方法就是开着首页,再打开 https://sdwpub.cc.cd/test 再关闭,缓存这个页面。然后过一段时间访问 https://sdwpub.cc.cd/test 。我测了很多次都没卡顿。如果不开着首页过五分钟就有可能卡顿。chrome 的话,打开一次首页之后再访问首页就不卡顿了。

代码

index.html:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Edge 卡顿缓解</title>
</head>
<body>
  <!-- 正常页面内容 -->

  <span>测试。</span>

  <!-- 不可见框架,用于保持页面活跃 -->
  <iframe id="keepAliveFrame" src="keepalive" style="display:none;"></iframe>

  <script>
    // 每半分钟刷新一次不可见框架
    setInterval(function() {
      var frame = document.getElementById('keepAliveFrame');
      if (frame) {
        frame.src = 'keepalive?t=' + Date.now();
      }
    }, 30000);

    // 注册 Service Worker
    if ('serviceWorker' in navigator) {
      window.addEventListener('load', function() {
        navigator.serviceWorker.register('/sw.js').catch(function(err) {
          console.error('SW 注册失败:', err);
        });
      });
    }
  </script>
</body>
</html>

sw.js:

// == sw.js ==
// Service Worker:全站 GET 请求 SWR 缓存 + 预缓存首页

const CACHE_NAME = 'swr-cache-v1';

// 安装时预缓存首页
self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(CACHE_NAME).then(cache => cache.add('/').catch(() => {}))
  );
  self.skipWaiting(); // 立即激活,不等待旧 SW
});

// 激活时接管所有客户端
self.addEventListener('activate', event => {
  event.waitUntil(self.clients.claim());
});

// SWR 策略:拦截所有同源 GET 请求
self.addEventListener('fetch', event => {
  const { request } = event;
  if (request.method !== 'GET') return;

  const url_tmp = new URL(event.request.url);
  
  // 判断 pathname 是否为 /keepalive
  if (url_tmp.pathname === '/keepalive') {
    // 直接返回 "test" 四个字符作为响应
    event.respondWith(
      new Response('test', {
        status: 200,
        headers: { 'Content-Type': 'text/plain' }
      })
    );
    return; // 已处理,不再继续
  }

  // 仅处理同源请求,避免跨域 opaque 响应的复杂性
  const url = new URL(request.url);
  if (url.origin !== self.location.origin) return;

  event.respondWith(
    caches.open(CACHE_NAME).then(cache =>
      cache.match(request).then(cached => {
        // 后台网络请求,用于更新缓存
        const networkFetch = fetch(request).then(response => {
          if (response && response.status === 200) {
            cache.put(request, response.clone());
          }
          return response;
        }).catch(() => {});

        if (cached) {
          // 命中缓存:立即返回,同时后台更新
          event.waitUntil(networkFetch);
          return cached;
        }
        // 未命中:等待网络响应
        return networkFetch;
      })
    )
  );
});