npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@xfe-team/better-quicklink

v0.0.2

Published

Faster subsequent page-loads by prefetching in-viewport links during idle time

Downloads

7

Readme

@xfe-team/better-quicklink

可以在空闲时间预获取页面可视区域(以下简称视区)内的链接,加快后续加载速度。

Fork 改进

当前工具库通过 fork 的方式进行了以下问题的改进:

  1. quicklink 参数 origins 应该可以使用正则数组或字符串用于匹配, 因为这样在大多数情况下更为实用
  2. quicklink 当前仅仅只是用过 html 的 tag 标签进行静态的 html 拉去. 然而, 我们可以使用 iframe 进行预拉去整个 html 包括 html 所关联的内部资源.

工作原理

Quicklink 通过以下方式加快后续页面的加载速度:

  • 检测视区中的链接(使用 Intersection Observer)。
  • 等待浏览器空闲(使用 requestIdleCallback)。
  • 确认用户并未处于慢速连接(使用 navigator.connection.effectiveType)或启用省流模式(使用 navigator.connection.saveData)。
  • 预获取视区内的 URL(使用 <link rel=prefetch> 或 XHR)。可根据请求优先级进行控制(若支持 fetch() 可进行切换)。

开发原因

该项目旨在为网站提供一套解决方案,预获取处于用户视区中的链接,同时保持极小的体积(minifiy/gzip 后 <1KB)。

安装方法

nodenpm 用户:

npm install --save @xfe-team/better-quicklink

用法

初始化后,quicklink 将自动在闲时预获取视区内的链接 URL。

快速上手:

<!-- 从 dist 目录下引入 quicklink -->
<script src="//zhcdn01.xoyo.com/xassets/lib/better-quicklink/{VERSION}/better-quicklink.umd.js"></script>
<!-- 初始化(你可以随时进行) -->
<script>
if(!!(window.IntersectionObserver && Array.prototype.includes && window.Promise && window.URL)) {
  quicklink();
}
</script>

举个例子,你可以在 load 方法触发之后进行初始化:

<script>
window.addEventListener('load', () =>{
   quicklink();
});
</script>

或者导入 ES 模块:

import quicklink from "dist/better-quicklink.mjs";
quicklink();

以上方法适用于多页网站。单页应用可以搭配 router 使用 quicklink:

  • 进入新路由地址后,调用 quicklink()
  • 针对特定 DOM 元素/组件调用 quicklink()
  • 调用 quicklink({urls:[...]}),传入自定义 URL 集合进行预获取。

API

quicklink 接受带有以下参数的 option 对象(可选):

  • el:指定需要预获取的 DOM 元素视区。
  • urls:预获取的静态 URL 数组(若此参数非空,则不会检测视区中 document 或 DOM 元素的链接)。
  • timeout:整型数,为 requestIdleCallback 设置超时。浏览器必须在此之前进行预获取(以毫秒为单位), 默认取 2 秒。
  • timeoutFn:指定超时处理函数。默认为 requestIdleCallback。也可以替换为 networkIdleCallback(详见 demo)等自定义函数。
  • priority:布尔值,指定 fetch 的优先级。默认为 false。若配置为 true 将会尝试使用 fetch() API(而非 rel=prefetch)。
  • origins: 静态字符串数组,包含允许进行预获取操作的 URL 主机名。默认为同域请求源,可阻止跨域请求。
  • ignores: RegExp(正则表达式),Function(函数)或者 Array(数组),用于进一步确定某 URL 是否可被预获取。会在匹配请求源之后执行。

待探索:

Polyfills

quicklink:

  • requestIdleCallback 的一个非常小的回退。
  • 需要支持 IntersectionObserver (请参阅 CanIUse)。我们推荐使用 Polyfill.io 等服务选择性地实现此功能:
<script src="https://polyfill.io/v2/polyfill.min.js?features=IntersectionObserver"></script>

或者,请参见 Intersection Observer polyfill

方法

为预获取操作自定义超时时间

默认超时时间为 2 秒(通过 requestIdleCallback),这里我们重写为 4 秒:

quicklink({
  timeout: 4000
});

设置用于检测链接的 DOM 元素

默认值为 document

const elem = document.getElementById('carousel');
quicklink({
  el: elem
});

自定义预获取 URL 数组

如果你想指定用于预获取的静态 URL 列表,而不是视区内的链接,你可以使用自定义 URL。

quicklink({
   urls: ['2.html','3.html', '4.js']
});

为预获取设置请求优先级

默认为低优先级(rel=prefetch 或 XHR)。对于高优先级(priority: true)的操作,尝试使用 fetch() 或退阶使用 XHR。

quicklink({ priority: true });

自定义受允许请求源列表

指定可被预获取的主机名列表,默认情况下仅允许同源主机名。

划重点:你还得加上自己的主机名!

quicklink({
  origins: [
    // 添加我自己的
    'my-website.com',
    'api.my-website.com',
    // 添加第三方的
    'other-website.com',
    'example.com',
    // ...
  ]
});

允许所有源

允许所有跨域请求。

注意:可能会导致 CORB 以及 CORS 问题!

quicklink({
  origins: true,
  // 或者
  origins: []
});

定义一个自定义正则匹配所有源列表(Fork 变更)

指定可被预获取的正则主机名列表,默认情况下仅允许同源主机名。

quicklink({
  origins: [
    /xoyo\.com$/i,
    /baidu\.com$/i
  ]
});

使用 iframe 进行预加载 (Fork 变更)

使用属性 useIframeStrategy 用于启用 iframe 预加载

window.quicklink({
  useIframeStrategy: true,
  origins: [
     /xoyo\.com$/i,
     /baidu\.com$/i
  ],
});

自定义忽略模式

以下过滤器会在匹配 origin 之后执行。Ignores 在避免大型文件下载或 DOM 属性动态响应时十分有用!

// 默认启用同源限制。
//
// 这个示例会忽略所有对以下模式的请求:
//  - 所有 "/api/*" 路径名
//  - 所有 ".zip" 扩展名
//  - 所有带有 noprefetch 扩展名的 <a> 标签
//
quicklink({
  ignores: [
    /\/api\/?/,
    uri => uri.includes('.zip'),
    (uri, elem) => elem.hasAttribute('noprefetch')
  ]
});

也许你还想忽略那些包含 URL fragment 的 URL(比如 index.html#top),不对它们进行预获取。那么对于在页面中使用了锚点标题,或者在单页应用设置了 URL fragment 的情况,这个功能可以避免对类似的 URL 进行预获取。

使用 ignores 来实现:

quicklink({
    ignores: [
        uri => uri.includes('#')
        // 或者使用正则表达式: /#(.+)/
        // 或者使用元素匹配: (uri, elem) => !!elem.hash
    ]
});

浏览器支持

quicklink 提供的预获取是渐进增强的,跨浏览器支持如下:

  • 不使用 polyfills:Chrome,Firefox,Edge,Opera,Android Browser,Samsung Internet 支持。
  • 使用 Intersection Observer polyfill(gzipped/minified 后大约 6KB):Safari,IE9+ 支持。

部分功能支持分层实现:

直接使用预获取器

quicklink 包含一个预获取器,可以单独导入其他项目中。方法是先将 quicklink 作为依赖项安装,然后按如下方式使用:

<script type="module">
import prefetch from '../src/prefetch.mjs';

const urls = ['1.html', '2.html'];
const promises = urls.map(url => prefetch(url));
Promise.all(promises);
</script>

Demo

这个 WebPageTest demo 演示了 quicklink 的预获取功能,它将页面加载性能提高了 4 秒! 这个 Youtube 视频 对使用预获取之前和之后进行了对比。

为了做演示,我们在 Firebase 上部署了一个 Google Blog,接着部署了另一个在主页添加了 quicklink 的版本,测试从主页导航到一个自动预获取的文章所用时间。结果表明预获取版本加载速度更快。

请注意:这绝不是对这项技术优缺点的详尽测试,只是演示了该方法可能带来的潜在改进。你自己的实现可能不尽相同。

相关项目

  • 在用 Gatsby 吗? 现在可以免费下载它了。它使用 Intersection Observer 预获取视图中的所有链接,本项目灵感亦来源于此。
  • 想要更加数据驱动的方案吗? 参见 Guess.js。它根据用户上网方式,使用数据分析和机器学习来预获取资源。它还有 WebpackGatsby 的插件。

ChangeLog

0.0.1 (2019-10-16)

  • feat: 临时修复 prefetch 潜在可能异常的场景

0.0.1 (2019-10-08)

  • feat: init commit

许可证

本项目已获得 Apache-2.0 许可。 原作者: addyosmani [email protected] Fork 来源: quicklink