标签: network

  • 使用 WebP/AVIF 压缩博文图片

    使用 WebP/AVIF 压缩博文图片

    往文章中贴截图的时候,如果使用压缩率较低的图片格式(jpeg/png),长时间的图片下载耗时会降低用户的阅读体验。

    根据 CanIUse 的统计,目前绝大多数的网上冲浪用户使用的浏览器已经支持了 WebP/AVIF 这类高效的图片格式。

    https://caniuse.com/avif Can I use AVIF?
    https://caniuse.com/webp Can I use WebP?

    以文章开头的那张图片为例,原图大概 108KB,转换成 AVIF 格式并压缩后,体积缩小了接近 90% 。

    如果想要给 WordPress 启用自动转换的功能,我推荐使用下面的免费插件,只要你的 PHP 支持 imagick/GD 插件,就可以使用。

    https://wordpress.org/plugins/performance-lab/

    安装完成后需要在管理面板中启用 Mordern ImageFormats 功能。

    如果需要把已有的图片都转换成 WebP/AVIF,可以使用下面的插件批量转换。

    https://wordpress.org/plugins/compressx/

    安装完成后就可以在后台管理页面批量转换格式或者单独地转换格式。

    一些疑问

    如果用户的浏览器不支持 WebP/AVIF 该怎么办?

    AVIF 在比较新的浏览器中普及率很高 只有现代 IE —— Safari 不支持,WebP 的兼容性也非常好,不过万一有人用史前时代的浏览器上网呢?

    其实这个问题完全不用担心,上面介绍的插件在生成 WebP/AVIF 格式后并不会删除原图,浏览器会跟 WordPress 协商应该使用何种格式的图片向用户展示。

    怎么确认我正在使用 WebP/AVIF 版本的图片?

    仅仅依靠文件名无法区分图片格式,应该检查浏览器请求的响应部分,如果 Content-Type 的值为 image/avif 说明这张图片正在以 AVIF 格式展示,WebP 也是同理。

    为什么图片看起来有些糊?

    CompressX 插件默认使用有损压缩,建议手动调整为无损压缩选项。

    为什么转换格式这么慢?

    转换速度完全取决于你的服务器配置,简而言之,加钱世界可得~

    为什么 PNG 图片没有被自动转换成 WebP/AVIF ?

    因为 Modern Image Format 暂时还没加上这个功能,具体可以看这里的讨论:https://github.com/WordPress/performance/pull/1421。就目前而言,可以使用 CompressX 插件手动转换 PNG 图片。

  • 不要钱的博客网站性能优化

    赛博菩萨 Cloudflare 给免费帐户提供了 Cache Rules 功能,除了可以点亮域名后的云朵图标之外,还可以利用 Cache Rules 缓存博客网站的页面,提高访问者的使用体验。

    要给 WordPress 网站启用 Cache Rules 推荐使用下面这个插件:

    https://wordpress.org/plugins/wp-cloudflare-page-cache/#developers
    Super Page Cache for Cloudflare

    不过在使用这个插件的时候需要注意,这个插件自带的 Cloudflare API Token 权限说明有误,请参考下面的权限列表。

    如果你想我一样还使用了 LiteSpeed Cache 等缓存插件,建议参考 Super Page Cache 的 FAQ 来调整其他关联插件的配置。

    完成插件的安装跟配置后,可以在 Cloudflare 控制台看到由插件创建的 Cache Rule:

    至此,你的网站就可以享受到免费的全球 CDN 加成了。

  • 使用 cloudflare tunnel 在线上预览本地的开发服务器

    Cloudflare Tunnel 是一项服务,允许开发者将其本地开发服务器通过安全的隧道连接到 Cloudflare 的服务器,并发布到互联网上。这意味着:

    1. 其他人可以直接通过互联网访问你本机的开发服务器
    2. 本地的 HTTP 服务可以自动获得由 Cloudflare 提供的 https 证书

    Cloudflare 在这篇文章中介绍了如何将本地项目发布到互联网,但是对于前端开发服务器的场景来说,缺少一些必要的配置说明,例如,稳定的域名、网页缓存策略等。如果你遇到了开发服务器通过 Cloudflare tunnel 访问后出现了一些诡异的问题,不妨参考下面的步骤来检查一下自己的配置。

    创建本地管理的 tunnel

    在开始之前,请确保你准备好了这些东西:

    • 在本地安装 cloudflared
    • 在 cloudflare 上绑定了自己的域名

    接着,参考这里的说明,创建一个本地管理的 tunnel。完成这里的步骤后,你应该会得到一份 config.yaml 文件,默认存储在 ~/.cloudflared 目录下。

    Cloudflare 的文档中使用了 url 字段配置反向代理,但我建议使用下面的 ingress 配置,这样你可以在同一个配置文件中声明多个服务。

    tunnel: <Tunnel ID>
    credentials-file: /path/to/<Tunnel ID>.json
    
    ingress:
      - hostname: ng-serve.zeeko.dev
        path: /api/.*
        service: http://localhost:3000
      - hostname: ng-serve.zeeko.dev
        service: http://localhost:4200
      # this is a required fallback rule
      - service: http_status:503

    禁用 Cloudfare 缓存

    你的 Cloudflare 帐户很可能默认开启了请求缓存功能,在一些使用场景下,例如,webpack dev server,这个自带的缓存功能会让 dev server 变得很鬼畜,我们需要手动在 Cloudflare 控制面板禁用缓存。

    添加 webpack dev server 白名单

    如果你在使用 webpack dev server,记得把绑定的域名添加到 allowedHosts 中,避免 HMR 失败。

  • 如何使用 Zerotier 连接你家中的设备

    我在家里的旧笔记本上使用 Open My Vault 建立了 NAS,不过我只能在家里连上 WiFi 才能访问它。在过年回老家、出门旅游或者外出办公的时候就没法使用了。虽然在这些场景经常用不上 NAS,不过,“我可以不用,但不能没有”。

    经过一番调研后,我发现我需要的是一个 VPN 软件,通过 VPN 安全地访问运行在家里的网络服务。基于部署难度上的考量,我选择了 zerotier,这是一款非常简单易用的 VPN 软件,免费版可以连接 25 个节点,对于我来说,完全够用了。但是,在国内的网络环境下,节点间的连接往往不太稳定,我在国内没有自己的公网 IP 服务器,所以借助一台香港服务器,来提高 zerotier 网络的稳定性。

    首先,在 my.zerotier.com 创建一个虚拟网络,我选择的私有网段是 10.2.2.0/24,因为这个网段不容易跟常见的家庭路由器内网撞车。

    家里的网络有全局透明代理,可以直接在运行 NAS 的服务器上使用官方的 zerotier 客户端加入 zerotier 网络。

    我没有在路由器上安装 zerotier:

    • 我的 OpenWRT 虚拟机系统版本太奇葩了,没法从官方源安装 zerotier
    • 我希望路由器的功能尽量少一些,毕竟 OpenWRT 跟日常使用的 Linux 系统有很大区别,对我而言有额外的维护负担

    我的 VPS 在香港,也需要加入 zerotier network,直接使用官方的 Linux 客户端就行,我并没有在 VPS 上建立 zerotier moon 服务,这跟我手机上的连接 zerotier 的方式有关。

    手机有时会出门,而且没法设置多个代理,所以就用 v2ray 客户端(SagerNet)将所有访问 10.2.2.0/24 的请求转发到 VPS 服务器。因为 VPS 已经加入了 zerotier 网络,所以手机上就不用安装 zerotier 客户端。笔记本电脑也是同理,这样做还可以避免 zerotier VPN 跟工作 VPN 冲突。

    不过这样的设置也带来了新的问题,对于手机而言,部署在家里的服务在不同网络环境下有不同的 IP 地址,虽然 zerotier 有 DNS 功能,但是我的手机本质上并没有加入 zerotier VPN,所以实际上也没办法使用 zerodns。还好我有自己的域名,在公网上,我把指向家里服务的域名都解析到 zerotier 的私有地址(10.2.2.0/24)。在家里的路由器上,将这些域名强制设置为局域网址(192.168.1.0/24)。

    至此,出门在外的时候,我终于可以随时访问部署在家里的 NAS 了,使用联通 5G 网络运行 iperf3 测试,能够跑到 60Mbps(对比通过 VPS 代理测速的 speedtest.net 结果 120Mbps),应急使用完全足够了。

  • 如何解决米家设备在透明代理下无法联网的问题

    我在家里的一台旧笔记本上部署了透明代理服务,让连上家里网络的设备都能赛博漫游到国外,不过最近,在我的透明代理网络下,米家设备全部没法联网。我的透明代理工作机制如下:

    OpenWRT 强制启用 DHCP,给米家设备设置特定的 IP 地址,并把米家设备的网关设置为主路由;其他设备的网关设置为 OpenWRT。

    OpenWRT 会把所有需要转发(FORWARD,即目标地址非 OpenWRT 本身)的请求发送给透明代理端口(localhost:12345),接着运行在 OpenWRT 上的 v2ray 会对来自 12345 端口的请求分流,国内请求直接发送,国外请求通过代理协议发送到服务端。

    经过一番排查后,我发现在最近的一次主路由固件升级过后,OpenWRT 强制启动 DHCP 失效了,米家设备的网关被主路由设置成了 OpenWRT 。米家设备需要请求 https://:Mijia Cloud。而 Mijia Cloud 的 IP 地址是米家设备通过其他接口获取的,无法通过正常的 DNS 解析。这时,就引发了 v2ray 的一个问题:v2ray 在分流时会嗅探请求的域名以及域名解析后的 IP 地址,帮助判断请求是否需要被代理。因为 Mijia Cloud 无法被解析,导致嗅探功能出错,v2ray 无法进一步处理请求,导致请求被丢弃

    知道了问题的成因,解决方法就很简单,通过 OpenWRT 上的 iptables 分流,让来自米家设备的请求绕过代理:

    iptables -t mangle -A V2RAY -s 192.168.68.<mijia device ip> -j RETURN

    但是这样做,米家设备还是无法联网,通过 tcpdump 发现米家设备只能发送请求,无法接收响应。

    又是一番搜索,怀疑是一些路由器会校验请求来源设备 IP 跟数据包中来源 IP 的一致性,米家设备请求被 OpenWRT 转发到主路由网关,导致来源设备 IP 跟数据包中的来源 IP 不一致,最终请求被拦截在了主路由处。要解决这个问题,得在 OpenWRT 对应的网络接口上启用「动态 IP 伪装」,说白了就是 NAT 。

    其他设备也是被 OpenWRT 转发到主路由的,为什么它们没有出现这种问题呢?这时就需要进一步了解 Linux 的网络原理了:

    所有发往网关的请求应该都需要转发(FORWARD,因为请求的目标 IP 不是网关本身),但是所有基于这篇透明代理白话文设置的透明代理中,转发流量都被 iptables 发到了 12345 端口,变成了入站请求(INPUT),经过代理软件处理后,作为出站请求(OUTPUT)发出,这些流量就不再被认为是转发流量了,在主路由看来,这些被 v2ray 处理过的流量来源请求都是 OpenWRT ,所以不会触发来源请求校验失败。而被 iptables 分流的米家设备请求,从主路由看来,都是由 OpenWRT 发出但是来自米家设备 IP 的,导致校验失败。

    上面的根因分析完全是我半吊子的推测,可能不够准确、专业,但是启用 OpenWRT 的「动态 IP 伪装」之后,确实解决了米家设备无法联网的问题。


    参考链接