写点什么

这个库居然能够快速打开页面的链接

作者:FE情报局
  • 2022-12-05
    陕西
  • 本文字数:2236 字

    阅读完需:约 7 分钟

这个库居然能够快速打开页面的链接

背景

这几天领导找我,说我们的 H5 页面内置了很多链接,这些链接的打开的速度有点慢,你有什么办法可以优化一下么?或者有什么好的方案可以拿出来聊聊,我心想,这提升速度的方案无非就那么几种,我要是优化不好,就目前这就业形势,怕是要把我优化了

其实按照惯性,本质来说打开速度慢作为前端的我们无非从以下三点优化

  1. 「优化资源,请求并行」

  2. 「优化代码,提升渲染速度」

  3. 「告诉后端接口响应快点」

这三种不论哪一种,提升的速度只能说是一般,毕竟我们已经做过相关的优化了,再做有点产出和人力不匹配了,除了这些,一些链接不属于我们内部的,这种有没有办法呢?可不可以从另一个方面来考虑问题?

由于是 H5 页面打开之后,所有的链接都是内嵌的,内嵌的话我们找到这个链接,提前加载是不是就可以了,正好前几天看到一个库,quicklink,是 chrome 浏览器团队出的,它可以加快打开链接的速度

https://github.com/GoogleChromeLabs/quicklink

真的这么神奇么?

我们来看一下这个库的基本原理,它的主要作用是通过空闲的时间来提前获取视口内的链接进行预渲染或者预加载,使后面我们打开的链接能够快速

它到底是怎么做到的

检测视口元素

首先,它要知道进入视口的元素有哪些,从而获取进入视口元素的链接,所以第一步先看哪些元素进入视口了

Intersection Observer,这个是 JS 中的一个 API,主要用来检测目标元素是否到达了指定位置,这个 API 用处非常大,之前我们检测的时候会不断去看某个元素的位置信息和高度信息进行对比,判断,来做一些我们想做的事情,有了这个 API,你可以很方便的进行比如图片懒加载,上拉加载下拉刷新的操作,某个元素到某个位置的时候执行什么操作,和之前一直使用 scroll 事件的监听简化了很多

比如要检测红色方块是否处于屏幕内外,可使用下列代码

const io = new IntersectionObserver((o) => console.log(o), {})io.observe(document.getElementsByTagName('div')[0])
复制代码

如果元素在屏幕内出现或者消失,都会打印 o 这个数据,具体的可查看 MDN,然后拿到视图内的元素查找元素对应的链接,链接便获取到了

浏览器空闲时间

requestIdleCallback 这个 api 虽然是一个实验中的功能,但是目前已经能够在各大主流浏览器中使用

它的主要作用是在浏览器空闲的时候执行一些函数,用法是在这个函数中传入一个待执行的函数,比如

window.requestIdleCallback(() => console.log('我将在浏览器空闲的时候调用'))
复制代码

检测连接状态

对于一些使用慢网的用户,我们需要提前检测用户当前网络状态,网络不好的情况下不采用预加载的方式

navigator.connection.effectiveType// 4g
复制代码


如果用户想要减少流量的使用,可用下面的 api 进行检测,返回一个布尔值

navigator.connection.saveData// boolean
复制代码

预加载

预加载的方式有以下几种

link prefetch

最简单的一种就是在页面添加 link 标签

<link rel="prefetch" href="https://baidu.com">
复制代码

添加完 link 标签之后,当你看页面请求的时候,你会发现,它会在浏览器空闲时间去请求预加载的链接

如果动态去添加 link 标签可以么?测试一下

const linkPrefetch = document.createElement('link');linkPrefetch.setAttribute('rel','prefetch');linkPrefetch.setAttribute('href','https://www.baidu.com');document.head.appendChild(linkPrefetch)
复制代码

同样也能达到上述效果

或者使用 XMLHttpRequest 对象进行相应的请求,再或者使用 fetch

预渲染

上图是预渲染和没有预渲染的结果对比,很明显预渲染的页面打开速度要更快,使用 Speculation Rules API 可以灵活的配置需要预渲染的页面

<script type="speculationrules">{  "prerender": [    {      "source": "list",      "urls": ["next.html", "next2.html"]    }  ]}</script>
复制代码

动态添加预渲染也是 OK 的,跟 link 类似,但是前提我们要判断当前浏览器是否支持 Speculation Rules API

if (HTMLScriptElement.supports &&    HTMLScriptElement.supports('speculationrules')) {  const specScript = document.createElement('script');  specScript.type = 'speculationrules';  specRules = {    prerender: [      {        source: 'list',        urls: ['/next.html'],      },    ],  };  specScript.textContent = JSON.stringify(specRules);  console.log('added speculation rules to: next.html');  document.body.append(specScript);}
复制代码

总结

要想使用 quicklink 这个库,它的原理我们上面基本上都说明了,使用方面也比较简单,对整个项目的影响几乎没有

<script src="https://cdnjs.cloudflare.com/ajax/libs/quicklink/2.3.0/quicklink.umd.js"></script><script>window.addEventListener('load', () => {  quicklink.prefetch(["https://baidu.com"])});
复制代码

只需要做如上配置你就能够预加载你想要的链接,当然你也可以不用自己手动配置,直接使用如下代码即可,它就会根据一系列的判断,将预加载在合适的时机进行加载

window.addEventListener('load', () => {  quicklink.listen();});
复制代码


不论要不要加预加载或者预渲染,前提都是要保证不影响用户资源,导致过度渲染,要做到确保用户点击这个链接的可能性很高的时候再预渲染,感兴趣的话可以关注公众号【FE 情报局】

调研完成之后,我们在项目中使用了 Quicklink,转化率提高了 50%,页面转换速度和打开速度提高了好几倍,领导对我刮目相看,升职加薪指日可待

发布于: 刚刚阅读数: 4
用户头像

FE情报局

关注

还未添加个人签名 2018-11-08 加入

还未添加个人简介

评论

发布
暂无评论
这个库居然能够快速打开页面的链接_FE情报局_InfoQ写作社区