prerender-skeleton-plugin
v1.0.1
Published
本插件从预渲染插件`prerender-spa-plugin`改写而来,其中骨架屏的实现主要是参考网易考拉的骨架屏实现方式`awesome-skeleton`。 取两者之精华,并且修复了一些bug并且增加了一些功能。
Downloads
1
Maintainers
Readme
一个支持自动化预渲染以及骨架屏的webpack插件
本插件从预渲染插件prerender-spa-plugin
改写而来,其中骨架屏的实现主要是参考网易考拉的骨架屏实现方式awesome-skeleton
。
取两者之精华,并且修复了一些bug并且增加了一些功能。
使用方式
const PrerenderSpaPlugin = require('prerender-skeleton-plugin');
// webpack plugin
addWebpackPlugin(
new PrerenderSpaPlugin({
staticDir: path.join(__dirname, 'build'),
// puppbter设备
device: 'iPhone X',
// 支持配置浏览器cookie
cookies: '',
// 路由支持数组功能 并且允许配置是否开启骨架屏
routes: [
{ path: '/' },
{ path: '/love' },
{
path: '/tag',
// 骨架屏
skeleton: true,
// 骨架屏的节点 内部使用的是querySelectorAll 只支持单节点
skeletonRoot: '.tag-list',
// 骨架屏是否开启动画
animation: true
},
{
path: '/home',
skeleton: true,
skeletonRoot: '.homeContent',
animation: true
}
],
// 下面的配置跟原有prerender-spa-plugin插件一致
consoleHandler: true,
renderer: new PuppeteerRenderer({
injectProperty: '__PRERENDER_INJECTED',
inject: {
prerender: true
},
headless: true,
// 这个是监听 document.dispatchEvent 事件,决定什么时候开始预渲染
// document.dispatchEvent(new Event('render-event'))
renderAfterDocumentEvent: 'custom-render-trigger'
}),
server: {
// 跨域请求
proxy: {
'/api': {
target: 'https://api.carrotwu.com',
secure: false,
changeOrigin: true,
pathRewrite: { '/api': '' }
}
}
}
})
)
其中options的参数上述两个插件都可以进行透传
dom 节点属性
这是获取优质骨架图的要点,通过设置以下几个 dom 节点属性,在骨架图中对某些节点进行移除、忽略和指定背景色的操作,去除冗余节点的干扰,从而使得骨架图效果达到最佳。
| 参数名称 | 说明 | | --- | --- | | data-skeleton-remove | 指定进行移除的 dom 节点属性 | | data-skeleton-bgcolor | 指定在某 dom 节点中添加的背景色 | | data-skeleton-ignore | 指定忽略不进行任何处理的 dom 节点属性 | | data-skeleton-empty | 将某dom的innerHTML置为空字符串 | | data-skeleton-map | 保证列表渲染兄弟节点时骨架屏效果一致(具体作用可以参考下面) |
data-skeleton-map
因为骨架屏的长宽是根据实时数据的长短来进行背景铺满的,假设我们有这么一个react渲染列表:
<div className="tag-list">
{tagList.map((tag) => (
<Link className="tag-item" key={tag} to={`/tag/${tagMap[tag].value}`}>
{tag}
</Link>
))}
</div>
假设返回的tagList数据文字长度完全不一致,那么生成的骨架屏tag列表也会出现长度不一致的情况:
这种情况下,骨架屏体验会变得很糟糕。我们要的效果是长度一致完全一样,这种情况下我们可以给相同的列表添加上data-skeleton-map
自定义属性。
插件内部会对兄弟节点中含有data-skeleton-map
属性并且tagName相同的节点进行处理,以第一个节点为进行拷贝把第一个兄弟节点后的节点替换成第一个节点的副本。
即渲染的时候是: [a1,a2,a3,a4,a5]。加上data-skeleton-map
属性之后就会替换成[a1,a1,a1,a1,a1]。这样子就能保证节点的骨架屏效果是一致的。
注意事项
注意一下情况
<div className="tag-list">
{tagList.map((tag) => (
<div data-skeleton-map className="tag-item" key={tag} to={`/tag/${tagMap[tag].value}`}>
{tag}
</div>
))}
// taglist2 因为是taglist的兄弟节点 并且tagName也是div 也会被插件认为是相同的节点进行替换
{tagList2.map((tag2) => (
<div data-skeleton-map className="tag-item2" key={tag2}>
{tag}
</div>
))}
</div>
如果认为tagList2的节点跟tagList的节点是不相关的,这时候需要给tagList2加多一层即可:
<div className="tag-list">
{tagList.map((tag) => (
<div data-skeleton-map className="tag-item" key={tag} to={`/tag/${tagMap[tag].value}`}>
{tag}
</div>
))}
<div>
// 这种情况下就不会有干扰
{tagList2.map((tag2) => (
<div data-skeleton-map className="tag-item2" key={tag2}>
{tag}
</div>
))}
</div>
</div>