预渲染pre-render 和 页面白屏处理

2018-05-31  本文已影响0人  wdp1005

页面白屏来源:

  1. 解析html。
  2. 客户端js渲染。
  3. 加载异步组件渲染。
  4. ajax获取数据渲染。

解析html

  1. 减小html大小。
  2. async/deferer脚本执行。
  3. 脚本放最后。

客户端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>

问题

  1. 当通过url直接访问应用/foo 和/bar,都会先显示// 在这里增加初始内容
  2. 如果组件是异步加载,则下载和渲染组件期间会白屏。


    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
上一篇下一篇

猜你喜欢

热点阅读