动态网站实现 SPA 般的速度

动态网站实现 SPA 般的速度

August 21, 2023
11ty , SPA , 工具箱 ,

昨天在研究 11ty 的时候看到了 SINGLE PAGE APPLICATIONS (SPA) WITH ELEVENTY 这篇文章,文中提到 11ty 工具生成的网站偏向于传统静态网站,通称为 MPA,如 Gatsby.js 、Vuepress、Gridsome 等工具则都是 SPA。并且说明 11ty 可能并不是最优的 SPA 网站生成工具,他们认为 SPA 的网页性能会偏低,且打包的一些配套脚本体积会比较大。

The data supports the case that Single Page Applications are a bad default for the web too. An analysis of Core Web Vitals across 9.3 million web sites in February 2023 shows that only 26% of sites built using the most popular Single Page Application framework (Next.js) have good Core Web Vitals, far lower than the web at large (40%).

不过我之前使用的 Gridsome 没有感受到他们说的这个问题(有可能是项目还没什么附加代码),Gridsome 生成的 SPA 网站在速度上有着惊人的表现,所有页面几乎都是秒加载,以至于我当时还以为是本地缓存的原因,所以让群里的仓颉同学体验了一下,他给我的反馈也是极佳。这还是在直接使用了 Github Page,扶墙状态下的体验,感兴趣的朋友也可以体验一下:My Gridsome Page

不过 SPA 网站也有一些自己的缺点,目前我能感受到的一个就是可能需要做额外的搜索引擎优化,不过现代的这些工具已经会帮用户做好这一步了。

那么,MPA 网站、动态网站有什么办法实现更快的页面加载速度,获得如 SPA 一般的体验呢?

这个问题其实是国内博客爱好者一直在想办法解决的,我之前也有一些体验,之前使用过 instant.page 的页面加载优化工具,不过那个工具比较偏保守 instant.page 的策略是用户鼠标悬浮的时候进行页面预加载,我测试了一下,我悬浮到点击这个过程有大概 200ms 的延迟,这个脚本就是利用这个时间进行网页预加载。

不过 instant.page 的效果就我使用下来而言,感觉还是比较玄学的,优化不太明显。

11ty 的这篇文中也提到了一些让网页加速的办法和工具,其中一个叫 quicklink 的项目让我很感兴趣,我实际体验下来的感觉是要比 instant.page 的效果强上不少。

quicklink 的策略要稍微激进一些,他会在页面加载完成后对所有视窗内出现的站内链接进行预加载。并且随着视窗的改变持续监听是否有新的需要预加载的页面。

Quicklink attempts to make navigations to subsequent pages load faster. It:
Quicklink 尝试使后续页面的导航加载速度更快。它:

Detects links within the viewport (using Intersection Observer)
检测视口内的链接(使用 Intersection Observer)

Waits until the browser is idle (using requestIdleCallback)
等待浏览器空闲(使用 requestIdleCallback)

Checks if the user isn't on a slow connection (using navigator.connection.effectiveType) or has data-saver enabled (using navigator.connection.saveData)
检查用户是否处于慢速连接(使用 navigator.connection.effectiveType )或启用了数据保护程序(使用 navigator.connection.saveData )

Prefetches (using <link rel=prefetch> or XHR) or prerenders (using Speculation Rules API) URLs to the links. Provides some control over the request priority (can switch to fetch() if supported).
预取(使用 <link rel=prefetch> 或 XHR)或预呈现(使用推测规则 API)链接的 URL。提供对请求优先级的一些控制(如果支持,可以切换到 fetch() )。

如何使用

你只需要在页面的 head 部分或者 body 内最后的部分写入以下代码就可以体验,国内用户可以使用一些 CDN 来优化加载速度,我用的 https://jsd.cdn.zzko.cn/ 的镜像:

<script  src="https://jsd.cdn.zzko.cn/npm/quicklink@2.3.0/dist/quicklink.umd.js"></script>
<script>window.addEventListener('load', () => {  quicklink.listen();});</script>

效果

效果如下图,个人体验下来效果还不错,你觉得呢?欢迎评论和我交换意见。

加入评论