2017-02-06 2 views
1

Ich habe eine Anwendung mit mehreren Modulen, die gerendert werden müssen, sobald sie fertig geladen haben. Die Idee ist, dass jedes Modul seine dedizierte Renderfunktion unabhängig von den Zuständen anderer Module ausführt.Rendern jedes Modul separat nach dem Laden

Hier ist die Implementierung des Hauptmoduls:

;(function(doc, win, undefined) { 
    'use strict'; 

    define(['module', 'domReady!'], function(main) { 
     var modules = main.config().modules; 
     while (modules.length) { 
     require([].concat(modules.shift()), function(module) { 
      module.init(); 
     }); 
     } 
    }); 

}(document, window)); 

Es scheint, dass trotz der Tatsache, dass jedes Modul richtig machen soll, nachdem es geladen worden ist, nichts auf dem Bildschirm angezeigt wird, bevor alle Module fertig geladen haben. Dies führt zu Verzögerungen beim Eingeben der App und gibt keinen Hinweis darauf, dass die App gestartet wurde. Was könnte diese Art von Verhalten verursachen und wie kann man die Initialisierung der App so reibungslos wie möglich gestalten?

Antwort

1

Es ist nicht Teil der AMD-Semantik, den gewünschten Effekt zu bieten. Die einzige Garantie, die Sie haben, besteht darin, dass der Rückruf, den Sie an require übergeben, nicht ausgeführt wird, bis die Module, die in dem Abhängigkeitsfeld aufgelistet werden, das zu dem Rückruf gehört, und ihre Abhängigkeiten geladen werden.

RequireJS hat keine genaue Kontrolle darüber, wie der Browser die Anforderungen an den Server sendet. Zum Beispiel, wenn es so passiert, dass der Browser bereits zu viele Anfragen anhängig ist (für Stylesheets, Bilder oder andere Dinge, die er neben den Modulen laden muss, die Sie über require angefordert haben) kann beschließen, die RequireJS-Anfragen zu verschieben, bis die früheren Anfragen gelöst sind.

Wie die Anfragen auf dem Serverende gelöst werden, beeinflusst auch, was in welcher Reihenfolge passieren wird.

Dann gibt es die Struktur Ihrer Anwendung. Angenommen, main.config().modules enthält ['A', 'B', 'C']. So wollen Sie A, B, C in Reihenfolge laden und sie so schnell wie möglich initialisieren lassen. Es stellt sich jedoch heraus, dass alle diese Module auch jquery abhängen. Wenn RequireJS A ausführt, wird define(['jquery], function ($) {... ausgeführt. Okay, jetzt muss jquery abgerufen werden. Zu der Zeit jquery wurde abgerufen, die Wahrscheinlichkeit ist, dass B und C werden auch darauf warten. Daher führt RequireJS A, B, C und die Rückrufe, die auf sie warten, nacheinander aus. Mit nur einer Abhängigkeit ist es vielleicht keine große Sache, aber wenn Ihre Module von einer Menge anderer gebräuchlicher Module abhängen, summiert sich dies und das Endergebnis ist, dass Sie eine merkliche Wartezeit bekommen, während die gemeinsamen Module geladen werden und dann wie A aussieht , B, C in einem Batch ausführen.

Es ist möglich, mit dem RequireJS-eigenen Optimierer oder einem anderen Optimierer, der AMD-Module versteht, zu versuchen, Ihre Module zu Bündeln zu kombinieren, die das gesuchte Ergebnis begünstigen. Um diese Art der Optimierung zu erreichen, muss ein Entwickler die Struktur der Anwendung sorgfältig analysieren. Im Allgemeinen gibt es kein einzelnes Flag, keine Option oder kein Plugin, das Sie einfach einschalten können, um das gewünschte Ergebnis zu erhalten. Außerdem, wie oben erwähnt, arbeiten Browser und Server möglicherweise so, dass alles kaputt geht.


Eine Sache, die ich der Vollständigkeit halber erwähnen sollte. Sie können eine sequentielle Initialisierung erzwingen, aber ein Modul anfordert erst nach dem vorherigen geladen ist:

;(function(doc, win, undefined) { 
    'use strict'; 

    define(['module', 'domReady!'], function(main) { 
     var modules = main.config().modules; 
     function next() { 
     var name = modules.shift(); 
     if (name === undefined) { 
      return; 
     } 

     require([name], function (module) { 
      // When one module has loaded, we initiate the request for the 
      // next one. 
      next(); 

      // And init what we've got now. 
      module.init(); 
     }); 
     } 

     next(); 
    }); 
}(document, window)); 

jedoch hier die Kosten ist, dass B nur angefordert wird nach A geladen ist, usw.Während in Ihrem ursprünglichen Code alle Module sofort angefordert werden. Dies kann zu einer Gesamtinitialisierungszeit führen, die länger ist.

+0

Vielen Dank für eine sehr tiefe Antwort! Vor der Verwendung der RequireJS-Bibliothek in meiner Anwendung waren die Ladezeiten tatsächlich besser, zumindest mit einer relativ schnellen Download-Geschwindigkeit. Der Hauptgrund, warum ich RequireJS verwendet habe, war sicherzustellen, dass meine App in der Zukunft bei wachsendem Wachstum gewartet werden kann (besonders wenn die Anzahl der Abhängigkeiten und Module höher wird). Ich denke, mein Hauptziel ist es, die Verzögerung zwischen dem Abrufen der Hauptabhängigkeiten und dem Starten der Initialisierung der Module zu verringern. Zumindest um mein "Laden" Modul laden und schnell initialisieren zu können und damit die Benutzererfahrung zu verbessern. –

Verwandte Themen