1

環境

インターネットにアクセスできない無線 LAN で、同期された HTML5 スライドショーを約 50 人の観客に見せるためのアプリケーションを作成しています。

コンピューターの 1 つで Node.js サーバーを実行し、Socket.IO 経由で 50 のクライアントに接続します (ちなみに、そのうちの 1 つだけがプレゼンテーションを制御します)。

ハードウェアは、国内のワイヤレス 802.11b/g ルーターと 50 台のモバイル デバイス (タブレット、ネットブック、スマートフォン) です。

問題

スライドショーが開始されると、ルータがすべてのクライアントに同時に完全なスライドショーを送信する必要があるため、クライアントがスライドショーを見るのに時間がかかりすぎます (5 MB のスライドショーの場合、約 10 分以上)。

スライドショーの外観

<html>
  <head>
    <title>My Slideshow</title>
    <script src="javascripts/slidesplayer.js"></script>
    <link rel="stylesheet" href="/stylesheets/style.css">
  </head>

  <body>    
    <div id="slides-containter">

      <div class="slide" id="slide_1">
        <!--Contents such as images, text, video and audio sources -->
      </div>

      <div class="slide" id="slide_2">
        <!--Contents -->
      </div>

      <!--A bunch of slides here-->

    </div>
    <script>
      // Here I load the slides
    </script>
  </body>
</html>

やりたいこと

slides-container最初は、完全に空の要素をロードしたいと思います。

次に、スライドショーを進めながら、サーバーから次のスライドを表す GETを取得し、それを DOM に追加して、それが完了したときにのみdivクライアントが写真やその他のもののダウンロードを開始するようにします。そのスライド(したがって、ネットワークの過負荷が大幅に減少します)。

もう 1 つの関連する事実は、スライド ショー (を含むslidesplayer.js) は、PowerPoint プレゼンテーションをこの HTML5 形式に解析する外部ソフトウェアから自動的に生成され、PowerPoint で既に作成されている多くのプレゼンテーションを使用することです。

div.slide私の最初の印象は、jQuery-ajax を使用してこれを達成する必要があるということですが、私の考えは要素を別々のファイルにコピーするだけなので、良い方法でそれを行う方法が正確にはわかりません。

更新: この回答は、表示する前に DOM 操作に jQuery を使用することを提案しています。jQuery は、現在の DOM に挿入されていなくても、DOM オブジェクトを操作するたびにリソースを要求しているようです。したがって、考えられる解決策の 1 つは、文字列のみで動作することです。この問題の詳細については、thisおよびthis question で確認できます。

4

3 に答える 3

2

1 つの解決策は、これをフロントエンド ソリューションとして扱うことです。フロントエンドは、一度に食べられる量だけを食べるべきです。

これらの 5 MB の大部分を占めているのは、スライドショー マークアップ自体ではなく、外部リソース (画像など) であると想定しています。この場合、DOM は必要になるまでこれらのリソースを呼び出そうとしないでください。

スライド ドキュメント全体を ajax 呼び出しに提供することをお勧めしますが、呼び出されたときに各スライドにマークアップを導入するだけです。このようなもの:

$.ajax('path/to/slides', {
  async:    false,
  complete: function ajaxCallback(slidesDOM){
    // Pull out the individual slides from your slideshow HTML 
    $slides = $(slidesDOM).find('.slide');

    // For each of these...
    $slides.each(function prepareSlide(){
      // Store a reference to the slide's contents
      var $slideContent = $($(this).html());
      // Empty the contents and keep only the slide element itself
      var $slideWrapper = $(this).empty();

      $slideWrapper
        // Put the slide where you want it
        .appendTo('.slidesContainer')
        // And attach some kind of event to it 
        // (depending on how your slideware works, you might want to bind this elsewhere)
        .on('focus', function injectContent(){
          // Put the content in — NOW external resources will load
          $slideWrapper.append($slideContent);

          // Unbind this function trigger
          $slideWrapper.off('focus', injectContent);
        });
    })
  }
});
于 2012-12-21T15:16:16.230 に答える
1

1) You shouldn't be streaming payloads with SocketIO. Socket is made for low-load. If you need to transmit en-masse, I'd recommend using a standard HTTP AJAX request. Then, you can use Socket.IO to control which slide you are on.

2) Try AngularJS. They've basically done all the thinking for you regarding view switching (which is essentially what you are doing). They have a great tutorial, which helps alot.

3) To simplify you Socket calls, I'd recommend using ConversationJS both client and server side.

于 2012-12-21T15:05:02.820 に答える
1

質問で述べたように、DOM 要素を操作すると、そのリソースを使用する要素を DOM に挿入しなくても、ブラウザーはリソースをダウンロードします。

私の場合、私ができる最善の解決策は、少なくともタグに対してある種の遅延読み込みを使用することでした (ただし、やimgなどの他のタグに対しては簡単に拡張できます)。audiovideo

src私がしたことは、属性を別の名前に置き換え(この場合)、すべての img タグにxsrcカスタムの空の属性を追加することでした。src

<img id="someImg" src="#" xsrc="foo.png"></img>

次に、jQuery を使用して、画像をダウンロードする必要があるときsrcはいつでも属性値を変更しました。xsrc

// When I want the image to be downloaded from the server
$('#someImg').attr( 'src' , $('#someImg').attr('xsrc') )

この背後にあるアイデアについては、既に言及した質問 ( thisおよびthis )で詳細を確認できます。

于 2013-01-03T15:36:01.477 に答える