web-dev-qa-db-fra.com

Travailleurs Web gérant AJAX appels - optimisation excessive?

Je travaille avec un code qui gère toutes les requêtes AJAX en utilisant Web Workers (si disponible). Ces travailleurs ne font presque rien de plus que XMLHttpRequest la gestion des objets (pas de calculs supplémentaires). Toutes les demandes créées par les travailleurs sont asynchrones (request.open("get",url,true)).

Récemment, j'ai eu quelques problèmes concernant ce code et j'ai commencé à me demander si je devais passer du temps à le réparer ou simplement vider la solution entière.

Jusqu'à présent, mes recherches suggèrent que ce code peut effectivement nuire aux performances. Cependant, je n'ai pu trouver aucune source crédible soutenant cela. Mes deux seules conclusions sont:

  • 2 ans suggestion de fonctionnalité jQuery pour utiliser les travailleurs Web pour les appels AJAX
  • this SO question qui semble poser des questions sur quelque chose d'un peu différent (en utilisant des requêtes synchrones dans les travailleurs Web vs AJAX)

Quelqu'un peut-il m'indiquer une source fiable discutant de cette question? Ou, existe-t-il des repères qui pourraient dissiper mes doutes?

[ [~ # ~] modifier [~ # ~] ] Cette question devient un peu plus intéressante lorsque WebWorker est également responsable de l'analyse du résultat (JSON.parse). L'analyse asynchrone améliore-t-elle les performances?

43
Konrad Dzwinel

J'ai créé un référence appropriée pour cela sur jsperf . Selon le navigateur, l'approche WebWorker est 85-95% plus lente qu'un appel ajax brut.


Remarques:

  • comme le temps de réponse du réseau peut être différent pour chaque demande, je teste uniquement new XMLHttpRequest() et JSON.parse(jsonString);. Il n'y a pas réel AJAX appels en cours.
  • Les opérations de configuration et de démontage de WebWorker ne sont pas mesurées
  • notez que je teste une seule demande, les résultats pour l'approche webworker peuvent être meilleurs pour plusieurs demandes simultanées
  • Calvin Metcalf m'a expliqué que comparer la synchronisation et l'async sur jsperf ne donnerait pas de résultats précis et il a créé ne autre référence qui élimine la surcharge asynchrone. Les résultats montrent toujours que l'approche WebWorker est beaucoup plus lente.
  • De la discussion Reddit J'ai appris que les données transmises entre la page principale et WebWorker sont copiées et doivent être sérialisées dans le processus. Par conséquent, l'utilisation de WebWorker pour l'analyse uniquement n'a pas beaucoup de sens, les données devront être sérialisées et désérialisées de toute façon avant de pouvoir les utiliser sur la page principale.
26
Konrad Dzwinel

La première chose à retenir est que les travailleurs Web accélèrent rarement les choses dans le sens de prendre moins de temps, ils accélèrent les choses dans le sens où ils déchargent le calcul sur un thread d'arrière-plan afin que le traitement lié à l'interaction avec l'utilisateur ne soit pas bloqué. Par exemple, lorsque vous prenez en compte le transfert des données, faire un calcul énorme peut prendre 8 secondes au lieu de 4. Mais si cela était fait sur le thread principal, la page entière serait gelée pendant 4 secondes, ce qui est probablement inacceptable.

Dans cet esprit, déplacer uniquement les appels ajax hors du thread principal ne vous rapportera rien car les appels ajax ne sont pas bloquants. Mais si vous devez analyser JSON ou mieux, extraire un petit sous-ensemble d'une grande demande, un travailleur Web peut vous aider.

Une mise en garde que j'ai entendu mais non confirmée est que les travailleurs utilisent un cache différent de la page principale de sorte que si les mêmes ressources sont chargées dans le thread principal et le travailleur, cela pourrait entraîner une grande duplication des efforts.

16
Calvin

Vous optimisez votre code au mauvais endroit.

Les requêtes AJAX s'exécutent déjà dans un thread séparé et retournent à la boucle d'événement principale une fois qu'elles sont satisfaites (et appellent la fonction de rappel définie).

Les travailleurs Web sont une interface pour les threads, destinés aux opérations coûteuses en calcul. Tout comme dans les applications de bureau classiques lorsque vous ne voulez pas bloquer l'interface avec des calculs qui prennent beaucoup de temps.

6
Radu Potop

Asynchrone IO est un concept important de Javascript.

Tout d'abord, votre demande est déjà asynchrone, le IO est non bloquant et pendant votre demande, vous pouvez exécuter n'importe quel autre code Javascript. L'exécution du rappel dans un travailleur est beaucoup plus intéressante que la demande.

Deuxièmement, les moteurs Javascript exécutent tout le code dans le même thread , si vous créez de nouveaux threads, vous devez gérer la communication de données avec le message de travail api (voir Sémaphore ).

En conclusion, la nature asynchrone et à un seul thread de JavaScript est puissante, utilisez-la autant que possible et ne créez des travailleurs que si vous en avez vraiment besoin, par exemple dans un long processus Javascript.

3
jsan

D'après mon expérience, les travailleurs Web ne devraient pas être utilisés pour AJAX appels. Tout d'abord, ils sont asynchrones, ce qui signifie le code s'exécutera toujours pendant que vous attendez le retour des informations.

Maintenant, utiliser un travailleur pour gérer la réponse est certainement quelque chose pour lequel vous pouvez utiliser le Web Worker. Quelques exemples:

  • Analyser la réponse pour construire un grand modèle
  • Calcul de grandes quantités de données à partir de la réponse
  • Utiliser un Worker Web partagé avec un moteur de modèle en conjonction avec la réponse AJAX pour construire le code HTML qui sera ensuite renvoyé pour être ajouté au DOM.

Edit: une autre bonne lecture serait: Opinion sur les requêtes synchrones chez les travailleurs du web

1
transformerTroy