Groups | Search | Server Info | Keyboard shortcuts | Login | Register


Groups > de.comp.lang.javascript > #4814

Re: Gluecksrad

From Thomas 'PointedEars' Lahn <PointedEars@web.de>
Newsgroups de.comp.lang.javascript
Subject Re: Gluecksrad
Date 2016-11-18 21:45 +0100
Organization PointedEars Software (PES)
Message-ID <2780097.5fSG56mABF@PointedEars.de> (permalink)
References (6 earlier) <e803739f-9e3e-96e0-cb70-0209232585e8@arnowelzel.de> <4986933.DvuYhMxLoT@PointedEars.de> <a596fa85-d687-0419-8821-1ba99d147e99@arnowelzel.de> <1763443.oMNUckLgyt@PointedEars.de> <f43cdcfc-2d16-4e03-cd9e-32b99d4ab69e@arnowelzel.de>

Show all headers | View raw


Arno Welzel wrote:

> Thomas 'PointedEars' Lahn schrieb:
>> Arno Welzel wrote:
>>> […] Performanceprobleme erkenne in der *Praxis* ich keine,
>>> selbst wenn die Performanceunterschiede verschiedener Umsetzungen
>>> theoretisch messbar sein mögen.
>> 
>> Je länger man Deine Website anschaut, umso mehr Arbeitsspeicher frisst
>> sie, weil immer mehr davon für immer neue Objekte reserviert werden muss
>> –
>> unnötiger Weise.  Irgendwann wird dann der Tab oder der Browser vom OOM-
>> Killer abgeschossen oder das System hängt.  Das ist nicht nur theoretisch
>> messbar (was BTW ein Widerspruch in sich ist; Messungen sind immer
>> Praxis).
> 
> Aha - und welcher Umgebung soll das sein?

Chromium “53.0.2785.143 Built on 8.6, running on Debian stretch/sid (64-
bit).”  Nach 10 Minuten auf der Website ist der Speicherbedarf des Tabs 
(siehe Chromium Task-Manager, Shift+Esc) um ca. 7.14 MiB angestiegen.  Man 
kann beobachten, wie der Speicherbedarf im 5-Sekunden-Takt von kontinierlich 
ansteigt.  Das korreliert genau mit dem wiederholten überflüssigen Erzeugen 
der XHR-Instanz, wie man in der Spalte “Network” und mit “Profiles”, “Record 
Allocation Timeline” sieht (zuerst steigt der Speicherbedarf, dann gibt es 
die Netzwerkaktivität).

Start:           21:12 CET
Spalte “Memory”: 60'552 KiB

Ende:            21:22 CET
Spalte “Memory”: 67'312 KiB

Das Ergebnis ist zuverlässig (nach “uncached reload”) reproduzierbar.

Und dabei habe ich *nichts* auf der Website oder im Browser gemacht ausser 
gelegentlich zwischen Browser-Task-Manager und Newsreader (nicht im Browser) 
hin- und herzuschalten.

Das Problem gibt es nicht nur auf Deiner Website (sondern besonders 
problematisch auch bei Facebook und Twitter, die auch über XHR den Status 
aktualisieren), aber die Ursache ist dieselbe.  Denn wenn man nichts macht 
oder XHR richtig macht, passiert es nicht.
 
> Hier mit Linux Mint 14 und Firefox 49 lässt sich das nicht reproduzieren.
> Auch nach mehrere Stunden ist der Speicherbedarf nicht angestiegen,

Wie misst Du das?

> der OOM-Killer wird logischerweise auch nicht aktiv und ein
> hängendendes System habe ich ebenfalls nicht.

Du solltest auch nicht davon ausgehen, dass Deine Website die einzige ist, 
die im Browser angezeigt wird.
 
> Eine kurzer Vergleich

Was heisst „kurz“?

> mit Windows 7 und Firefox 49 sowie IE 11 wie auch Firefox unter MacOS hat
> ebenfalls keine Auffälligkeiten gezeigt.

Hast Du nur in Firefox 49 und IE 11 getestet?
 
>> Über den Rest Deiner DAU-dummen Reaktion breiten wir lieber den Mantel
>> des Schweigens.
> 
> Zeige mir, was an der verwendeten switch()-Anweisung konkret *falsch*
> ist oder lass' es.

Ich schrieb „_unnötig bis_ falsch“.  Es hilft Deiner Argumentation nicht, 
wenn Du mich verkürzt wiedergibst.

Weshalb ich das schrieb, dachte ich, sei offensichtlich.

Zur besseren Lesbarkeit habe die Einrückung reduziert und den Quelltext 
lesbarer formatiert (auch etwas, an dem Du noch arbeiten kannst):

| req.onreadystatechange = function () {
|   switch (req.readyState)
|   {
|     case 4:
|       […]
|       break;
| 
|     default:
|       return false;
|       break;     
|   }
| };

Die switch-Anweisung befindet sich *alleinstehend* in einer *Funktion*.

Somit ist die return-Anweisung überflüssig, denn nach der switch-Anweisung 
wird die Funktion ohnehin verlassen:

  req.onreadystatechange = function () {
    switch (req.readyState)
    {
      case 4:
        […]
        break;
  
      default:
        break;     
    }
  };

Schreibt man die return-Anweisung hin, ist die zweite break-Anweisung 
überflüssig, denn die Funktion wird ja schon durch die return-Anweisung 
verlassen:

  req.onreadystatechange = function () {
    switch (req.readyState)
    {
      case 4:
        […]
        break;
  
      default:
        return false;
    }
  };

Es handelt sich ausserdem um einen Event-Listener, der an eine Event-
Handler-Eigenschaft zugewiesen wurde.  Da ist es wesentlich, wie der 
Rückgabewert aussieht, denn ein Rückgabewert kann zur Vermeidung der 
Standardaktion führen (das ist nicht immer “false”, kann auch “true” sein).  
Man sollte also nicht einfach blind einen Wert zurückgeben, weil „das schon 
funktioniert“, sondern sich diesen gut überlegen, und im Zweifelsfall "gar 
nichts" (d. h. “undefined”) zurückgeben:

  req.onreadystatechange = function () {
    switch (req.readyState)
    {
      case 4:
        […]
        break;
  
      default:
        return;
    }
  };

Das ist aber schon das Standardverhalten ohne return-Anweisung:

  req.onreadystatechange = function () {
    switch (req.readyState)
    {
      case 4:
        […]
        break;
  
      default:
    }
  };

Will man die Funktion erweitern, also Anweisungen nach der switch-Anweisung 
hinzufügen, muss man sich daran erinnern, dass da noch eine return-Anweisung 
in der switch-Anweisung steht; solange wundert man sich, weshalb der neue 
Code manchmal nicht ausgeführt wird:

  req.onreadystatechange = function () {
    switch (req.readyState)
    {
      case 4:
        […]
        break;
  
      default:
        return false;
        break;
    }

    /*
     * _Halb_toter Code; kann je nach readyState Probleme verursachen;
     * schlecht testbar.
     */
  };

In der default-Klausel steht kein (sinnvoller) Code, sie kann also 
genausogut weggelassen werden.

  req.onreadystatechange = function () {
    switch (req.readyState)
    {
      case 4:
        […]
        break;
    }
  };

Lässt man die default-Klausel nicht weg, so lässt sich dies weniger 
fehlerträchtig schreiben:

  req.onreadystatechange = function () {
    if (req.readyState == 4)
    {
      // …
    }
    else
    {
      return;
    }

    /*
     * _Halb_toter Code; kann je nach readyState Probleme verursachen;
     * schlecht testbar.
     */
  };

Spätestens jetzt sieht man, dass man den Code stark vereinfachen kann, 
wodurch er weniger fehlerträchtig und leichter wartbar wird:

  req.onreadystatechange = function () {
    if (req.readyState == 4)
    {
      // …
    }

    /*
     * Evtl. Code hier nun nicht mehr tot; gut testbar.
     */
  };

oder (“early return”, “gauntlet“):

  req.onreadystatechange = function () {
    if (req.readyState != 4) return;

    // …

    /*
     * Evtl. Code hier nun nicht mehr tot; gut testbar.
     */
  };

> Und zum Thema "Sicherheit": zeige mir, welches ausnutzbare(!")
> Sicherheitsproblem bei meiner Verwendung von windows.setTimeout()
> übergibt.

Erstens heisst es window.setTimeout().

Zweitens kann der Code, wenn er als String übergeben wird, nur auf global 
verfügbare Symbole zugreifen.  Das ist für sich schon ein Problem, auch ein 
Sicherheitsproblem.  Denn jedes fremde Script, was im Dokument geladen wird, 
kann die Werte im globalen Ausführungskontext manipulieren, also zum 
Beispiel die Funktion überschreiben.  Sogar jede Extension und jedes Plugin 
kann das, weil der globale Kontext an das Tab/Fenster gekoppelt ist.

Drittens ergibt sich das ausnutzbare Sicherheitsproblem dadurch, dass Du als 
Autor nicht Sicherheitsfeatures des Browsers wie Content Security Policy 
nutzen kannst, solange Du den Code als String übergibst (siehe Referenz).

Kein heutzutage sinnvoll scriptbarer Browser erfordert noch die String-
Variante.  Wie aus der ECMAScript Support Matrix hervorgeht (ausnahmsweise, 
weil dieses Feature mit dem Netscape DOM eingeführt wurde, bevor es die 
Trennung zwischen Sprache und DOM gab), wird die Variante mit 
Funktionsausdruck/-referenz spätestens seit Mozilla 1.0 und Internet 
Explorer 5.5 unterstützt.  (Das würdest Du unter anderem wissen, wenn Du 
unter anderem die ES Matrix auch mal *lesen* würdest.)

Durch die String-Variante ergeben sich also gegenüber der Variante mit 
Funktionsausdruck/-referenz *keinerlei* Vorteile und *nur* Nachteile.

> Und ja, die Problematik von eval() ist mir sehr wohl bewusst
> und ja, wenn ich es mal umbaue, werde ich sicher eine andere Lösung
> bevorzugen.

Die Lösung ist trivial; ich hatte sie Dir sogar bereits hingeschrieben.

Somit kann ich nur hoffen, dass ich mit diesem Posting nicht *wieder* meine 
kostbare Freizeit (an Dich) verschwendet habe.

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

Back to de.comp.lang.javascript | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

Gluecksrad Klaus Ketelaer <spam@spambouncer.de> - 2016-11-11 17:19 +0100
  Re: Gluecksrad Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-11-11 19:52 +0100
    Re: Gluecksrad Klaus Ketelaer <spam@spambouncer.de> - 2016-11-12 12:24 +0100
      Re: Gluecksrad Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-11-13 20:49 +0100
  Re: Gluecksrad Arno Welzel <usenet@arnowelzel.de> - 2016-11-14 01:52 +0100
    Re: Gluecksrad Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-11-14 02:25 +0100
      Re: Gluecksrad Arno Welzel <usenet@arnowelzel.de> - 2016-11-14 10:19 +0100
        Re: Gluecksrad Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-11-14 10:57 +0100
          Re: Gluecksrad Arno Welzel <usenet@arnowelzel.de> - 2016-11-15 08:38 +0100
        Re: Gluecksrad Klaus Ketelaer <spam@spambouncer.de> - 2016-11-15 00:41 +0100
  Re: Gluecksrad Klaus Ketelaer <spam@spambouncer.de> - 2016-11-15 17:21 +0100
    Re: Gluecksrad Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-11-15 19:27 +0100
      Re: Gluecksrad Klaus Ketelaer <spam@spambouncer.de> - 2016-11-16 12:13 +0100
        Re: Gluecksrad Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-11-16 12:37 +0100
        Re: Gluecksrad "Christoph M. Becker" <cmbecker69@arcor.de> - 2016-11-16 12:58 +0100
        Re: Gluecksrad Arno Welzel <usenet@arnowelzel.de> - 2016-11-16 16:19 +0100
          Re: Gluecksrad Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-11-16 18:29 +0100
            Re: Gluecksrad Arno Welzel <usenet@arnowelzel.de> - 2016-11-16 19:13 +0100
              Re: Gluecksrad Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-11-16 19:29 +0100
                Re: Gluecksrad Arno Welzel <usenet@arnowelzel.de> - 2016-11-17 20:21 +0100
                Re: Gluecksrad Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-11-18 03:09 +0100
                Re: Gluecksrad Arno Welzel <usenet@arnowelzel.de> - 2016-11-18 17:23 +0100
                Re: Gluecksrad Arno Welzel <usenet@arnowelzel.de> - 2016-11-18 17:40 +0100
                Re: Gluecksrad Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-11-18 17:56 +0100
                Re: Gluecksrad "Christoph M. Becker" <cmbecker69@arcor.de> - 2016-11-18 18:19 +0100
                Re: Gluecksrad Arno Welzel <usenet@arnowelzel.de> - 2016-11-18 19:14 +0100
                Re: Gluecksrad Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-11-18 20:06 +0100
                Re: Gluecksrad Arno Welzel <usenet@arnowelzel.de> - 2016-11-19 10:04 +0100
                Re: Gluecksrad Arno Welzel <usenet@arnowelzel.de> - 2016-11-18 19:06 +0100
                Re: Gluecksrad Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-11-18 20:16 +0100
                Re: Gluecksrad Arno Welzel <usenet@arnowelzel.de> - 2016-11-19 10:22 +0100
                Re: Gluecksrad Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-11-18 21:45 +0100
                Re: Gluecksrad Arno Welzel <usenet@arnowelzel.de> - 2016-11-19 10:38 +0100
                Re: Gluecksrad Arno Welzel <usenet@arnowelzel.de> - 2016-11-19 10:56 +0100
                Re: Gluecksrad Arno Welzel <usenet@arnowelzel.de> - 2016-11-19 11:48 +0100
          Re: Gluecksrad Klaus Ketelaer <spam@spambouncer.de> - 2016-11-22 21:19 +0100
            Re: Gluecksrad Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-11-22 22:13 +0100
              Re: Gluecksrad Klaus Ketelaer <spam@spambouncer.de> - 2016-11-23 01:08 +0100
                Re: Gluecksrad Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-11-23 01:21 +0100
                Re: Gluecksrad "Peter J. Holzer" <hjp-usenet3@hjp.at> - 2016-11-23 22:47 +0100
            Re: Gluecksrad Arno Welzel <usenet@arnowelzel.de> - 2016-11-23 10:06 +0100
              Re: Gluecksrad Arno Welzel <usenet@arnowelzel.de> - 2016-11-23 10:18 +0100
                Re: Gluecksrad Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-11-23 12:16 +0100
                Re: Gluecksrad Arno Welzel <usenet@arnowelzel.de> - 2016-11-24 21:28 +0100
                Re: Gluecksrad Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-11-24 22:45 +0100
                Re: Gluecksrad Arno Welzel <usenet@arnowelzel.de> - 2016-11-25 23:11 +0100
                Re: Gluecksrad Klaus Ketelaer <spam@spambouncer.de> - 2016-11-23 16:41 +0100
                Re: Gluecksrad Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-11-23 21:15 +0100
              Re: Gluecksrad Klaus Ketelaer <spam@spambouncer.de> - 2016-11-23 15:41 +0100
                Re: Gluecksrad "Christoph M. Becker" <cmbecker69@arcor.de> - 2016-11-23 16:21 +0100

csiph-web