SEO

It’s important. That’s why it’s universal.

SEO: Search Engine Optimization (Search Engine Optimization), it refers to the site Optimization, such as: website structure adjustment, website content construction, website code Optimization and off-site Optimization methods, to carry out Search Engine Optimization.

In short: use a variety of techniques to ensure that your Web content is maximized, weighted and trafficked by search engines.

** Common keywords: white hat, black hat, SEM, Backlink, Linkbait, PageRank, Keyword Stuffing… , all around a core: SEO; Traffic is the fast track to cash, and SEO is the best way to get traffic at low cost.

At present, most search engines can only capture the data resources directly outputed by URIs, but cannot capture the data of asynchronous requests of Ajax classes. Google has Its Own Webmaster AJAX Crawling Guidelines. Technical support.

SPA

**SPA: ** Single Page Web Application (SPA), which is a single Web page application, is a Web application that loads a single HTML page and dynamically updates the page as the user interacts with the application.

Simply put: The Web is no longer pages, but a whole application, a routing system, a data system, a page (component) system… Composed of applications where a routing system is not required.

Most Vue projects are SPA apps, angular. js, Angular, Vue, React… And the original Pjax.

SPA era, mainly used in Web side history or hash (mainly to low version of the browser compatibility) API, in the first request after routing output the entire application server, the following routing are controlled by the front, front end by routing as hub control (components) a series of page rendering loading and data interaction.

The various frameworks mentioned above are the standardized encapsulation of routing, data and view as the basic structure.

The earliest SPA applications, preached by big manufacturers such as Gmail, Google Docs and Twitter, are widely used in scenarios where SEO requirements are not high.

SSR

SSR: Server Side Render, that is: the web page is generated through Server Side Render output to the client.

In the era before SPA, our Web architecture was mostly SSR, such as WordPress (PHP), JSP technology, JavaWeb… Or DEDECMS, Discuz! These programs are traditional typical SSR architecture, that is, the server takes out data and template combination to generate HTML output to the front end. When the front end makes a request, it requests HTML resources to the server again, and the routing is controlled by the server.

Second, there is a concept called Prerendering.

If you’re only using server-side rendering to improve SEO for a few marketing pages (home page, About, contacts, etc.), you can do it with pre-rendering. Pre-rendering does not compile HTML in real time like server rendering, it only generates several static pages for specific routes during construction, which means we can compile some specific page components into HTML files when we build through Webpack plug-in, and output them directly to the search engine in the form of static resources.

But in real business, most of the time what we need is real-time rendering, which is the subject of today’s discussion.

Why

Why SSR, for the experience, and SEO.

First, users may be accessing websites from a distance when the network is slow – or with poor bandwidth. In these cases, minimize the number of page requests to ensure that the user sees the basic content as soon as possible. You can use Webpack’s code split to avoid forcing users to download an entire single-page application, but it’s not nearly as high-performance as downloading a single, pre-rendered HTML file.

For some parts of the world, people may be able to access the Internet only with a 1998 computer. While Vue only runs on IE9 and above, you might want to provide basic content for those older browsers as well – or trendy hackers using Lynx on the command line.

In most business applications, we have SEO requirements, we need search engines to grab more of our content, more detailed understanding of our web page structure, rather than just the home page or specific static page index, this is the most important significance of SSR.

In short, we need the search engine to see code like this:

Instead of code like this:

Moreover, we also need to achieve SPA on the basis of SSR, namely: first screen rendering.

The basic process is:

When the browser accesses a URI resource for the first time (first screen), the Web server takes the corresponding data according to the route and renders it and outputs it, which contains two parts:

  • Route page corresponding page and rendered data
  • Complete SPA program code

After the client first screen rendering, where we see is actually a and SPA about the application, before any action by the next we are client applications to interact, from the Web page/component rendering, routing is also controlled by the browser, users only need to deal with the current browser application.

Before SSR was officially supported by major SPA frameworks, there were some third-party solutions, such as: Prerender. IO, and what they do is they set up an HTTP middle layer, and when they determine that the access is coming from a spider, they output cached HTML data, and if that data doesn’t exist, they call a third-party service to cache the HTML and repeat.

Another method is to build spider rendering logic by ourselves. When UA is identified as a search engine, the template and data prepared by the server are used to render and output HTML data; otherwise, SPA application code is output.

I also considered this method at that time, but there are many disadvantages, such as:

  • You need to write a separate rendering template for spiders, because most of the SPA code is not directly available on the server
  • If the search engine detects a discrepancy between spider crawler data and real access data, it will do a weight reduction penalty, which means that the render template must still be exactly the same as the EXPECTED output of the SPA

Therefore, the best way is that SPA and the server can use the same template, and use the same server logic branch, to put it simply: Vue, Ng2… Can run directly on the server side.

React based Next. Js, Vue based nuxt. js, and Ng2 support.

Yes, nuxt.js is the star of the day.

Nuxt.js

The official introduction is as follows:

Nuxt.js is a general application framework based on Vue.

By abstracting the organization of the client/server infrastructure, Nuxt.js focuses on the UI rendering of the application.

Our goal is to create a flexible application framework on which you can initialize infrastructure code for new projects or use Nuxt.js in existing Node.js projects.

Nuxt.js presets various configurations needed to develop server-side rendered applications using Vue.

In addition, we also provide a command called nuxt generate, which provides the ability to generate static sites for Vue based applications.

We believe that the functionality provided by this command is a new step towards developing Web applications that integrate various micro-services.

As a framework, Nuxt.js provides many useful features for the typical client/server application architecture pattern, such as asynchronous data loading, middleware support, layout support, and more.

Too long-winded, in my words:

Nuxt.js is a Vue based SSR framework encapsulated by Webpack and Node.js. With nuxt. js, you can implement a first-screen rendering Web application through its agreed file structure and API without having to build a set of SSR programs yourself.

It was also called nuxt.js because it was inspired by Next-js.

The authors are two brothers from France, EvenYou mentioned on weibo many times that they have also seen the brothers in Europe.

Before this, there were some domestic integration attempts on Vue SSR, but they were not successful, mainly because the combination of Webpack and Node did not practice the best scheme. When I saw that Nuxt.js manages the relationships between multiple program components by constringting folders and configuration files nuxt.config.js, I thought, cool!

I’m not going to give you any more details, because the official documentation is very comprehensive and mature, at 0.10.5 (now RC-11), but only the architecture and principles, and some of the problems that production environments encounter.

First of all, nuxt.js is a Node application. As mentioned above, we want to run Vue on the server, so we must use the Node environment.

Our access to the nuxt.js application is actually access to the route of the Node.js program, which outputs the first screen rendering + the SPA script code for rerendering, and the route is generated by the pages folder that nuxt.js has agreed to.

So, overall, nuxt.js manages our application through the constraints of individual folders and configuration files without being extensible, with its own plug-in mechanism.


According to the current version, the file structure of nuxt.js program is roughly divided into the following parts:

  • Pages: each page component, used to generate corresponding routes, support nesting, support dynamic routes
  • Components: Components that you use to manage public or non-public components yourself
  • Layouts: A component that allows you to assign different pages to different layouts
  • Assets: Various assets used for Webpack compilation, usually small assets, such as replacing Sprite images and so on
  • Middleware: Middleware that executes before first screen rendering and routing, returns promise or next (useful!)
  • You can also import plugins, as well as some Node modules. You can even import your own third-party libraries
  • Store: Built with vuex, you can directly return the data module or return a self-built vuex root object, specific to the document
  • Others: you can customize folders and alias mappings, as described in the documentation, here is the configuration code

Nuxt.config. js extends program management into the following categories:

  • Build: mainly corresponds to the configuration items in Webpack, you can extend the default Webpack configuration, as shown here
  • cache: mainly corresponds to the built-in component cache modulelru-cacheConfiguration object, has default value, optional close
  • css: corresponds to our references to style files everywhere in SPArequirestatements
  • dev: used to customize environment variables, corresponding to beforewebpack.config.jsVariable statements in related files
  • Env: Same as above
  • generate:generateCustomize the behavior of command execution
  • head: the correspondingvue-metaGlobal configuration of plug-ins,vue-metaFor VUE/SSR program document meta information management
  • Loading: Used to customize nuxt.js built-in progress bar components
  • Performance: used to configure node. js server performance
  • plugins: Used for management and applicationpluginsPlug-ins in folders
  • Rootdir: used to set the root directory of the nuxt.js application.
  • Srcdir: the source directory used to set the nuxt.js application.
  • router: designed forvue-routerExtensions and customizations, including middleware configurations, are not perfect (see below).
  • Transition: Used to customize the default property values for the built-in page-switching transition effects in Nuxt.js
  • watchers: Used to customize the file listening module built into nuxt.jschokidarAnd Webpack configuration items

generate

Meanwhile, Nuxt.js supports building applications directly into static HTML with the generate command, which, as mentioned above, can be exported as a static resource.

Production environment practice

Special asynchronous requirements

This is one of the most common problems in production environments.

Take the Sidebar on the right side of my blog as an example. In the component structure, it is a sub-component under the host layout, not a page component, and cannot use the fetch method in the page component. The official explanation is that sub-components cannot use blocking asynchronous request, that is: The asynchronous data obtained by the child components cannot be used for server-side rendering, which is reasonable for the program to avoid abnormal blocking and simplify the business model;

But in practical need, I need these asynchronous data enhancement stations within the chain. So, we can use the nuxtServerInit API in built-in Vuex. This API is the method executed for the first time after the nuxt.js program is instantiated. Inside, it returns a promise from which we can complete all asynchronous requests for sub-components within our site. You can then map the data to the corresponding child component, and there is the code in action.

Memory problems

There is a memory expansion problem on ali Cloud low server. The memory of a Blog program Run is as high as 100M+. Of course, due to the special single-thread asynchronous mechanism of Node.js, I don’t care about it temporarily.

However, after a period of access, especially the instant high concurrency access, will lead to memory expansion burst table downtime, after analysis, is caused by component cache, component cache reduced to 10, the problem has been improved, but not obvious;

The deeper reason is that each time a user visits, the program rerenders the component output, and the component data resides in memory for a period of time until V8GC collects it.

The final solution is:

Use the official recommended “use nuxt.js in the code” method to customize the node.js program entry, some optimization of the program; If you need deep control of both your business and your application, I recommend this approach, which allows you to manage your application in the same way you manage Node.js applications.

The specific optimization method uses a garbage collection module called idLE-GC to optimize memory management.

Idle-gc was a feature that was deprecated in earlier versions of Node. It was used to recycle heap memory when idle, and was later removed from Node.js due to a BUG that often caused CPU loads. The authors of this project fixed the BUG and released the module.

In addition, if the machine configuration is sufficient, it is recommended to enable the cache option, that is, the cache option, and appropriate large configuration, cache meaning is to use memory to reduce the CPU calculation pressure, this is a good business practice for single-threaded Node.js.

Last update: this module is no longer used and was eventually resolved by optimizing business logic + optimizing page structure and abstraction granularity + upgrading hardware.

This is one of the daily data from the PM2 monitoring process:

Mobile version adaptation problem

Almost all search engines are split between PC and mobile, so we can use the layouts module to separate our mobile and PC services. In my blog project, because the business logic and page are not complex enough, so I use the form of CSS3 media query + component judgment to achieve mobile adaptation.

Route Custom meta problem

Currently, the SUPPORT for the Router in the API is not comprehensive, such as custom configuration is not available, but you can modify and manage the instantiated Router object through the host component corresponding to the cycle hook, although it is not elegant.

The Window problem

Since the underlying Vue uses the Virtual DOM, the compilation of nuxt.js in node.js is actually a process of evaluating objects to strings, and does not rely on Window/ DOM, or any VUe-based SSR program.

We may use some DOM-dependent plug-ins/extensions in actual production. The correct way is to determine the application environment of the plug-in/extension by variables according to the official document – the method recommended by the plug-in for browser only. Here is the practice code, or use the SSR version of the component, such as: Vue-awesome-swiper, or a plug-in that wraps directive instead of Component, should not use DOM libraries in Node.js such as JsDOM. These libraries are designed for crawlers and tests and take up a lot of memory. This is not a real solution!

For more common usage questions, please refer to the official answers.

Finally: this is my blog, but also a complete nuxt.js program, source code here.

If there is a mistake, look forward to correction

After the