前言vue项目的SEO很差。在传统的混合网站中,页面在服务器上生成并发送回客户端。爬虫在爬取页面时,已经从服务器获取到内容完整的页面,而在vue单页应用中,页面内容是通过javascript动态生成的。传统爬虫爬取页面时,获取到的html文件只有一个div标签,没有任何有价值的东西。解决SEO的方法有很多种,每种方法都有自己的优缺点,预渲染就是其中之一。预渲染的原理是:打包时,使用自己的爬虫爬取指定页面(vue渲染后的页面),生成对应的html文件,将打包后的文件夹部署到服务器。当浏览器访问这些路径时,由于服务器上有对应的html文件,所以访问的是匹配的html文件,可以理解为网页的快照。首次访问或刷新时,查看当前页面的源代码,其中包含大量渲染后的内容。html文件的js中包含newVue()构建vue单页应用的代码。通过$router.push等方式跳转时,依然沿用vue的逻辑,不会影响vue的功能。两张图可以明显感受到预渲染的效果:适用场景:适用于内容变化不频繁的页面,如官网大部分页面、宣传页面等;因为生成的html页面已经渲染过了,不会影响vue的能力,所以也可以作为首屏优化,减少单页白屏的时间。但是预渲染不适合动态的网站内容,比如文章详情页,因为预渲染需要指定url,一个url对应生成一个html文件。文章太多,不可能发一篇新文章,重新部署一次代码。代码实现了这里使用的vue2和vue-cli搭建的项目。prerender插件为:prerender-spa-plugin安装依赖npminstallprerender-spa-plugin-D配置vue.config.js//导入prerender-spa-plugin插件,并创建一个PuppeteerRendererconstPrerenderSPAPlugin=require('prerender-spa-plugin')constRenderer=PrerenderSPAPlugin.PuppeteerRendererconstpath=require('path')module.exports={configureWebpack:()=>{if(process.env.NODE_ENV!=='production')returnreturn{plugins:[newPrerenderSPAPlugin({staticDir:path.join(__dirname,'dist'),//强制,渲染生成文件的目录要和项目包的生产路径一致routes:['/','/about','/some/deep/nested/route'],//需要预渲染的强制路径??//自定义渲染器,不是必须的,但是在vue项目中需要到它的渲染器:newRenderer({//wait对于在渲染页面之前在页面上调用的指定事件,这是与其他爬虫的重要区别//在main.jsdocument.dispatchEvent(newEvent('my-app-element')),两者的事件名称要对应。renderAfterDocumentEvent:'my-app-element'})})]}}}修改main.js/...newVue({router,store,mounted(){//vue执行完挂载的生命周期后,表示页面有Mountingiscomplete,这是再次触发自定义事件,告诉插件可以渲染了document.dispatchEvent(newEvent('my-app-element'))},render:h=>h(App)}).$mount('#app')查看路由方式预渲染必须使用history的路由形式runbuild执行打包命令,它会先执行正常的Pack并进行预渲染。您可以打开dist文件夹以查看打包的更改。vue相关的操作,比如点击事件,路由跳转,填坑预渲染后不生效。查看App.vue文件,看最外层的div是否有id="app",添加即可。打包过程中提示Unabletoprerenderallroutes(无法预渲染所有路由)。我经常在打包过程中遇到它。如果失败了,再试一次,多做几次。猜测是跟渲染性能有关。电脑太差,路由太多,或者页面太大等等。
