Laden...

Erster Aufruf einer View extrem langsam (ASP.NET MVC)

Erstellt von Telefisch vor 5 Jahren Letzter Beitrag vor 5 Jahren 4.059 Views
T
Telefisch Themenstarter:in
372 Beiträge seit 2008
vor 5 Jahren
Erster Aufruf einer View extrem langsam (ASP.NET MVC)

Hallo Ihr wissenden...
nun habe ich meine neue Site endlich online und muss feststellen, dass der erste Aufruf eines Views extrem lange dauert.
Am längsten dauert der initiale Aufruf des Home-Views.
Ich habe schon mit vorkompilieren veröffentlicht und dabei auch die option ‚allow precompiled site to be updated‘ deaktiviert, aber es ist so langsam, dass der Edge meint die Seite gäbe es gar nicht und auf Telekom Navigationshilfe weiterleitet.
Vom Safari aus dauert es beim ersten Aufruf etwa eine viertel Minute.
Danach dann höchstens eine Sekunde. Auch die weiteren Views, die dann auch Daten beinhalten brauchen maximal 1-2 Sekunden.

Wo fange ich da am besten an zu suchen?
Daten werden im Home-View gar nicht groß geladen aber ich denke mal die Verbindung zum SQL Server wird dort bestimmt schon aufgebaut?

Bin für jeden Hinwis dankbar.
Gruss Carsten

6.911 Beiträge seit 2009
vor 5 Jahren

Hallo Telefisch,

um konkret helfen zu können fehlt uns der Kontext. Also* wo hostest du die Anwendung?

  • was macht der Controller?
  • ...

Mit den gegeben Infos lässt sich nur raten...

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

16.806 Beiträge seit 2008
vor 5 Jahren

Sprichst Du wirklich von einer View?

Sofern es der erste Request an den (IIS) Server überhaupt ist: absolut normal.
Eine Webanwendung wird auf einem Webserver erst dann gestartet, wenn der erste Request erfolgt.
Erst dann lädt die Applikation alle notwendigen Dinge - und liefert dann die erste Antwort aus.
Je weniger geladen werden muss, desto kürzer die Warmup Time.

Es gibt aber in den WebServern entsprechende Einstellungen (Idle Time), die man deaktivieren kann und so immer die Applikation sofort gestartet wird.
Dabei wird aber nur der Warmup verkürzt; den Warmup selbst gibt es dann immer noch.

Was eine Telekom Navigationsseite sein soll: das ist definitiv kein Standardverhalten von Edge.

T
Telefisch Themenstarter:in
372 Beiträge seit 2008
vor 5 Jahren

Also dann mal erst ein paar Randdaten:

Windows Server 2012 mit IIS und SQL-Server.
beim Laden der Index Seite wird lediglich das Layout mit Navbar und einer Sidebar geladen.
Der Inhalt der Sidebar ist dann allerdings, abhängig vom angemeldeten User bzw. bei nicht angemeldetem User gefüllt oder eben nicht. Hier hätte ich den einzigen Aufruf der vielleicht etwas Zeit kosten könnte. Das wäre dann aber "nur" die Information ob der User angemeldet ist und falls ja, welcher Usergruppe er angehört. Da die Ladezeit aber auch bei nicht angemeldetem User so hoch ist, kann der Aufbau der Sidebar schon nicht mehr die große Rolle spielen.
Das ganze geschieht mittels ASP.NET Identities.

Diese Telekom Navigationsseite taucht manchmal auf, wenn man von einem Telekom Anschluss aus eine unbekannte Seite öffnen will. Mega überflüssig aber ist halt so. Ich denke hier geht sie auf, weil zu lange kein Response kommt.

Abt, danke für den Tipp mit der Idle Time, da werde ich mal weitersuchen...

16.806 Beiträge seit 2008
vor 5 Jahren

Riecht nach dem ganz normalen Applikationsstart einer Webseite.

Du kannst aber zB. Serilog verwenden (ohnehin empfehlenswert für jede Anwendung) und genau loggen, wann was passiert.
Dann siehst Du ein genauen, zeitlichen Ablauf.

T
Telefisch Themenstarter:in
372 Beiträge seit 2008
vor 5 Jahren

...ich muss diesen Threat nochmal rauskramen.

Der anfänglich verzögerte Start ist ja offensichtlich normal.
Ich habe nun also seit einiger Zeit eine erste Version der Datenbank produktiv und stelle fest, dass sie trotz geringster Datensatzanzahl quälend langsam geworden ist.
Die Datenbank hat der zeit keine 18MB und auch eigentlich keine ungewöhnlichen Beziehung.
Auf dem Developer-Rechner fluppt die Datenbank problemlos aber auf den Server ist das ganze Gebilde gähnend langsam.
Mein Problem ist, dass ich überhaupt keine Ahnung habe, wo ich mit der Suche beginnen soll.
Bin mit SQL-Server leider noch ziemlich unerfahren 😦

Wenn ich eine neue View öffne und demnach einen Datensatz abfrage geht die CPU Leistung kurzzeitig auf ca.85%, wobei hier der IIS worker-Prozess am meisten mit über 50% verbraucht.
Ich gehe aber eher davon aus, dass in der Konfiguration des SQL-Servers etwas nicht so richtig gut geklungen ist.
Wie geht Ihr an so eine Fehlersuche heran?

16.806 Beiträge seit 2008
vor 5 Jahren

Ich würde in solch einem Fall das Environment clonen (Server, DB...) und dann Stück für Stück gewisse Dinge versuchen auszuschließen; evtl. auch ein Remote Debugging anhängen, um an gewisse Ausführungen und deren Laufzeiten zu kommen.

T
Telefisch Themenstarter:in
372 Beiträge seit 2008
vor 5 Jahren

Da hab ich keine Hardware für.
Gibt es denn im SQL Server nirgends irgendwelche Logs, mit denen man nachvollziehen kann was er so grade tut?

T
2.219 Beiträge seit 2008
vor 5 Jahren

Dafür hat der SQL Server einen eigenen Profiler.
Auch grundsätzliche Dinge wie CPU, RAM und Plattenlast lassen sich direkt über den Task Manager/Resourcen Monitor vin Windows prüfen.

Wenn auch von deiner Seite ausgeschlossen ist, dass du bei deinen SQL Abfragen keine langsamen Abfragen ohne Indizies etc. fährst, sollten sich die meisten Probleme über den Task Manager/Resourcen Monitor ablesen lassen.

Wie sieht den die Hardware vom SQL Server aus.
Welche Version habt ihr und wie sieht dein Test System aus?

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

T
Telefisch Themenstarter:in
372 Beiträge seit 2008
vor 5 Jahren

Hmm…
zu den Taskmanager-Daten hatte ich ja oben schon was geschrieben.
Es handelt sich um einen Virtuellen Server mit Windows Server 2012 Standard,
SQL Server 2012
2 virtuelle CPUs
3GB Ram
150GB Festplatte.

Das ist der Aufruf einer View, der beispielsweise rund 5 Sekunden dauert:


public ActionResult Edit(int id = 0)
        {
            if (id == 0)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            FunctionGroup functionGroup = db.FunctionGroups.Find(id);
            if (functionGroup == null)
            {
                return HttpNotFound();
            }
            
            ViewBag.ProjectName = functionGroup.Project.ProjectName;
            
            //Properties laden
            ViewBag.Properties = db.FunctionGroupProperties.AsNoTracking()
                .Where(a => a.FunctionGroupId == id)
                .OrderBy(a => a.ListPosition).ToList();

            //Funktionen laden
            ViewBag.Functions = db.Functions.AsNoTracking()
                .Where(a => a.FunctionGroupId == id)
                .OrderBy(a => a.ListPosition).ToList();

            TreeBuilder tb = new TreeBuilder();
            ViewBag.copyData = tb.GetFunctionTree(db);
            ViewBag.copyProperties = tb.GetPropertiesTree(db);
            return View(functionGroup);
        }

Ich finde die eigentlich jetzt nicht so spektakulär...
Wir reden hier bei Tabellen in der Größe von bisher vielleicht 400 Datensätzen.

T
2.219 Beiträge seit 2008
vor 5 Jahren

Hast du mal geschaut ob die Abfragen gegen den DB Server überhaupt lange dauern?
Von der aktuellen Datenmenge + Hardware des DB Servers würde ich aktuell sagen, dürfte er eigentlich keine Probleme haben.
Wenn auch die Abfrage über Sql Management Studio auch direkt die Daten liefert, dann kann es nicht an der DB liegen.

Hier hilft es auch sich die Ausführungspläne anzuschauen um ggf. falls dort eine normale Abfrage lange dauert.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

16.806 Beiträge seit 2008
vor 5 Jahren

Der Code ist sehr suboptimal. Verletzte quasi jede ASP.NET best practise - und verletzt dabei jede Art der Schichtentrennung.

Hast Du denn schon analysiert, welche Zeile den Impact von 5 Sekunden erzeugt?
Wir haben auch keine Glaskugel. 😉

ViewBag.copyData = tb.GetFunctionTree(db);
ViewBag.copyProperties = tb.GetPropertiesTree(db);

Das ist nicht nur Code Smell; das riecht extrem fischig.
Da schrillen alle Alarmglocken.

Was passiert hier?

T
2.219 Beiträge seit 2008
vor 5 Jahren

Mich würde auch interessieren was db ist.
Sieht für mich nach Entity Framework DbContext Instanz aus.
Gehört beim Drei-Schichten-Model nicht in die View sondern in die Datenschicht und abgetrennt von der Business Logik bzw. in deinem Fall der View.

Wie Abt schon sagt, sieht der Code nicht sauber aus und lässt auch sonst nur sehr oberflächlich erahnen wo das Problem liegen kann.

Auch fehlen mir noch Details zum Resourcen Monitor.
Zeigt dieser irgendwas in Richtung Plattenlast oder vollen RAM o.ä.?
Auch ist unklar ob du auf dem gleichen Server deine Web liegen hast und ob du auch auf diesem Server deinen lokalen Test laufen lässt.
Schon solche Details können Aufschluss geben wo der Schuh drückt.

Auch müsstest du immer noch prüfen ob deine in der View verwendeten Abfragen per SQL Management Studio auch langsam sind oder ob dieser dort laufen.
Wenn diese im SQL Management rennen, dann liegt es nicht an der DB.
Dann muss es eher in deinem aktuellen Code liegen.
Bei schlechtem Code spielt auch die DB Größe dann keine Rolle mehr.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

5.657 Beiträge seit 2006
vor 5 Jahren

Also erstmal geht es in dem Thread um den **ersten **Aufruf einer View, und nicht um irgendwelche DB-Abfragen.

Du gibst uns keine Infos, aber es klingt so, als ob es immer so lange dauert bei dir.

Hast du überhaupt schonmal geschaut, **was **da so lange dauert? Du hast einen Debugger und einen Profiler zur Verfügung, nutze sie! Damit erfährst du mehr als per Ferndiagnose vom Forum.

Ansonsten wurde ja schon alles zu dem Code gesagt. Ich hoffe stark, daß der nicht im produktiven Einsatz ist. Schau dir mal ein paar Grundlagen an:
[Artikel] Drei-Schichten-Architektur

Und auch, wenn es hier MVC und nicht MVVM ist: [Artikel] MVVM und DataBinding. ViewBag ist das Equivalent zu globalen Variablen. Benutze soetwas niemals, sondern OOP bzw. ein geeignetes ViewModel für die View.

Weeks of programming can save you hours of planning

T
Telefisch Themenstarter:in
372 Beiträge seit 2008
vor 5 Jahren

So, damit hier keiner Amok läuft...
Ich programmiere hier eher hobbymäßig und muss mich nebenbei auch noch um andere Dinge kümmern.
Ich werde mir heute Eure Fragen und Anregungen nochmal genauer anschauen und Euch dann auch auf Stand bringen.
Was das drei-Schichten Modell angeht...
Ich habe mir ASP.NET MVC selbst beigebracht und habe es ganuso aus bezahlten Lernvideos gelernt.
Wie oder Wo soll ich denn jetzt nochmal den Controller in Logikschicht und Datenzugriffsschicht aufteilen?

Ja, die letzten beiden Codezeilen habe ich nicht kommentiert, hab ich übersehen.

Ja, es ging ursprünglich um den ersten Aufruf einer View, in anderen Foren bekommt man auf die Fresse, wenn man auch nur einen Threat Zuviel startet, hier ist es eben anders.
Danke dafür!

db ist in der Tat das EF DB Context, wird aber nirgends einer View übergeben, wer auch immer das behauptet.
Hier wird lediglich das Ergebnis eines Funktionsaufrufes an die View übergeben!

Alle anderen noch offenen Fragen werde ich beantworten, sobald ich sie beantworten kann.

Ach ja und MrSparkle, "Du hast einen Debugger und einen Profiler zur Verfügung, nutze sie!"
genau das war meine eigentliche Frage.

5.657 Beiträge seit 2006
vor 5 Jahren

Ganz ruhig, niemand bekommt auf die Fresse, und niemand läuft Amok. Es geht nur um den Code, nicht um deine Persönlichkeit.

Und wenn der Titel des Threads zu deinem Beitrag paßt, dann ist das vor allem in deinem Interesse.

Profiler und Debugger sind in Visual Studio sowie im Browser eingebaut. Wie du den Debugger verwendest, kannst du hier nachlesen: [Artikel] Debugger: Wie verwende ich den von Visual Studio?, für den Profiler findest du Anleitungen bei YouTube. Es geht eigentlich nur darum zu messen, welche Aufrufe wieviel Zeit benötigen.

Wir können das ja nicht von hier aus machen, dafür mußt du Verständnis haben.

Weeks of programming can save you hours of planning

T
Telefisch Themenstarter:in
372 Beiträge seit 2008
vor 5 Jahren

Hallo MrSparkle,
erstmal danke für den Link, und natürlich erwarte ich nicht dass jemand seine Glaskugel für mich bemüht.
Ich stehe halt vor einem Problem und suche erstmal einen Weg der Ursache näher zu kommen.
Was ich nicht bedacht hatte, dass der Server eventuell deutlich langsamer sein könnte als mein Notebook, auf dem das Debugging gemacht wird.

Daraus und aus den Anregungen hier ergeben sich bei mir neue Fragen, die ich vielleicht vorher stellen sollte, bevor ich dem SQL Server die Schuld gebe.

Das Thema Drei-Schichten-Modell ist hier sicher nicht ganz unangebracht, auch wenn die kontroverse Diskussion über Sinn und Unsinn bei "überschaubarer" Logik sicher nie enden würde.
Da es natürlich im Laufe eines Projektes immer mehr Methoden und Funktionen gibt ist sicher auch bei meinem Projekt auf lange Sicht diese Architektur sinnvoll und sollte sicher frühest möglich implementiert werden.
Irgendwie fallen mir zu diesem Thema, im Zusammenhang mit ASP.net MVC nur nicht die richtigen Suchbegriffe ein.
Bisher war ich davon ausgegangen, dass der Controller quasi die Logikschicht ist.
Das ist aber wohl ein Irrtum. Der Controller gehört dann wohl eher zur Präsentation.
Jetzt mal aus der Praxis, wie/wo implementiere ich denn die Businesslogik?
Ich meine, im einfachsten Fall gebe ich einer View einen Datensatz mit:

FunctionGroup functionGroup = db.FunctionGroups.Find(id);
return View(functionGroup);

Wie würde ich das denn mit einer zwischengeschalteten Logikschicht lösen?
Eine Trennung in drei Schichten macht schließlich nur Sinn, wenn ich sie konsequent überall einsetze.

T
2.219 Beiträge seit 2008
vor 5 Jahren

Es wäre sinnvoller das in einem eigenen Thread zu besprechen.
Auch bei den aktuellen Problemen weichen wir von dem urspünglichen Punkt mit der langsamen View schon ab.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

T
Telefisch Themenstarter:in
372 Beiträge seit 2008
vor 5 Jahren

Ok, dann fange ich nen neuen Threat an...