4

ピンタレストに似たフィードを持つサイトがあり、jquery スープをより構造化されたものにリファクタリングすることを計画しています。最も可能性の高い 2 つの候補は、AngularJS と Backbone+Marionette です。このサイトはユーザーが作成し、ほとんどが消費志向 (典型的な 90/9/1 ルール) であり、ユーザーは投稿にいいね、ブックマーク、コメントを付けることができます。フィードからライトボックスを開き、ピンタレストと同様に、コメント、関連する投稿を含む投稿の詳細を表示します。

私たちは散発的にバックボーンを使用しており、そのアイデアには精通していますが、ボイラープレートによって延期されました。Marionette はその点で大いに役立つと思いますが、長期的に役立つのであれば、方向性をもっと根本的に (Angular などに) 変更することにもオープンです。

要求事項:

  • SEO の理由から、最初のページは静的でなければなりません。フレームワークが既存のコンテンツから開始できることが重要です。
  • ライトボックスに必要なデータを既にフィードにロードして、トランジションを高速化できるようにしたいと考えています。一部のデータ (タイトル、説明、写真、いいね! の数/ブックマークの数、コメントの数) は既に存在しますが、詳細ビュー用に読み込まれる追加のデータがあります - コメント、類似の投稿、これが好きな人などです。
  • フィードまたは詳細ライトボックスで発生した投稿への変更は、ほとんど作業なしで他の投稿に反映されるはずです (たとえば、フィードから気に入った場合、ライトボックスに移動すると、いいね! と新しいいいね! の数が表示されるはずです。または、反対。)
  • モバイル サイト (現在は Sencha Touch にあります) を移行して、共通部分に同じコード ベースを使用し、モバイル サイトとメイン サイト間でより緊密な機能パリティを実現したいと考えています。

Angular に関する私の懸念に関連するこれらの要件:

1)テンプレートの追加ページを介してレンダリングしている間、最初のページの読み込みを静的にすることは可能ですか/問題がありますか。

2) ページのさまざまな部分に複数のデータソースを使用することは問題がありますか? たとえば、メインの投稿部分は、埋め込まれた json データとフィードの「もっと見る」から取得されますが、追加の詳細は別の ajax 呼び出しから取得されます。

3) 双方向バインディングはクールですが、レンダリングされるアイテムの数が原因で、このケースではマイナスになるのではないかと心配しています。双方向バインディングが必要な要素の数は比較的少ないです。次のような投稿:

私たちのユースケースについて心配してください。それぞれに 1 ~ 2 ダースの詳細を含む何百もの投稿を簡単に作成できます。変更されないことがわかっているフィールド/要素がある場合、双方向バインディングを「無効」にすることはできますか?

ビューポートの外側の要素を同じメモリにアンロードすることは正常/可能ですか? これは、メモリがさらに懸念されるため、モバイルの方向にも関連しています。

AngularJS は私たちのユースケースでうまく機能しますか? ここで役立つトリック/ヒントはありますか?

4

2 に答える 2

18

「無限スクロール」とか、入れたまま送りとか色々な方法があります。どちらを選択するかは、ユーザーのニーズと許容される応答ペイロードのサイズによって決まります。

ここにあるように、パフォーマンスを満たすところでユーザビリティを犠牲にします。

1. アセットを追加する

このメソッドは、ユーザーが現在のスクロールの高さの一番下に到達すると、別の API 呼び出しが行われ、「さらに多くのコンテンツをスタックする」という従来の末尾への追加アプローチです。これには、クロスデバイスの警告を処理するための最も効果的なソリューションであるという利点があります。

あなたが述べたように、このソリューションの欠点は、ユーザーがコンテンツを不注意にスクロールすると、大きなペイロードがメモリをあふれさせることにあります。スロットルはありません。

<div infinite-scroll='getMore()' infinite-scroll-distance='0'>
  <ul>
    <li ng-repeate="item in items">
      {{item}}
    </li>
  </ul>
</div>

var page = 1;
$scope.getMore() = function(){ 
 $scope.items.push(API.returnData(i));
 page++;
}

2.スロットルでアセットを追加する

ここでは、無限に追加されるフィードでより多くの結果をユーザーが表示し続けることができることを提案していますが、より多くのデータの呼び出しを調整するか、「手動で」呼び出す必要があります。これは、ユーザーがスクロールして返されるコンテンツのサイズに比べて扱いにくくなります。

ペイロードごとに返されるコンテンツが多い場合、ユーザーは「もっと見る」ボタンをクリックする必要が少なくなります。もちろん、これはより大きなペイロードを返すというトレードオフです。

<div>
  <ul>
    <li ng-repeate="item in items">
      {{item}}
    </li>
  </ul>
</div>
<div ng-click='getMore()'>
  Get More!
</div>

var page = 1;
$scope.getMore() = function(){
  $scope.items.push(API.returnData(i));
  page++;
}

3. 仮想スクロール

これは、無限スクロールの最後の最も興味深い方法です。アイデアは、結果の範囲のレンダリングされたバージョンのみをブラウザーのメモリに保存するということです。つまり、複雑な DOM 操作は、構成で指定された現在の範囲に対してのみ作用します。ただし、これには独自の落とし穴があります。

最大のものはクロスデバイス互換性です。

ハンドヘルド デバイスにデバイスの幅に達する仮想スクロール ウィンドウがある場合 --- 独自のスクロール バーでこの「フィード」を超えてスクロールすることはできないため、ページの全体の高さよりも小さい方がよいでしょう。スクロールは、フィードを含む実際のページではなく、常に仮想スクロール フィードで動作するため、ページの途中で「立ち往生」します。

次に信頼性です。ユーザーがスクロール バーを手動で低いインデックスから非常に高いインデックスにドラッグすると、ブラウザーにこれらのディレクティブを非常に高速に実行させることになり、テストではブラウザーがクラッシュしました。これは、スクロール バーを非表示にすることで修正できますが、もちろん、ユーザーは非常にすばやくスクロールすることで同じシナリオを呼び出すことができます。

ここにデモがあります

起源

"Initial page must static for SEO reasons. It's important that the framework be able to start with existing content, preferable with little fight."

つまり、コンテンツを提供する前に、ページをサーバー側で事前にレンダリングする必要があるということですか? このアプローチは初期の数千人ではうまく機能していましたが、ほとんどの人がこれをやめてシングル ページ アプリ スタイルに移行しています。正当な理由があります:

  • ユーザーに送信する初期シードは、API データを取得するためのブートストラップとして機能するため、サーバーの作業が大幅に軽減されます。

  • 遅延読み込みアセットと非同期 Web サービス呼び出しにより、認識される読み込み時間が、従来の「最初にサーバー上ですべてをレンダリングしてから、ユーザー アプローチに吐き出す」よりもはるかに速くなります。

  • ページのプリレンダリング/キャッシュ エンジンを使用して Web サーバーの前に配置し、「完全にレンダリングされたバージョン」でのみ Web クローラーに応答することで、SEO を維持できます。この概念はここでよく説明されています。

we would prefer to have the data needed for the lightbox loaded already in feed so that the transition can be faster. Some of the data is already there (title, description, photos, num likes/ num bookmarks,num comments) but there is additional data that would be loaded for the detail view - comments, similar posts, who likes this, etc.

フィードの初期ペイロードに各「フィード ID」の子データ ポイントが含まれておらず、追加の API リクエストを使用してそれらをライトボックスにロードする必要がある場合 --- 正しく行っています。それは完全に合法的なユースケースです。単一の API 呼び出しに 50 ~ 100 ミリ秒かかると主張することになりますが、これはエンド ユーザーには認識できない遅延です。どうしてもフィードに追加のペイロードを送信する必要がある場合は、あまり勝てません。

Changes to the post that happen in the feed or detail lightbox should be reflected in the other with little work (eg, if I like it from the feed, I should see that like and new like count number if I go to the lightbox - or the opposite.)

ここでテクノロジーを混合しています --- いいね ボタンは facebook への API 呼び出しです。これらの変更が同じページの facebook のようなボタンの他​​のインスタンス化に反映されるかどうかは、facebook がそれを処理する方法次第ですが、簡単な Google が役立つと確信しています。

ただし、あなたのウェブサイトに固有のデータ --- いくつかの異なる使用例があります。

  • ライトボックスのタイトルを変更し、現在表示されているフィードに変更を反映させたいとします。「編集アクションの保存」POST がサーバーに送信された場合、成功のコールバックにより、websocket で新しい値の更新がトリガーされる可能性があります。この変更は、自分の画面だけでなく、他のすべての画面にも反映されます。

  • また、双方向のデータ バインディングについて話している可能性もあります (AngularJS はこれに優れています)。双方向のデータ バインディングを使用すると、「モデル」または Web サービスから取得したデータをビュー内の複数の場所にバインドできます。このように、同じモデルを共有しているページの一部を編集すると、他の部分も同時に更新されます。これは HTTP リクエストの前に発生するため、まったく異なる使用例です。

We would like to migrate our mobile site (currently in Sencha Touch) to also use the same code base for the parts that are common so we can have closer feature parity between mobile and main site.

BootstrapFoundationなどの最新のレスポンシブ CSS フレームワークを実際に確認する必要があります。レスポンシブ Web デザインを使用するポイントは、サイトを 1 回作成するだけで、さまざまな画面サイズすべてに対応できることです。

機能のモジュール性について話している場合は、AngularJS が重要です。アイデアは、Web サイトのコンポーネントを別のプロジェクトで使用できるモジュールにエクスポートできるということです。これにはビューも含まれます。また、レスポンシブ フレームワークを使用してビューを作成した場合は、どこでも使用できると思います。

1) Will it be possible/problematic to have initial page loads be static while rending via the templates additional pages.

上で説明したように、この種のアプローチから離れるのが本当に最善です。絶対に必要な場合、テンプレート エンジンは、ペイロードがサーバー側でレンダリングされたか、クライアント側でレンダリングされたかを気にしません。部分的なページへのリンクも同様にアクセス可能です。

2) is it problematic to have multiple data-sources for different parts of page - eg the main post part comes from embedded json data and from "see more"s in the feed while the additional detail would come from a different ajax call.

繰り返しますが、これはまさに業界が移行しようとしているものです。すべての外部 API データをフェッチする初期静的ブートストラップを使用して、「認識された」および「実際の」読み込み時間を節約できます --- これにより、完全に独立したピースの懸念を分離しているため、開発サイクルも大幅に短縮されます。API はビューを気にする必要があり、ビューは API を気にする必要があります。アイデアは、API とフロント エンド コードの両方を、より小さなピースに分割することでモジュール化/再利用可能にすることができるということです。

3) While the two-way binding is cool - I'm concerned it might be a negative in our case because of the number of items being rendered. The number of elements that we need two-way binding is relatively small.

また、この質問とあなたが下に残したコメントを組み合わせます。

Thanks for the answer! Can you clarify - it seems that 1) and 2) just deal with how you would implement infinite scrolling, not the performance issues that might come from such an implementation. It seems that 3 addresses the problem in a way similar to recent versions of Sencha Touch, which could be a good solution

遭遇するパフォーマンスの問題は完全に主観的なものです。スロットリングなどのパフォーマンスに関する考慮事項をディスカッションにまとめようとしました。スロットリングを使用すると、サーバーが受けるストレスの量と、ユーザーのブラウザーが DOM に追加された新しい結果セットごとに実行する必要がある作業を大幅に削減できるからです。

無限スクロールは、しばらくすると、ユーザーのブラウザ メモリを消費します。私があなたに言えることは避けられませんが、テストを通してのみ、あなたはどれだけ伝えることができます. 私の経験では、ユーザーのブラウザーは大量の悪用を処理できると言えますが、繰り返しますが、各結果セットのペイロードの大きさと、すべての結果に対して実行しているディレクティブは完全に主観的です。説明したオプション 3 の範囲データ セットでのみレンダリングするソリューションもありますが、それらにも制限があります。

返される API データのサイズは 1 ~ 2kbs を超えてはならず、クエリを返すのに約 50 ~ 200 ミリ秒しかかからないはずです。これらの速度を満たしていない場合は、クエリを再評価するか、子 ID を使用して他のエンドポイントに詳細をクエリして、返される結果セットのサイズを削減する時期かもしれません。

于 2013-06-25T16:27:50.340 に答える