Laden...

[erledigt] Ajax Update Traffic minimize

Erstellt von Diräkt vor 11 Jahren Letzter Beitrag vor 11 Jahren 1.493 Views
D
Diräkt Themenstarter:in
615 Beiträge seit 2009
vor 11 Jahren
[erledigt] Ajax Update Traffic minimize

Hallo

Verwendete Technologien:

=> ASP WebForms
=> Jquery
=> EF
=> Ajax

Scenario:

Ich habe UserControls, diese werden zuerst serverseitig erstellt und gerendert. Danach werden diese alle 3 Sekunden updated, etwa so :


window.setInterval(update, 10000);

function update()
{
  PageMethods.GetList(onsuccess);

  function onsuccess(data)
  {
     $('#' + data[i].ClientInformation.TitleTextClientId).text(data[i].TitleText);
  }
}

Das funktioniert auch wunderbar nur :

=>1. Wie kann ich nur die veränderten Eigenschaften updaten, um den Post zu minimieren ?
=>2. Gibt es eine sinvollere Möglichkeit also meine Überlegung zu Punkt 1 ?

( 1.

Überlegung :
=> Ich cache das Entity und gebe dieses dem BL mit. Dieser vergleicht auf "veränderte Properties" und gibt nur dieses zurück, die andern mit dem Wert NULL. ( nicht veränderten )

=> Problem bei der Überlegung:
Die Daten gehen dennoch an den Client ( {TitleText=null;....}
Wie kann ich den Traffic minimieren ?
)

( 2.

Muss ich jetzt wirklich eine Art eigenes Protokoll (oder Parser) schreiben, um den Traffic zu minimieren ? Das ich im Request z.B. erhalte : "T="Title", und ich dann weiss T = TitleText ?!

)

Herzlichen Dank für Anregungen und Ideen

Beste Grüsse

Diräkt

16.807 Beiträge seit 2008
vor 11 Jahren

Das Problem ist, dass Du hier mehr oder weniger auch in den ViewState von WebForms eingreifst.
WebForms war bislang nicht wirklich auf RIAs ausgelegt. Es konnten zwar durch das UpdatePanel ganze Sektionen ausgetauscht werden; auf die Kommunikation mit Json war aber am Anfang nicht gedacht worden.

WebForms hatte zwei große Ziele

  • Daten-getriebene Anwendungen zu erreiche, zum Beispiel Sharepoint
  • Windows Forms Entwickler einen leichteren Einstieg in die Web-Welt zu schaffen.
    Aber es war eben niemals auf irgendeine Einsparung von Traffic fokussiert!

Daher kam dann 2007 auch MVC auf den Markt, da die Nachteile gegenüber anderen Technologien, wie J2EE und Co immer mehr zum Vorschein kamen.

MVC ist im Gegensatz zu WebForms kein Event-basierendes System, sondern ein Request-basierendes System. Der Fokus von Performance, klarer Stuktur und dem Einhalten der Web-Prinzipien war von Anfang vorhanden.

  • Es gibt keinen ViewState, der unnötig Overhead erzeugt
  • Ajax ist sehr sehr leicht umzusetzen
  • Direkte Integration von Json, um Traffic (u.a. auch für mobile Clients) zu sparen
    Aus meiner Sicht hast Du also - jedenfalls in diesem Bezug - die falsche Technologie gewählt.

WebForms hat mit dem Update auf 4.0 es doch auch tatsächlich geschafft, dass es HTML5 unterstützt. Viele hatten nicht mehr dran geglaubt.
Trotzdem musst Du mit einer Tatsache leben:
In WebForms passiert vieles automatisch und versteckt sich hier Magic-Code. In MVC hast Du die volle Kontrolle bis ins kleinste Detail.

Nun doch noch zu Deinem Problem:
Einzelne Eigenschaften zu verändern ist bei MVC quasi insgesamt ein 10 Zeiler.
Bei WebForms hingegen musst Du - wenn Du Pech hast - eine extra aspx-Seite erstellen, die den Ajax-Request beantwortet. Zudem musst Du aufpassen, dass der ViewState nicht ungültig wird - und für für jede Eigenschaft einzeln!

Zu Deinem zweiten Problem: das effizienteste Format heißt Json.
Das wirst Du wohl suchen und bislang noch nicht kennen. Zaubern kann aber auch das nicht.

D
Diräkt Themenstarter:in
615 Beiträge seit 2009
vor 11 Jahren

Hallo Abt

Danke für Deine Antwort.

Ich bekomme die Daten als JSON, das Problem aber ist dabei auch folgendes:

TitleTextValue = "1";
TitleTextValue = null;

{TitleTextValue:1;} 
{TitleTextValue:;}

Wie man sieht benötigt der Variablen-Namen einiges mehr an bytes als der Wert. Selbst wenn der Wert nicht vorhanden ist, wird das Property mitgegeben.

Eigentlich geht es mir ja nur darum, diesen "overhead" irgendwie einsparen zu können.

Gibts dafür eine Lösung ?

Beste Grüsse

Diräkt

16.807 Beiträge seit 2008
vor 11 Jahren

Ganz ehrlich: Du kümmerst Dich um den Overhead von Json und verwendest ASP.NET WebForms.
Das wär wie wenn Du einen schwerfälligen, 100 Jahre alten Golf fährst und dann mäckerst, dass er mehr als 2 Liter Sprit auf 100KM braucht und aus allen Löchern pfeifft 😉

Die sparsammere Variante von Json wäre Bson; quasi als Binary.
Verwendet die MongoDB zur Datenhaltung. Eher unüblich weil unnötig hier.

Effektiver als Dein Wunsch wäre hier das Aktivieren der dynamischen Komprimierung vom IIS. Dann wird Dein Request in ein GZip gepackt und ist nur noch 1/20stel so groß.

Lad Dir mal Chrome oder Firefox zusammen mit Firebug und dem PageSpeed Addin von Google.
Dann siehste, wo bei Dir wirklich deutlich mehr rausholen lässt als im Json.


Wenn es Dir nur um den einen Wert geht: wieso antwortest Du als Result dann überhaupt mit Json statt direkt mit dem Wert?

D
Diräkt Themenstarter:in
615 Beiträge seit 2009
vor 11 Jahren

Hallo Abt

Danke für Deine Antwort.

Ich habe den Overhead wirklich nur im Response. Der Rest wird ja nur einmal geladen. Ob es hier ein paar bytes mehr oder weniger sind, ist nicht match-entscheidend.

Wenn die spezifische Seite jedoch 24/7 läuft, und alle 3 Sekunden ein Update erfährt, spielen die paar bytes (des Respones) eine entscheidende Rolle...

Es geht darum, das sehr viele Werte updated werden müssen. Als Veranschaulichung, wenn ich 4 Controls auf der Page habe (in real sind es im Schnitt etwa 20), sieht die Response etwa so aus :


{"d":[{"__type":"WebControls.SharedClasses.AdGroupDockingItem","Id":1,"TilePositionId":0,"Title":"Activity Group","MemberText":"Members","AlarmText":"Alarm","AvailableText":"Availabel","OccupiedText":"Occupied","ProductiveText":"Productive","MembersValue":"12","AlarmValue":"11","AvailableValue":"11","OccupiedValue":"16","ProductionValue":"14","OPercent":1,"CPercent":10,"Signal":"efefef","DockPosition":"","ClientInformation":{"OeeValueClientId":"1_C_ctl01_lblOPct","CapacityValueClientId":"1_C_ctl01_lblCpct","TitleTextClientId":"1_C_ctl01_lblTitle","MembersValueClientId":"1_C_ctl01_lblMembersValue","AvailableValueClientId":"1_C_ctl01_lblAvailableValue","OccupiedValueClientId":"1_C_ctl01_lblOccupiedValue","SignalColorClientId":"1_C_ctl01_signal","GaugeOeeClientId":"1_C_ctl01_RadLinearGauge2","GaugeCapacityClientId":"1_C_ctl01_RadLinearGauge1","ProductionValueClientId":"1_C_ctl01_lblProductiveValue","WidgetClientId":"1_C_ctl00"}},{"__type":"WebControls.SharedClasses.AdGroupDockingItem","Id":2,"TilePositionId":0,"Title":"Activity Group","MemberText":"Members","AlarmText":"Alarm","AvailableText":"Availabel","OccupiedText":"Occupied","ProductiveText":"Productive","MembersValue":"11","AlarmValue":"112","AvailableValue":"113","OccupiedValue":"614","ProductionValue":"915","OPercent":1,"CPercent":6,"Signal":"dedede","DockPosition":"","ClientInformation":{"OeeValueClientId":"2_C_ctl01_lblOPct","CapacityValueClientId":"2_C_ctl01_lblCpct","TitleTextClientId":"2_C_ctl01_lblTitle","MembersValueClientId":"2_C_ctl01_lblMembersValue","AvailableValueClientId":"2_C_ctl01_lblAvailableValue","OccupiedValueClientId":"2_C_ctl01_lblOccupiedValue","SignalColorClientId":"2_C_ctl01_signal","GaugeOeeClientId":"2_C_ctl01_RadLinearGauge2","GaugeCapacityClientId":"2_C_ctl01_RadLinearGauge1","ProductionValueClientId":"2_C_ctl01_lblProductiveValue","WidgetClientId":"2_C_ctl00"}},{"__type":"WebControls.SharedClasses.AdGroupDockingItem","Id":3,"TilePositionId":0,"Title":"Activity Group","MemberText":"Members","AlarmText":"Alarm","AvailableText":"Availabel","OccupiedText":"Occupied","ProductiveText":"Productive","MembersValue":"172","AlarmValue":"171","AvailableValue":"100","OccupiedValue":"176","ProductionValue":"174","OPercent":90,"CPercent":2,"Signal":"ababab","DockPosition":"","ClientInformation":{"OeeValueClientId":"3_C_ctl01_lblOPct","CapacityValueClientId":"3_C_ctl01_lblCpct","TitleTextClientId":"3_C_ctl01_lblTitle","MembersValueClientId":"3_C_ctl01_lblMembersValue","AvailableValueClientId":"3_C_ctl01_lblAvailableValue","OccupiedValueClientId":"3_C_ctl01_lblOccupiedValue","SignalColorClientId":"3_C_ctl01_signal","GaugeOeeClientId":"3_C_ctl01_RadLinearGauge2","GaugeCapacityClientId":"3_C_ctl01_RadLinearGauge1","ProductionValueClientId":"3_C_ctl01_lblProductiveValue","WidgetClientId":"3_C_ctl00"}},{"__type":"WebControls.SharedClasses.AdGroupDockingItem","Id":4,"TilePositionId":0,"Title":"Activity Group","MemberText":"Members","AlarmText":"Alarm","AvailableText":"Availabel","OccupiedText":"Occupied","ProductiveText":"Productive","MembersValue":"1112","AlarmValue":"1111","AvailableValue":"1101","OccupiedValue":"1161","ProductionValue":"1141","OPercent":51,"CPercent":49,"Signal":"fff","DockPosition":"","ClientInformation":{"OeeValueClientId":"4_C_ctl01_lblOPct","CapacityValueClientId":"4_C_ctl01_lblCpct","TitleTextClientId":"4_C_ctl01_lblTitle","MembersValueClientId":"4_C_ctl01_lblMembersValue","AvailableValueClientId":"4_C_ctl01_lblAvailableValue","OccupiedValueClientId":"4_C_ctl01_lblOccupiedValue","SignalColorClientId":"4_C_ctl01_signal","GaugeOeeClientId":"4_C_ctl01_RadLinearGauge2","GaugeCapacityClientId":"4_C_ctl01_RadLinearGauge1","ProductionValueClientId":"4_C_ctl01_lblProductiveValue","WidgetClientId":"4_C_ctl00"}}]}

Daher die Frage, wie ich dies optimiere.

=> das Aktivieren der dynamischen Komprimierung vom IIS.

Ok werde ich gleich testen ! Danke !

Dann blieben noch die Fragen :
=> Kann ich ein Wert "NULL" setzen und dieser wird dann GAR NICHT in JSON serialisiert?
=> Kann ich die VariablenNamen irgendwie "einfach" drastisch kürzen, (nur für die Übertragung)

Beste Grüsse

Diräkt

16.807 Beiträge seit 2008
vor 11 Jahren

Du kannst ja Dein Json zusammen stellen oder kürzen wie Du lustig bist - außer wenns nen WebForms-Automatismus is oder Du WebForms-Variablen verwendest; dann kannst Du hier nichts kürzen.
Musst halt dafür sorgen, dass es korrekt interpretiert wird.
Dafür isses wie gesagt nicht ausgelegt. In MVC verwende ich aber durchaus eine Kürzung; hier kann ich den Code oder ein Mapping ja so gestalten, wie ich will.

D
Diräkt Themenstarter:in
615 Beiträge seit 2009
vor 11 Jahren

Danke Abt für Deine Antwort.

Letzte Nachfrage :

=> Gibts eine Möglichkeit die Kürzung per Attribute zu lösen ?
(damit es dann automatisch wieder gemappt wird)

sowas in dieser Art:

public class X
{

[Json-Attribute:A]
public string Abcdefgh{get;set;}

}

Beste Grüsse

Diräkt

16.807 Beiträge seit 2008
vor 11 Jahren

Keine Ahnung; ich verwende die Json-Serializer aus .NET nicht, da sie unheimlich langsam sind.
Ich verwende Newtonsoft.Json - ohne irgendwelche Attribute.
Schön per Hand und schön dokumentiert - ohne Magie.

D
Diräkt Themenstarter:in
615 Beiträge seit 2009
vor 11 Jahren

Hallo Abt

Perfekt! Danke für den Tipp !

Null Value ignore:

string ignored = JsonConvert.SerializeObject(movie,Formatting.Indented,new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });

"Custom Mapping"
[JsonProperty("name")]
public string Name { get; set; }

Scheint als würde alles abgedeckt werden !!!

Danke !

Beste Grüsse

Diräkt