パフォーマンスはUIの重要な機能であるため、問題は非常に深刻です。 たとえば、Amazonでは、わずか0.1秒のページ読み込み遅延により、店舗の売上が1%減少すると推定しています。 Googleによると、0.5秒の遅延は検索クエリの数を20%削減します。
TwitterのRuby / JavaScript開発者Alex MacCaw は、この問題に対する論理的な解決策を提供しています 。Ajaxの原則をフロントエンドだけでなく、ユーザーインターフェイスにも拡張します。 彼は、AUI(非同期ユーザーインターフェイス)と呼ばれるものに適したフレームワークを開発しました。
McCawによると、インターフェースはサーバーが応答するのを待つ必要はありません。これは完全に不必要な遅延を引き起こすからです。 たとえば、このスクリーンショットでインターフェースは何を期待しますか、なぜユーザーアクションをブロックしますか?
結局、手紙はバックグラウンドで静かに送信でき、ユーザーは送信の成功に関するメッセージを待つ必要がありません。 もちろん、 非常に重要な手紙を送り、それが確実に受取人に届いたことを知りたいというまれなケースを除きます。 しかし、実際には、これは信頼性の錯覚です。送信者のサーバーは、宛先が実際にこの手紙を受け取ることを保証できないためです。
何らかの方法で、Gmailインターフェース遅延の例は、ユーザーインターフェースがアクションを許可する前にサーバーからの応答を予期する数百および数千の他のWebアプリケーションに適用されます。
Alex McCawは、 Spine JavaScriptフレームワークを開発しました。 これは、アプリケーションのサーバー側に関係なく、つまり非同期的にUIが機能する概念的に新しいアプローチを実装します。
その結果、UIのパフォーマンスを大幅に向上させることができます。 Alexは、Spine(Rubyのバックエンド)の速度を評価できる単純なWebアプリケーションの例を示します。 Ajax REST呼び出しはバックグラウンドで送信されますが、すべてのアクションは瞬時に行われることに注意してください。
非同期UIを実装するには、3つの基本原則に従う必要があります。
- 状態の転送とクライアント側へのレンダリング
- インテリジェントなデータのプリロード
- 非同期サーバー通信
Page
というモデルを扱ってい
Page
。 コントローラでモデル名を変更すると、次のことが発生します。
page = Page.find(1) page.name = "Hello World" page.save()
save()
が呼び出されるとすぐに、Spineは次のことを行います。
- コールバックを確認し、変更をメモリに保存します
- イベント通知とユーザーインターフェイスの更新を変更する
- 変更メッセージとともにサーバーにAjax PUTリクエストを送信する
Alex McCawはこのような技術を長い間使用してきたため、エラーを回避するためにサーバーとのさまざまな同期を行いました。 たとえば、彼はクライアント側のデータ検証を実装しました。 もちろん、これは常に可能とは限りません(たとえば、属性の一意性を確認するには、データベースへのアクセスが必要です)。 簡単な解決策はありませんので、議論を続けます。 ネットワークエラーに対処する方が簡単です。サーバーにリクエストを送信する前にブラウザーを閉じないようにするには、
window.onbeforeunload
イベントの発生を監視し、未送信のリクエストが残っている場合はユーザーに通知するだけで十分です。
window.onbeforeunload = -> if Spine.Ajax.pending '''Data is still being sent to the server; you may lose unsaved changes if you close the page.'''
同様に、サーバーがエラーを返した場合、これをユーザーに渡すことができます。 このようなエラーは比較的まれにしか発生しないため、特に注意する必要はありません。 ユーザーに通知し、イベントをログに記録して、再度同期するだけで十分です。
サーバーへの要求は、エラーを避けるために厳密に順番にバックグラウンドで送信されます(データを更新する要求が新しい要素を作成する要求よりも早く到着する場合)。
バックボーンの例に従ってAlex McCawが提供するもう1つの手法は、クライアント側での一時的なCIDの生成です。これは、サーバー側で生成された一意のIDの代替です。 このアプローチにより、遅延が解消され、IDを生成する必要があるJavaScript関数の即時応答が維持されます。
Backboneは、さまざまなタイプの識別子に対してさまざまなAPIを使用します。
Users.getByCid(internalID) Users.get(serverID)
この「重複」を取り除くために、Spineは少し異なるアプローチを取ります。 ここでは、実際のIDを持つサーバーからの応答が受信されるまで一時識別子(疑似GUID)が使用され、その後Spineがそれに切り替えますが、両方の識別子は単一のAPIを介してアクセス可能なままです。
場合によっては、AUIの使用が不適切であることは明らかです。 たとえば、金融アプリケーションやインターネットバンキングでは、インターフェイスは資金の動きを正確に反映し、サーバーからの応答を受信する必要があります。 ただし、ほとんどの場合、AUIには従来のAjaxアプリケーションインターフェイスよりも明確な利点があります。