预渲染pre-render 和 页面白屏处理
2018-05-31 本文已影响0人
wdp1005
页面白屏来源:
- 解析html。
- 客户端js渲染。
- 加载异步组件渲染。
- ajax获取数据渲染。
解析html
- 减小html大小。
- async/deferer脚本执行。
- 脚本放最后。
客户端js渲染
// 使用vue-cli构建后的index.html,内容由客户端js渲染
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
<script type="text/javascript" src="/static/js/manifest.6b0afe9dae29c384450a.js"></script>
<script type="text/javascript" src="/static/js/vendor.426ef21560bb1458790e.js"></script>
<script type="text/javascript" src="/static/js/app.7721a2d8031d1ad79913.js"></script>
</body>
可以在模板html中增加初始内容,客户端渲染出页面时会自动替换掉。
<body>
<div id="app">
// 在这里增加初始内容
</div>
<!-- built files will be auto injected -->
</body>
问题
- 当通过url直接访问应用/foo 和/bar,都会先显示
// 在这里增加初始内容
。 -
如果组件是异步加载,则下载和渲染组件期间会白屏。
image.png
加载异步组件渲染。
取消动态组件
// const Foo = () => import('@/components/Foo')
// const Bar = () => import('@/components/Bar')
import Foo from '@/components/Foo'
import Bar from '@/components/Bar'
ajax获取数据渲染
比如列表数据响应前ul为空,可以使用骨架屏占位。
<ul v-if="users.length > 0">
<li v-for="user in users"
:key="user.name">{{ user.name }}</li>
</ul>
<div v-else>
<!-- 使用svg,节省网络下载时间,但是动画会被js阻塞 -->
<svg width="750" height="191" class="svgclz">
<circle cx="95" cy="102" r="63" fill="#edeff0" mask="url(#shining)" />
<rect width="160" height="35" x="190" y="45" fill="#edeff0" mask="url(#shining)" />
<rect width="400" height="35" x="190" y="90" fill="#edeff0" mask="url(#shining)" />
<line x1="0" y1="190" x2="750" y2="190" stroke="#edeff0"></line>
</svg>
</div>
预渲染 pre-render
预渲染有点像服务器端渲染和静态站点生成。
在构建应用时,使用预渲染器启动一个类浏览器环境用来加载指定路由,并将得到的html转存储到指定的文件目录,构建出来的 html 文件已有部分内容,减少白屏时间。
不适合渲染动态页面;渲染大量路由时,会延长构建时间。
参考:Prerender Vue.js Apps with prerender-spa-plugin v3
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const PuppeteerRenderer = PrerenderSPAPlugin.PuppeteerRenderer;
...
new PrerenderSPAPlugin({
staticDir: path.join(__dirname, '../dist'),
routes: ['/', '/foo', '/bar'],
renderer: new PuppeteerRenderer({
// // eg, with `document.dispatchEvent(new Event('custom-render-trigger'))`
// captureAfterDocumentEvent: 'custom-render-trigger',
// // Optional - Wait to render until the specified element is detected using `document.querySelector`
renderAfterElementExists: '#app',
})
})
...
文件目录
index.html
bar/index.html
foo/index