21

Angular ベースのクライアント側 MVC アプローチとサーバー側 NodeJS / ExpressJS サーバー側レンダー アプローチのどちらかを決定するためのオプションをチームで探しています。

Angular アプリは 1 つの index.html としてダウンロードし、XHR リクエストを作成してページに入力します。ページを事前にレンダリングする必要があるため、PhantomJS を使用して、コンテンツがサーバー上の場所に変更されたときにすべてのページのコピーを保存しました。これにより、SEO のサポートが可能になります。

他の人がこれを行っているかどうかを確認するために、人々が指摘できるフルページのバックボーン アプリケーションまたは角度のあるアプリケーションの例はありますか。

または、実際に目にすることができる NodeJS サーバー側でレンダリングされたアプリケーションの例です。

最後に、この種のアーキテクチャについて意見を持っている人はいますか?

4

4 に答える 4

34

私は主にサーバー レンダリング アプリケーションと主にクライアント レンダリング アプリケーションの両方に取り組んできました。各タイプには、独自の長所と短所があります。ただし、どちらかを選択する必要があるという考えは、誤った二分法です。リソースがあれば、両方を組み合わせて両方の長所を活かすことができます。

純粋にクライアント側のフレームワークには 4 つの主な課題があります。

  • SEOと分析
  • キャッシング
  • メモリー
  • レイテンシー

SEO

Node.JS を使用しているため、サーバー上のクライアント側フレームワークを使用して googlebot と会社の静的ページを出力するだけで、SEO の問題を軽減できます。最近、Google は単一ページ アプリケーション用の便利な Analytics API を作成しましたが、マスター テンプレートの最後に数行を追加するだけでは、少し手間がかかります。

キャッシング

キャッシュは、Web アプリケーションを高速化するための非常に重要な方法です。少量のデータの場合、クライアントのメモリまたは localStorage にデータをキャッシュする方が高速な場合がありますが、ストレージ スペースは非常に限られています (現在約 5MB)。さらに、localStorage でキャッシュの無効化を行うのは非常に困難です。

メモリー

記憶は、私が見落とすために心から支払ったものです。いつの間にか 200MB 以上の RAM を占有するアプリケーションを作成してしまっていました。最適化で半分にできるかもしれませんが、サーバー上ですべてレンダリングした場合、20 MB 以上かかるとは思えません。

レイテンシー

レイテンシも見逃しやすいです。たとえば Drupal では、ページごとに約 50 から 100 の SQL クエリが実行されます。データベース サーバーがアプリケーション サーバーのすぐ隣にある場合、待ち時間を気にする必要はなく、これらすべてのクエリを数百ミリ秒未満で実行できます。クライアント側のアプリケーションは、通常、1 つの AJAX リクエストを作成するのに 100 ミリ秒かかります。これは、これらの往復を最小限に抑えるためにサーバー側 API の設計に多くの時間を費やす必要があることを意味しますが、その時点で、サーバーは HTML を生成するために必要なすべてのデータを既に持っています。適切な RESTful インターフェイスと通信するクライアント側アプリケーションは、注意しないと非常に遅くなる可能性があります。

37 Signals は最近、新しいバージョンの Basecamp に実装したハイブリッド クライアント/サーバー アーキテクチャについてブログに掲載しました。このハイブリッド アプローチでは、サーバーを使用して HTML をレンダリングしますが、クライアントで PJAX などを利用して、ページ全体の更新をなくします。効果は本当に速く、私が推奨するものです。

于 2012-09-06T04:32:43.647 に答える
8

サーバー上の node.js を使用すると、原則として、同じコードを使用してクライアントとサーバーでレンダリングできます。このアプローチを実装するフレームワークはMeteorDerbyであり、クライアントとサーバー間のデータ モデルの透過的な同期も行います。どちらもまだアルファ版と見なされていますが、すでにかなりうまく機能しているようです。

一方、クライアント側とサーバー側の両方のレンダリングには長所と短所があります。

  • クライアント側のレンダリングには、最初のページの読み込みに時間がかかるという欠点がありますが、すべてのリソースが読み込まれると、ユーザーはページなしでシームレスにサイトをナビゲートできます。Ajax 呼び出しの数を最小限に抑えたり、クライアント側のキャッシュ (Angular.js コントローラーのキャッシュ データなど) を使用したりすることが必要になる場合があります。
  • サーバー側のレンダリングは、最初のページの読み込みが速く、SEO には適していますが、ユーザーがナビゲートするたびに、新しい URL を読み込む間、ページ全体が 1 秒間空白になります。

したがって、すべては、最初のページの読み込みを速くしたいが、ユーザーがそれほど長く滞在することを期待しない (サーバー側のレンダリングを使用する) か、または (Gmail のように) ページが高速に読み込まれることはそれほど重要ではないが、ユーザーは長時間ナビゲートします (その後、クライアント側のレンダリングを使用します)。

于 2012-09-06T01:02:52.253 に答える
5

現在、このクレイジーなアプローチをテストしています。クライアントで実行される angularJS アプリがあります。Googlebot をエージェントとして検出すると、 PhantomJSインスタンスを実行し、その出力でクローラーに応答します。トリッキーな部分は、クライアント アプリの読み込みがいつ完了したかを把握して、それを選択して返すことができるようにすることです。クライアント側の JS アプリがロードされる前にこれを行うと、クローラーは多くのデータを返さず、ほとんどが index.html だけを返します。

簡単な実装はここにあります: http://pastebin.com/N3w2iyr8

更新: 元の回答を書いた時点では、prerendr.io のようなものは存在しませんでしたが、今すぐ指摘できます。

于 2013-01-02T14:20:57.063 に答える
0

Application on Angular を Google がクロールできるようにするための私のソリューション。aisel.coで使用

  1. https://github.com/localnerve/html-snapshotsが扱うスナップショット
  2. .htaccess にルールを追加する

    RewriteCond %{QUERY_STRING} ^_escaped_fragment_=(.*)$
    RewriteCond %{REQUEST_URI} !^/snapshots/views/ [NC]
    RewriteRule ^(.*)/?$ /snapshots/views/%1 [L]
    
  3. スナップショット用の node.js スクリプトを作成し、ターミナルで実行します: node snapshots.js

    var htmlSnapshots = require('html-snapshots');
        var result = htmlSnapshots.run({
        input: "array",
        source: [
                "http://aisel.dev/#!/",
                "http://aisel.dev/#!/contact/",
                "http://aisel.dev/#!/page/about-aisel"
        ],
        outputDir: "web/snapshots",
        outputDirClean: true,
        selector: ".navbar-header",
        timeout: 10000
    }, function(err, snapshotsCompleted) {
        var fs = require('fs');
        fs.rename('web/snapshots/#!', 'web/snapshots/views', function(err) {
            if ( err ) console.log('ERROR: ' + err);
        });
    });
    
  4. すべてがcurlで機能することを確認し、ターミナルに入力します

    curl http://aisel.dev/ \?_escaped_fragment_\=/page/about-aisel/ これにより、スナップショットの内容が表示されるはずです .../www/aisel.dev/public/web/snapshots/views/page/about-aisel /index.html

グーグルや他のクローラーへのディレクティブについてはいけません。アプリの head に meta ルールを含める必要があります。

    <meta name="fragment" content="!">

Google の完全な条件はこちら: https://developers.google.com/webmasters/ajax-crawling/docs/specification

于 2014-04-29T10:49:34.267 に答える