又名给vuepress写一个插件😊
最终的效果以下css
最近在看pwa时,在MDN上看见一段有趣的关于实现渐进式图片加载的snippet,大意以下:html
<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,而后再去加载真正的原图,当原图加载完毕后,再渲染原图。这缩短了页面加载渲染的时间,让用户打开页面可以快速得到反馈。vue
咱们可能在medium和gatsby.js网站上见到过这种图片加载方式,可是vuepress自己是不支持的,因而便想实现这种图片加载方式,顺便写一个vuepress插件。node
实现的步骤以下:webpack
根据需求,咱们想要这样一个markdown解析效果git

解析后为:github
<img src="./thumbnial.jpg" data-src="./orign.jpg"></img>
首先须要说明一下一个vuepress页面是如何生成的web
markdown-loader vue-loader markdown--------------->vue SFCs?------>vue spa
上述并不许确,由于没有去深究中间产物究竟是什么。
回到主线上,官网上给出,vuepress使用markdonw-it
做为markdown的解析器,即上述的markdown-loader其实就是一个包装后的markdown-it
,同时vuepress暴露出了extendMarkdown
这一api用来改写markdown解析规则。
因此,咱们能够经过这一api,插入咱们自定义的关于图片的解析规则就可以实现咱们所须要的结果。因而咱们能够写一个mark-it的插件来实现这一功能。
在这,我遇到了两个坑,分别是shell
data-src
这一attribute.由于vuepres使用了url-loader
,因此会将图片之类的静态文件给存放在assets/images
文件夹下,而data-src
中的图片地址却不会发生变化。第二个很是好办,咱们能够经过chainWebpack
这一api该变vuepress的webpack config就能够实现,即在vueloader的transformAssetUrls
上添加img:["data-src"]
就行了。npm
对于第一个生成原图片的缩略图,我使用了imageThumbnail
库,该库仅支持异步方法。因此咱们须要将该异步方法包装成真正的同步方法。这里使用到了一个deasync
的库,它暴露了node底层的一个sleep()
方法,来使main line 强制挂起,提早进行事件循环,直到事件循环结束,再执行主线程序来实现同步。
这一步可使用clientRootMixin
这一api,给globalLayout.vue
混入一个全局的方法就能够了~
具体代码能够看一下俺的github仓库,因为接触vuepress不深刻,有些部分的实现很是的naive,并且整个代码也不是很优雅,不少方法都很是僵硬,欢迎你们pr或者本身编写代码更好地实现👏。
另,我将该插件上传到了npm上,你们能够npm install玩一玩~
$ npm install vuepress-plugin-progressive-image-loader