SSR и GraphQL: как избежать состояния загрузки, если отсутствует javascript (в целях SEO)? - PullRequest
0 голосов
/ 01 мая 2020

Сегодня я впервые пробую SSR (рендеринг на стороне сервера).

Мне нужно использовать его только для целей SEO: так что NO- Javascript браузеры (читатели) вместе со стандартными.

В своем приложении Svelte / Sapper я использую GraphQL (Apollo, URQL или SVQL).

ВОПРОС

Какой бы клиент GraphQL я не выбрал, я не могу понять, как управлять загрузкой вызова в конечную точку GraphQL.

Я имею в виду, что, поскольку мы не находимся в среде, где я могу использовать реактивность к событию для перезаписи части DOM (я выполняю рендеринг в nodejs server) каждый раз, когда пользователь (или поисковая система bot:) просматривает сайт (без javascript), он будет видеть только состояние ожидания вызова GraphQL: "Загрузка задач ...".

Я совершенно не прав?

ПРИМЕР КОДА

<script>
  import { initClient, query } from '@urql/svelte';

  initClient({ url: "https://0ufyz.sse.codesandbox.io" });

  const todos = query({
    query: `
      query {
        todos {
          id
          text
          complete
        }
      }
    `
  });
</script>

{#if $todos.fetching} <!-- This is the only state I see in my server rendered response -->
  Loading todos...
{:else}
  <ul>
    {#each $todos.data.todos as todo}
      <li>{todo.text}</li>
    {/each}
  </ul>
{/if}

Даже если мне удастся дождаться ответа GraphQL на сервере express и отобразить данные вместо сообщения о загрузке, проблема в том, что время намного длиннее (если конечная точка GraphQL Это медленно), и пользовательский опыт удручает, особенно для обычного пользователя с браузером и javascript.

Может быть, я что-то упускаю в рассуждениях.

Но что?

1 Ответ

0 голосов
/ 06 мая 2020

Предварительная загрузка

Как выполнить предварительную загрузку, задокументировано на официальном сайте здесь https://sapper.svelte.dev/docs#Preloading

Так что вы бы сделали что-то вроде этого

<script context="module">
  import { initClient, query } from '@urql/svelte';
  export async function preload() {
     initClient({ url: "https://0ufyz.sse.codesandbox.io" });

     const todos = query({
         // ...
      });
      return todos.toPromise().then(todos => ({todos}));
  }
</script>

<script>
   export let todos; // note this is the same name as above in the returned promise
</script>

{#if ....

Обратите внимание, что это должен быть компонент страницы.

Рендеринг DOM

SSR означает, что вы пишете текстовую строку, которая представляет DOM. Вы делаете это один раз и не можете обновить это потом. То, что выдает SSR, отправляется клиенту, и нет возможности его обновить. Поэтому, если вы хотите дождаться своего API и затем отправить DOM, вам просто нужно подождать, пока запрос займет.

...