云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

服务器_南京建设局网站_排行榜

小七 141 0

使用Cloudflare Workers快速使用Google字体

Google字体是web上最常见的第三方资源之一,但同时也带来了严重的用户性能问题。在边缘运行的Cloudflare Workers是解决这些性能问题的一个很好的解决方案,而不必修改每个使用Google字体的站点的发布系统。本文将详细介绍如何使用Cloudflare Workers修复Google字体的性能。更重要的是,它还提供了使用Cloudflare Workers在边缘进行高性能内容修改的代码。谷歌字体很慢首先,一些背景。谷歌字体为网站提供了丰富的免版税字体供网站使用。您可以选择要使用的字体,最后得到一个简单的样式表URL,以包含在页面上,以及用于将字体应用于页面部分的样式:身体{字体系列:"Open Sans",Sans-serif;}h1{字体系列:"Roboto Slab",衬线;}一旦页面的HTML可用,访问者的浏览器就会获取CSS文件。当浏览器对页面进行布局并发现需要字体用于文本的不同部分时,浏览器将请求底层字体文件。谷歌字体的服务方式,CSS是在一个领域(fonts.googleapis.com)字体文件在不同的域中(fonts.gstatic.com). 由于它们位于不同的域中,每个资源的fetch至少需要往返服务器四次:一次用于DNS查找、建立套接字连接、协商TLS加密(对于https)和最后一次请求本身的往返。字体css和字体文件各4次往返。这些请求不能并行进行,因为直到CSS下载并将样式应用到页面之后才知道字体。在最好的情况下,这意味着在文本可以显示之前需要八次往返(当HTML可用时,浏览器中已经存在的文本)。在一个较慢的3G连接上,往返时间为300ms,这将导致2.4秒的延迟。最好的案例!还有一个资源优先级问题。当您将来自同一个域的所有请求都放在同一个HTTP/2连接上时,它们可以相互调度。关键资源(如CSS和字体)可以在队列中向前推送,并在优先级较低的资源(如图像)之前交付。由于Google字体(以及大多数第三方资源)的服务域与主页资源不同,因此它们不能被优先考虑,最终会在下载带宽上相互竞争。这可能导致实际的取回时间比8次往返的最佳情况要长得多。CSS和字体下载与低优先级图像争夺带宽。在实际文本显示之前,用户将看到页面的图像和框架:页面在3.3秒开始绘制,部分图像没有文本。文本最终在页面加载后6.2秒显示。修复Google字体性能对于CSS和字体文件本身来说,修复性能问题和使字体闪电般快速的路径是不同的。我们可以将往返的总次数减少到一次:将CSS直接嵌入到HTML中。通过页面原点代理Google字体文件。嵌入的CSS作为HTML的一部分立即加载,字体在图像加载之前加载。优化CSS传递对于CSS,简单的答案是下载Google托管的CSS文件,或者直接为其提供服务,或者将其作为嵌入式样式表放入HTML中。问题在于,Google字体服务于一个特定于浏览器的CSS文件,每个浏览器的CSS文件都不同,因此当支持时,它可以提供更新的格式和使用新的功能,同时仍然为旧浏览器提供自定义字体支持。使用Cloudflare Workers,当浏览器请求HTML时,我们可以在获取时用特定于浏览器的样式表内容动态地替换外部CSS引用。这样,嵌入的CSS将始终是最新的,并且支持发出请求的任何浏览器的功能。这完全消除了为字体获取CSS的任何往返过程。优化字体文件传递对于字体文件本身,我们可以通过直接从与HTML相同的域提供字体文件来消除除获取之外的所有往返。这带来了一个额外的好处,即在与页面资源的其余部分相同的HTTP/2连接上提供字体,从而可以正确地确定字体的优先级,而不会争夺带宽。具体地说,当我们将CSS嵌入到HTML响应中时,我们重写所有的字体url以使用与HTML相同的域。当这些重写的请求到达worker时,URL被转换回Google提供的原始URL,并由worker(作为代理)获取。worker获取通过Cloudflare的缓存基础设施进行路由,因此它们将在边缘自动缓存。实际的URL重写非常简单,但是很有效。我们采用如下字体的URL:https://fonts.gsstatic.com/s/。。。我们只需在URL的前面添加页面域:https://www.example.com/fonts.gsstatic.com/s/。。。这样,当他们到达边缘时,工作人员可以查看请求的路径,并立即知道这是一个Google字体的代理请求。此时,重写原始URL很简单。你网站上的一个页面实际上有一个以/fonts.gstatic.com/,这些资源将中断,并应在URL中附加其他内容,以确保它们是唯一的。优化结果在实践中,结果可能相当引人注目。例如,在这个测试页面上,字体可用的等待时间从5.5秒下降到1秒(提高了81%):字体在HTML之后立即加载。从视觉上看,用户体验的改善也是相当显著的。而不是看到一个由图像组成的骨架页面,然后是最终出现的文本,文本立即可用(并且样式正确),用户可以立即开始消费内容:第一次绘制要快得多,在2.5秒时显示所有文本,而原始页面仍为空白。在3.3秒时,原始页面终于开始绘制,显示了部分图像而没有文本。在4.4秒时,优化的页面明显完成,而原始页面仍然没有显示任何文本。6.2秒时,原始页面最终显示文本内容。有一件事我在最初的测试中没有注意到,只有在查看并排视频时才发现,字体只有在优化的情况下才正确设置样式。在最初的情况下,加载字体所花的时间比Chrome的3秒超时时间要长,然后又回到了系统字体。不仅体验速度更快,而且从一开始就用自定义字体正确地设置了样式。使用Cloudflare worker优化Google字体GitHub上提供了实现字体优化的完整Cloudflare工作代码。因为这比文档中的大多数示例要复杂得多。在高层次上,该代码:过滤所有请求并确定请求是针对代理字体还是HTML(并通过未修改的所有其他请求)。重写URL并传递字体请求的fetch请求。对于HTML请求:通过未修改的方式将请求传递到源服务器。返回未修改的非UTF-8内容。。处理流式数据块中的HTML响应。将Google字体样式表链接标记替换为包含CSS和通过源代码重写为代理的字体url的样式标记。这里的代码稍作简化,以便更清楚地理解流程。GitHub上的完整代码添加了对CSS内存中工作缓存的支持(除了持久缓存API),并提供了用于切换HTML重写的查询参数(用于测试)。所有的内容修改都是通过在HTML上以字符串的形式进行操作(使用正则表达式和字符串匹配的组合)。这比将HTML解析为虚拟DOM、对其进行操作并转换回HTML要快得多、重量也轻得多。它还允许将HTML作为流进行增量处理。入口点addEventListener("fetch")调用是任何工作线程的主要入口点,并包含用于拦截入站请求的JavaScript。如果处理程序什么也不做,那么请求将正常传递,工作线程将在处理响应时离开路径。我们的目标是最小化工人必须做的工作量,以确定它是否是一个它感兴趣的请求。在代理字体请求的情况下,我们只需查看请求URL,就可以看到路径以/fonts.gstatic.com/. 为了识别对HTML内容的请求,我们可以查看请求的"accept"头。我测试过的每个主要浏览器都在请求文档时接受的内容类型列表中包含text/html。如果有一个浏览器没有把它作为accept头包含进来,HTML将被传递并原封不动地返回。这里所有内容的目标都是防故障保护,对于任何未涵盖的边缘情况,只返回未优化的内容。这样就不会有任何问题;它只是没有得到额外的性能提升。addEventListener("获取",事件=>{const url=新url(event.request.url);常量接受=event.request.headers.get('accept');如果(事件请求方法=='获取'&&url.pathname.startsWith('/fonts.gstatic.com/')) {//代理字体文件请求事件响应(proxyRequest('https:/'+url.路径名,事件请求));}else if(接受并接受索引("文本/html")!==-1){//处理HTML事件响应(处理HtmlRequest(事件请求