Skip to content

Commit

Permalink
docs(README): add simplified Chinese version for README.md (#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
jothy1023 committed Dec 18, 2018
1 parent 0073e2a commit a3e0221
Showing 1 changed file with 257 additions and 0 deletions.
257 changes: 257 additions & 0 deletions translations/zh-cn/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
<p align="center">
<img src="https://i.imgur.com/NVRZLHv.png" width="640" alt="quicklink">
<br>
<a href="https://www.npmjs.org/package/quicklink"><img src="https://img.shields.io/npm/v/quicklink.svg?style=flat" alt="npm"></a>
<a href="https://unpkg.com/quicklink"><img src="https://img.badgesize.io/https://unpkg.com/quicklink/dist/quicklink.js?compression=gzip" alt="gzip size"></a>
<a href="https://www.npmjs.com/package/quicklink"><img src="https://img.shields.io/npm/dt/quicklink.svg" alt="downloads" ></a>
<a href="https://travis-ci.org/GoogleChromeLabs/quicklink"><img src="https://travis-ci.org/GoogleChromeLabs/quicklink.svg?branch=master" alt="travis"></a>
</p>

# quicklink

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

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

- **检测视区中的链接**(使用 [Intersection Observer](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API))。
- **等待浏览器空闲**(使用 [requestIdleCallback](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback))。
- **确认用户并未处于慢速连接**(使用 `navigator.connection.effectiveType`)或启用省流模式(使用 `navigator.connection.saveData`)。
- **预获取视区内的 URL**(使用 [`<link rel=prefetch>`](https://www.w3.org/TR/resource-hints/#prefetch) 或 XHR)。可根据请求优先级进行控制(若支持 fetch() 可进行切换)。

## 开发原因

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

## 安装方法

[node](http://nodejs.org)[npm](https://npmjs.com) 用户:

```sh
npm install --save quicklink
```

或者从 [unpkg.com/quicklink](https://unpkg.com/quicklink) 获取 `quicklink`

## 用法

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

快速上手:

```html
<!-- 从 dist 目录下引入 quicklink -->
<script src="dist/quicklink.js"></script>
<!-- 初始化(你可以随时进行) -->
<script>
quicklink();
</script>
```

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

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

或者导入 ES 模块:

```js
import quicklink from "dist/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](https://github.com/pastelsky/network-idle-callback)(详见 demo)等自定义函数。
- `priority`:布尔值,指定 fetch 的优先级。默认为 `false`。若配置为 `true` 将会尝试使用 `fetch()` API(而非 rel=prefetch)。
- `origins`: 静态字符串数组,包含允许进行预获取操作的 URL 主机名。默认为同域请求源,可阻止跨域请求。
- `ignores`: RegExp(正则表达式),Function(函数)或者 Array(数组),用于进一步确定某 URL 是否可被预获取。会在匹配请求源之后执行。

待探索:

- 支持资源扩展名检测及使用 [rel=preload](https://w3c.github.io/preload/) 获取高优资源。
- 使用 [Priority Hints](https://github.com/WICG/priority-hints) 进行重要性提示。

## Polyfills

`quicklink`:

- [requestIdleCallback](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback) 的一个非常小的回退。
- 需要支持 `IntersectionObserver` (请参阅 [CanIUse](https://caniuse.com/#feat=intersectionobserver))。我们推荐使用 Polyfill.io 等服务选择性地实现此功能:

```html
<script src="https://polyfill.io/v2/polyfill.min.js?features=IntersectionObserver"></script>
```

或者,请参见 [Intersection Observer polyfill](https://github.com/w3c/IntersectionObserver/tree/master/polyfill)

## 方法

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

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

```js
quicklink({
timeout: 4000
});
```

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

默认值为 `document`

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

### 自定义预获取 URL 数组

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

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

### 为预获取设置请求优先级

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

```js
quicklink({ priority: true });
```

### 自定义受允许请求源列表

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

> **划重点**:你还得加上自己的主机名!
```js
quicklink({
origins: [
// 添加我自己的
'my-website.com',
'api.my-website.com',
// 添加第三方的
'other-website.com',
'example.com',
// ...
]
});
```

### 允许所有源

允许所有跨域请求。

> **注意**:可能会导致 [CORB](https://chromium.googlesource.com/chromium/src/+/master/services/network/cross_origin_read_blocking_explainer.md) 以及 [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) 问题!
```js
quicklink({
origins: true,
// 或者
origins: []
});
```

### 自定义忽略模式

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

```js
// 默认启用同源限制。
//
// 这个示例会忽略所有对以下模式的请求:
// - 所有 "/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` 来实现:

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

## 浏览器支持

quicklink 提供的预获取是[渐进增强](https://www.smashingmagazine.com/2009/04/progressive-enhancement-what-it-is-and-how-to-use-it/)的,跨浏览器支持如下:

- 不使用 polyfills:Chrome,Firefox,Edge,Opera,Android Browser,Samsung Internet 支持。
- 使用 [Intersection Observer polyfill](https://github.com/w3c/IntersectionObserver/tree/master/polyfill)(gzipped/minified 后大约 6KB):Safari,IE9+ 支持。

部分功能支持分层实现:

- 用于检查用户是否处于低速联网状态(通过`navigator.connection.effectiveType`)的 [Network Information API](https://wicg.github.io/netinfo/) 仅适用于 [Chrome 61+ 和 Opera 57+](https://caniuse.com/#feat=netinfo)

- 如果 `{priority:true}`[fetch()](https://fetch.spec.whatwg.org/) 均不可用,则将使用 XHR。

## 直接使用预获取器

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

```html
<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](https://www.webpagetest.org/video/view.php?id=181212_4c294265117680f2636676721cc886613fe2eede&data=1) 演示了 quicklink 的预获取功能,它将页面加载性能提高了 4 秒! [这个 Youtube 视频](https://youtu.be/rQ75YEbJicw) 对使用预获取之前和之后进行了对比。

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

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

## 相关项目

- 在用 [Gatsby](https://gatsbyjs.org/) 吗? 现在可以免费下载它了。它使用 `Intersection Observer` 预获取视图中的所有链接,本项目灵感亦来源于此。
- 想要更加数据驱动的方案吗? 参见 [Guess.js](https://guess-js.github.io/)。它根据用户上网方式,使用数据分析和机器学习来预获取资源。它还有 [Webpack](https://www.npmjs.com/package/guess-webpack)[Gatsby](https://www.gatsbyjs.org/docs/optimize-prefetching-with-guessjs/) 的插件。

## 许可证

本项目已获得 Apache-2.0 许可。

0 comments on commit a3e0221

Please sign in to comment.