 In Teil 1 habe ich darüber gesprochen, wie einfach es ist, einen API-Server in Nuxt zu organisieren . In Teil 2 möchte ich Ihnen erklären, welche zusätzlichen Vorteile Sie vom Nuxt-Fullstack-Server erhalten können .
In Teil 1 habe ich darüber gesprochen, wie einfach es ist, einen API-Server in Nuxt zu organisieren . In Teil 2 möchte ich Ihnen erklären, welche zusätzlichen Vorteile Sie vom Nuxt-Fullstack-Server erhalten können .Teil 2: Beschleunigung des Server-Renderings!
Lassen Sie uns nun anhand des Beispiels Codesandbox.io/s/codesandbox-nuxt-3gzhl überlegen, wie unser Server funktioniert- Der Client fordert die Hauptseite 3gzhl.sse.codesandbox.io an
- Nuxt beginnt auf dem Server mit dem Rendern der Seite /pages/index.vue
- Kommt zu
 
   async fetch() {
    this.users = await this.$api("users", "index");
  },
 
- Über axios stellt er eine http-Anfrage unter 3gzhl.sse.codesandbox.io/api/users/index, d.h. auf mich
- Eine Verbindung wird hergestellt, eine neue Sitzung auf dem Server erstellt und Speicher für die Verarbeitung der http-Anforderung zugewiesen
- Eine eingehende Anfrage wird über das http- Protokoll akzeptiert , die URL wird analysiert, die Parameter werden verarbeitet
- Führt Server-Middleware aus
- Nuxt startet unseren API-Server
- JSON
- users.index(), JSON
- JSON http
- axios JSON
- API
Stellen Sie sich nun vor, wir haben 20 Komponenten auf der Seite, die Daten über die API anfordern. In einer Anforderung für die Seite mit dem Nuxt- Server werden 20 zusätzliche interne http- Verbindungen hergestellt und die Schritte 4 bis 13 werden 20 Mal ausgeführt. Der Nuxt-HTTP-Server kann mehr als 55.000 Anforderungen pro Sekunde verarbeiten. Wenn Sie jedoch interne HTTP-Anforderungen erstellen, reduzieren wir die potenziellen Serverressourcen um das Zehnfache.Wenn wir die Seite auf dem Server rendern, haben wir direkten Zugriff auf alle Controller im Ordner / api /Ändern wir die Logik so, dass beim Rendern auf dem Server der Controller-Code direkt aufgerufen wird und beim Aufruf vom Browser die Anforderung über http gesendet wurde- Benennen Sie die Datei /plugins/api-context.js in /plugins/api-context.client.js um
- Ändern Sie den Dateinamen in den Einstellungen /nuxt.config.js
 
   plugins: ["~/plugins/api-context.client.js"]
 
 Jetzt ist dieser. $ Api- Kontext nur für Client-Code verfügbar
 
- Erstellen Sie diesen. $ api- Kontext , um die Controller direkt auf dem Server
 
 /plugins/api-context.server.js aufzurufen
 export default (context, inject) => {
  inject("api", async (controller, method, params) => {
    try {
      let api = require("../api/" + controller.replace(/^\/+|\/+$|\.+/g, ""));
      return await api[method](params);
    } catch (e) {
      console.error(e);
      throw e;
    }
  });
};
 
- Verbinden Sie das Server-Plugin
 
 /nuxt.config.js
   plugins: [
    "~/plugins/api-context.client.js",
    "~/plugins/api-context.server.js"
  ]
 
Jetzt ruft die Funktion this. $ Api auf dem Server die Controller-Methode direkt auf, und auf dem Client dies. $ Api sendet eine http-Anfrage über axios .Der Code  async fetch() {
    this.users = await this.$api("users", "index");
  },
Beim Rendern auf dem Server wird keine http-Anforderung für sich selbst ausgeführt, sondern einfach die Datei /api/users.js über require verbunden und die index () -Methode aufgerufen , d. h. Elemente von 4 bis 13 werden nicht ausgeführt, aber nur 10 werden ausgeführt. Wenn der Client jedoch im Browser auf die Schaltfläche Aktualisieren klickt , werden dieselben Daten über http angefordert . Hier ist der vollständige Code: Codesandbox.io/s/codesandbox-nuxt-pbriwLeistungstest
Codesandbox.io/s/codesandbox-nuxt-rzdyw- Um den Einfluss der Geschwindigkeit externer Verbindungen zu beseitigen, habe ich den Empfang von Daten durch statische Daten ersetzt:
 
 /api/users.js
 
async function getDataFromDB() {
  return {
    page: 1,
    per_page: 6,
    total: 12,
    total_pages: 2,
    data: [
      {
        id: 1,
        email: "george.bluth@reqres.in",
        first_name: "George",
        last_name: "Bluth",
        avatar:
          "https://s3.amazonaws.com/uifaces/faces/twitter/calebogden/128.jpg"
      },
      {
        id: 2,
        email: "janet.weaver@reqres.in",
        first_name: "Janet",
        last_name: "Weaver",
        avatar:
          "https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"
      },
      {
        id: 3,
        email: "emma.wong@reqres.in",
        first_name: "Emma",
        last_name: "Wong",
        avatar:
          "https://s3.amazonaws.com/uifaces/faces/twitter/olegpogodaev/128.jpg"
      },
      {
        id: 4,
        email: "eve.holt@reqres.in",
        first_name: "Eve",
        last_name: "Holt",
        avatar:
          "https://s3.amazonaws.com/uifaces/faces/twitter/marcoramires/128.jpg"
      },
      {
        id: 5,
        email: "charles.morris@reqres.in",
        first_name: "Charles",
        last_name: "Morris",
        avatar:
          "https://s3.amazonaws.com/uifaces/faces/twitter/stephenmoon/128.jpg"
      },
      {
        id: 6,
        email: "tracey.ramos@reqres.in",
        first_name: "Tracey",
        last_name: "Ramos",
        avatar:
          "https://s3.amazonaws.com/uifaces/faces/twitter/bigmancho/128.jpg"
      }
    ],
    ad: {
      company: "StatusCode Weekly",
      url: "http://statuscode.org/",
      text:
        "A weekly newsletter focusing on software development, infrastructure, the server, performance, and the stack end of things."
    }
  };
  
}
....
 
- api , http
 
 /plugins/api-context.server.js
 export default (context, inject) => {
  inject("server", () => true);
  inject("api", async (controller, method, params) => {
    try {
      if (params && params.httpcall) {
        return await context.$axios["$" + (params ? "post" : "get")](
          "/api/" + controller + "/" + method,
          params
        );
      }
      let api = require("../api/" + controller.replace(/^\/+|\/+$|\.+/g, ""));
      return await api[method](params);
    } catch (e) {
      console.error(e);
      throw e;
    }
  });
};
 
- index.vue fetch api 50
 
 /pages/index.vue
   async fetch() {
    let start = new Date();
    let promises = [];
    let callNum = 50;
    for (let i = 0; i < callNum; i++) {
      promises.push(this.$api("users", "index"));
    }
    let arr = await Promise.all(
      promises.map(async p => {
        return await p;
      })
    );
    let res = [];
    for (let r of arr) {
      res = res.concat(r);
    }
    this.users = res;
    this.fetchType =
      (this.$server && this.$server() ? "Server internal" : "Client http") +
      " API call";
    this.fetchTime = new Date() - start;
  },
 
- httpcall.vue fetch api 50 http
 
 /pages/httpcall.vue
 ...
      promises.push(this.$api("users", "index", { httpcall: true }));
...
    this.fetchType =
      (this.$server && this.$server() ? "Server http" : "Client http") +
      " API call";
...
 
- Vergleichen Sie nun die Ausführungszeit von rzdyw.sse.codesandbox.io
 
 Server internen API - Aufruf Rendering Abrufzeit: 1 ms
 Zeit von 0 ms bis maximal 2 ms
 
 rzdyw.sse.codesandbox.io/httpcall
 Server http - API - Aufruf Rendering holt Zeit: 71MS
 Zeit von 46ms bis maximal 1059ms
 und mehrmals stürzte der Server im Allgemeinen mit einem Fehler ab
 
 RangeError
 Maximum call stack size exceeded
 
Hier ist ein vollständiges Beispiel - Codesandbox.io/s/codesandbox-nuxt-rzdywGesamtteil 2
- Mit minimalen Änderungen können Sie das Rendern von Servern um mehr als das 50-fache beschleunigen. In einem Live-Beispiel wurde das Rendern meiner Seite um das ~ 1,7-fache beschleunigt
- Die HTTP-Serverressourcen des Knotens wurden erheblich reduziert
- In optimierter Weise sollte die einzige Instanz von Nuxt der Last kleiner und mittlerer Projekte standhalten