Abstract: 1. SSR Server Rendering About server rendering: The Vue official website introduces that there are requirements for the Vue vers...
1. SSR Server Rendering
About server rendering: The Vue official website introduces that there are requirements for the Vue version as well as for the server, which needs to support the nodejs environment.
Trade offs for using SSR:
- Limited by development conditions, browser-specific code can only be used in certain lifecycle hook functions (lifecycle hook). Some external extension libraries (external library) may require special handling to run in a server rendering application.
- Higher environment and deployment requirements, requiring Node.js server operating environment.
- In the case of high traffic, prepare the appropriate server load and adopt the caching strategy wisely.
Advantages:
- Better SEO, because the search engine crawler crawler can view fully rendered pages directly;
- Faster content arrival time (time-to-content), especially for slow network conditions or slow-running devices.
Deficiency: (Problems encountered in development)
1.One set of code and two sets of execution environments will cause various problems. For example, the server does not have window and document objects, and the processing method is to add judgment.
If it is the client, it will execute:
If (process.browser) { Console.log (window) }
Refer to the npm package. For those with dom operations, such as wowjs, you cannot use import instead:
If (process.browser) { Var {WOW} = require ('wowjs') Require ('wowjs/css/libs/animate.css') }
2.Nuxt asyncData method, which gets the data before initializing the page, but only if called by the page component:
/ / load multiple APIs concurrently: Async asyncData ({app, query}) { Let [resA, resB, resC] = await Promise.all ([ App.$axios.get ('/ api/a') App.$axios.get ('/ api/b') App.$axios.get ('/ api/c') ]) Return { DataA: resA.data DataB: resB.data DataC: resC.data } }
Get the parameters in asyncData:
1.Obtain dynamic routing parameters, such as:
/ list/:id' = = >'/ list/123
Receive:
Async asyncData ({app, query}) { Console.log (app.context.params.id) / / 123 }
2.Get url? Get parameters, such as:
/ list?id=123
Receive:
Async asyncData ({app, query}) { Console.log (query.id) / / 123 }
3.If you use the v-if syntax, you will probably encounter this error when deploying online: Error while initializing app DOMException:
Error while initializing app DOMException: Failed to execute 'appendChild' on 'Node': This node type does not support this method.
at Object.We [as appendChild]
According to the 1552 prompt of issue on github nuxt, v-if should be changed to v-show syntax.
2. Static
At Nuxt When js performs generate static packaging, dynamic routing will be ignored.
-| pages/ ---| index.vue ---| users/ -----| _ id.vue
Dynamic routing is required to be a static page. You need to specify the values of dynamic routing parameters and configure them in the routes array.
/ / nuxt.config.js Module.exports = { Generate: { Routes: [ '/ users/1' '/ users/2' '/ users/3' ] } }
Run the package, and you can see the packaged page. But what if the value of the route dynamic parameter is dynamic rather than fixed? Use a function that returns the Promise object type, Use a callback is a function of callback (err, params).
/ / nuxt.config.js Import axios from 'axios' Export default { Generate: { Routes: function () { Return axios.get ('https://my-api/users') .then ((res) = > { Return res.data.map ((user) = > { Return { Route:'/ users/' + user.id Payload: user } }) }) } } }
The payload that we can now access from / users/_id.vue is as follows:
Async asyncData ({params, error, payload}) { If (payload) return {user: payload} Else return {user: await backend.fetchUser (params.id)} }
If you have a lot of dynamic routing parameters, such as commodity details, there may be tens of millions of them. You need an interface to return all the id, then traverse the id when packaging, and package it locally. If a product is modified or removed from the shelves, it has to be repackaged, and it is also very slow and unrealistic to pack in large quantities.
Advantages:
- Pure static files with ultra-fast access speed.
- Compared with SSR, server load is not involved.
- Static web pages should not be attacked by hackers and are more secure.
Deficiency: It is not applicable if there are many dynamic routing parameters.
3. Pre-render prerender-spa-plugin
If you only use SEO to improve a few marketing pages (for example, /, /about, /contact, etc.), then you may need to pre-render. Instead of using a web server to dynamically compile HTML in real time, use pre-rendering At build time (build time), you simply generate a static HTML file for a specific route. The advantage is that it is easier to set up pre-rendering and can use your front end as a completely static site.
$cnpm install prerender-spa-plugin-save
Vue cli 3 vue.config.js configuration:
Const PrerenderSPAPlugin = require ('prerender-spa-plugin') Const Renderer = PrerenderSPAPlugin.PuppeteerRenderer Const path = require ('path') Module.exports = { ConfigureWebpack: config = > { If (process.env.NODE_ENV! = = 'production') return Return { Plugins: [ New PrerenderSPAPlugin ({ // the path to the generated file can also be the same as that packaged by webpakc. // the following sentence is very important! // there can only be one level of this directory. If the directory hierarchy is greater than one level, there will be no error when it is generated, and it will only be stuck during pre-rendering. StaticDir: path.join (_ _ dirname,'dist') // corresponding to your own routing file, for example, if a has parameters, it needs to be written as / a/param1. Routes: ['/','/ product','/about'] // this is very important. If this section is not configured, it will not be precompiled. Renderer: new Renderer ({ Inject: { Foo: 'bar' } Headless: false // document.dispatchEvent (new Event ('render-event')) in main.js, and the event names of both should correspond to each other. RenderAfterDocumentEvent: 'render-event' }) }) ] } } }
Add in main.js:
New Vue ({ Router Render: h = > h (App) Mounted () { Document.dispatchEvent (new Event ('render-event')) } }). $mount ('# app')
Note: mode: "history" must be set in router. When you package it, you can see the file. Package it out of the folder / index.html. For example: about = > about/index.html, which contains html content.
Advantages:
- The change is small, just introduce a plug-in.
Deficiency:
- Cannot use dynamic routing
- For projects with only a small number of pages, packaging will be very slow when there are hundreds of pages.
4. Use Phantomjs to deal with the crawler
Phantomjs is a headless browser based on webkit kernel, that is, there is no UI interface, that is, it is a browser. It's just that the artificial operations such as clicking and turning pages need to be designed and implemented. Although "PhantomJS announced the termination of development", it has satisfied the SEO processing of Vue.
This solution is actually a bypass mechanism, and the principle is to determine whether the access source UA is crawler access through Nginx configuration. If so, the crawler request from the search engine is forwarded to a node server, then parse the complete HTML through PhantomJS and return it to the crawler.
Specific code is stamped here: vue-seo-phantomjs
.
To install global phantomjs, local express, test:
$phantomjs spider.js 'https://www.baidu.com'
If you see a push of html on the command line, congratulations, you have conquered PhantomJS. After startup, or use postman to increase the value of User-Agent to Baiduspider in the request header, the effect is the same.
Deploy online: Node, pm2, phantomjs and nginx related configurations should be installed online:
Upstream spider_server { Server localhost:3000 } Server { Listen 80 Server_name example.com Location / { Proxy_set_header Host $host:$proxy_port Proxy_set_header X-Real-IP $remote_addr Proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for If ($http_user_agent ~ * "Baiduspider | twitterbot | facebookexternalhit | rogerbot | linkedinbot | embedly | quora link preview | outbrain | pinterest | slackbot | vkShare | W3C_Validator | bingbot | Sosospider | Sogou Pic Spider | Googlebot | 360Spider") { Proxy_pass http://spider_server; } } }
Advantages:
- There is no need to change the project code at all, just follow the original SPA development, and the cost of developing SSR is small and not too much.
- This is the best choice for projects that have been developed with SPA.
Deficiency:
- Deployment requires node server support
- Crawler access is slower than web page access, because fixed time resource loading is completed before returning to the crawler
- If a large number of cyclic crawls of Baidu crawlers are maliciously simulated, it will cause server load problems. The solution is to determine whether the visited IP is the IP of Baidu official crawler.
Summary
If you build a large website, such as a mall, don't hesitate to use the SSR server to render directly. Of course, there are also corresponding problems. The community is mature and the English is better, All problems can be solved easily. If it's just a personal blog or a company official website, the other three can be used. If you want to optimize the SEO of projects that have been developed with SPA and support node servers, please use Phantomjs.