又名给vuepress写一个插件

最终的成果如下

思路

最近在看pwa时,在MDN上看见一段乏味的对于实现渐进式图片加载的snippet,粗心如下:

<img src="thumbnail.png" data-src="origin.png"></img>
var imgToLoad=document.qureySelectorAll('img[data-src]')imgToLoad.forEach(img=>{img.setAttribute('src',imgAttribute('data-src'));img.onload=()=>{   img.removeAttribute('data-src')}})
 img[data-src] {            filter: blur(0.2em);        }         img {            filter: blur(0em);            transition: filter 0.3s;    }

总得来说便是在加载渲染页面时,先加载和渲染页面的缩略图,作为一个placeholder,而后再去加载真正的原图,当原图加载结束后,再渲染原图。这缩短了页面加载渲染的工夫,让用户关上页面可能疾速取得反馈。

咱们可能在medium和gatsby.js网站上见到过这种图片加载形式,然而vuepress自身是不反对的,于是便想实现这种图片加载形式,顺便写一个vuepress插件。

实现的步骤如下:

1. 生成一张缩略图,而后插入进去

依据需要,咱们想要这样一个markdown解析成果

![image](./origin.jpg)

解析后为:

<img src="./thumbnial.jpg" data-src="./orign.jpg"></img>

首先须要阐明一下一个vuepress页面是如何生成的

         markdown-loader       vue-loadermarkdown--------------->vue SFCs?------>vue spa

上述并不精确,因为没有去深究两头产物到底是什么。
回到主线上,官网上给出,vuepress应用markdonw-it作为markdown的解析器,即上述的markdown-loader其实就是一个包装后的markdown-it,同时vuepress暴露出了extendMarkdown这一api用来改写markdown解析规定。
所以,咱们能够通过这一api,插入咱们自定义的对于图片的解析规定就可能实现咱们所须要的后果。于是咱们能够写一个mark-it的插件来实现这一性能。
在这,我遇到了两个坑,别离是

  • markdown-it插件仅反对同步函数
  • vue-loader默认不解析data-src这一attribute.因为vuepres应用了url-loader,所以会将图片之类的动态文件给寄存在assets/images文件夹下,而data-src中的图片地址却不会发生变化。

第二个十分好办,咱们能够通过chainWebpack这一api该变vuepress的webpack config就能够实现,即在vueloader的transformAssetUrls上增加img:["data-src"]就好了。

对于第一个生成原图片的缩略图,我应用了imageThumbnail库,该库仅反对异步办法。所以咱们须要将该异步办法包装成真正的同步办法。这里应用到了一个deasync的库,它裸露了node底层的一个sleep()办法,来使main line 强制挂起,提前进行事件循环,直到事件循环完结,再执行主线程序来实现同步。

2. 加载原图片

这一步能够应用clientRootMixin这一api,给globalLayout.vue混入一个全局的办法就能够了~

具体代码能够看一下俺的github仓库,因为接触vuepress不深刻,有些局部的实现十分的naive,而且整个代码也不是很优雅,很多办法都十分生硬,欢送大家pr或者本人编写代码更好地实现。

另,我将该插件上传到了npm上,大家能够npm install玩一玩~

$ npm install vuepress-plugin-progressive-image-loader