
Original uploaded to flickr by Simon Zirkunow
Werden für eine schöne, bunte und komfortable Webseite mehrere Extender aus dem AJAX Control Toolkit verwendet (wie z.B. der CollapsiblePanelExtender, der DropShadowExtender oder der RoundedCornerExtender) hat man ja öfter das Problem, dass die Seite beim Laden stark "flackert". Das wirkt natürlich ziemlich störend. Bei der Entwicklung von Windows-Anwendungen hat man in solch einem Fall immer noch die Option, das Neuzeichnen der Anwendungs-Oberfläche zu unterdrücken, bis alle Layout-Arbeiten beendet sind. Im Web ist das natürlich nicht möglich.
Deshalb kam ich auf die Idee, eine Art "Startbildschirm" (bzw. Startup Screen zu implementieren, der den eigentlichen Seitenaufbau verdeckt, bis die Seite komplett inklusive Layout fertig geladen ist. Das Prinzip dafür ist relativ simpel:
Per JavaScript-Funktion wird am Anfang der zu ladenden Seite dynamisch ein absolut positioniertes DIV erzeugt und als erstes sichtbares Element der Seite eingefügt. Dieses DIV kann dann zum Beispiel eine "Bitte warten" – Animation oder ähnliches enthalten. Ist die Seite fertig aufgebaut wird das DIV einfach wieder entfernt. Etwas schwierig ist es, den Zeitpunkt der "fertig geladenen" Seite zu ermitteln, d.h. den Zeitpunkt, an dem auch alle Extender ihre Manipulationen so weit abgeschlossen haben, dass die Seite nicht mehr flackert. Hier bieten sich zwei Möglichkeiten an:
- Man benutzt einen Timer – und verlässt sich darauf, dass die Seite bei Ablauf des selbigen auch immer fertig geladen ist. Allerdings mutet man dem Anwender damit unter Umständen auch zu, länger als nötig zu warten: Wird der Startbildschirm immer nach drei Sekunden entfernt, die Seite ist aber tatsächlich bereits nach einer Sekunde vollständig geladen, so muss der Anwender unnötiger Weise zwei Sekunden mit Warten zubringen.
- Man hängt sich an das load – Event der AJAX-Application, welches gefeuert wird, wenn die Anwendung komplett geladen ist, und entfernt den Startbildschirm dann. So ist er immer nur so lange zu sehen, wie tatsächlich notwendig – aber auch nicht kürzer.
Da die Seite natürlich nicht nur beim ersten Laden flackert, sondern auch dann, wenn sie aus der Anwendung heraus erneut aufgerufen wird, wäre es schlau, zwei verschiedene Startbildschirme zu verwenden: Einen für den ersten Start ("Die tollste Anwendung der Welt wird geladen…") und eine für nachfolgende Ladevorgänge ("Daten werden geladen…").
Im Folgenden nun eine Beispiel-Implementierung:
Im head – Bereich der Seite wird die Funktion zum Einfügen des DIVs definiert und in den Response-Stream geschrieben:
<%
Response.Write("<script type=\"text/javascript\">\n");
Response.Write("<!--\n");
Response.Write("\tfunction placeStartupLogo()\n");
Response.Write("\t{\n");
Response.Write("\t\tvar clientHeight;\n");
Response.Write("\t\tif (window.innerHeight)\n");
Response.Write("\t\t\tclientHeight =
((Sys.Browser.agent === Sys.Browser.Safari) ?
window.innerHeight :
Math.min(window.innerHeight,
document.documentElement.clientHeight));\n");
Response.Write("\t\telse\n");
Response.Write("\t\t\tclientHeight =
document.documentElement.clientHeight;\n");
Response.Write("\t\tvar clientWidth;\n");
Response.Write("\t\tif (window.innerWidth)\n");
Response.Write("\t\t\tclientWidth =
((Sys.Browser.agent === Sys.Browser.Safari ) ?
window.innerWidth :
Math.min(window.innerWidth,
document.documentElement.clientWidth));\n");
Response.Write("\t\telse\n");
Response.Write("\t\t\tclientWidth =
document.documentElement.clientWidth ;\n");
Response.Write("\t\t\n");
Response.Write("\t\tvar startupLogoWidth = 320;\n");
Response.Write("\t\tvar startupLogoHeight = 240;\n");
Response.Write("\t\t\n");
Response.Write("\t\tvar startupLoadDiv = document.createElement('div');\n");
Response.Write("\t\tstartupLoadDiv.id = 'startupLoadDiv';\n");
Response.Write("\t\tstartupLoadDiv.style.left = 0;\n");
Response.Write("\t\tstartupLoadDiv.style.top = 0;\n");
Response.Write("\t\tstartupLoadDiv.style.width = '100%';\n");
Response.Write("\t\tstartupLoadDiv.style.height = clientHeight+'px';\n");
Response.Write("\t\tstartupLoadDiv.style.background = '#FFFFFF';\n");
Response.Write ("\t\tstartupLoadDiv.style.textAlign = 'center';\n");
Response.Write("\t\tstartupLoadDiv.style.verticalAlign = 'middle';\n");
Response.Write("\t\tstartupLoadDiv.style.paddingTop =
(clientHeight / 2 - startupLogoHeight / 2) +'px';\n");
Response.Write("\t\t\n");
Response.Write("\t\tvar startupLogo =
document.createElement('img');\n");
if (null == Session["FirstLoad"])
{
Session["FirstLoad"] = false;
Response.Write("\t\tstartupLogo.setAttribute('src', '../res/firstLoad.jpg');\n");
Response.Write("\t\tstartupLogo.setAttribute('alt', 'Anwendung wird geladen...');\n");
}
else
{
Response.Write("\t\tstartupLogo.setAttribute('src', '../res/dataLoad.jpg');\n");
Response.Write("\t\tstartupLogo.setAttribute('alt', 'Daten werden geladen...');\n");
}
Response.Write("\t\tstartupLogo.style.textAlign = 'center';\n");
Response.Write("\t\tstartupLogo.style.verticalAlign = 'middle';\n");
Response.Write("\t\tstartupLogo.style.padding = '3px';\n");
Response.Write("\t\tstartupLogo.style.borderColor = '#000000';\n");
Response.Write("\t\tstartupLogo.style.borderWidth = '1px';\n");
Response.Write("\t\tstartupLogo.style.borderStyle = 'solid';\n");
Response.Write("\t\t\n");
Response.Write("\t\tstartupLoadDiv.appendChild(startupLogo);\n");
Response.Write("\t\tdocument.getElementById('aspnetForm').insertBefore(startupLoadDiv,
document.getElementById ('aspnetForm').firstChild);\n");
Response.Write("\t}\n");
Response.Write("-->\n");
Response.Write("</script>\n");
%>
Am Anfang des body – Bereichs (z.B. als erstes in einer definierten Web Form) wird die oben definierte Funktion aufgerufen:
<script type="text/javascript">
<!--
placeStartupLogo();
-->
</script>
Am Ende der Seite wird nun noch das Enfernen des Startbildschirms verdrahtet:
<script type="text/javascript">
<!--
function applicationLoaded()
{
Sys.Application.remove_load(applicationLoaded);
var startupDiv = document.getElementById('startupLoadDiv');
if (null != startupDiv)
startupDiv.parentNode.removeChild(startupDiv);
}
Sys.Application.add_load(applicationLoaded);
-->
</script>
Das Beispiel bietet natürlich noch viel Raum für Optimierungen und Erweiterungen – es entstand halt "auf die Schnelle"
Hauptsächlich geht es mir hier um die Verdeutlichung des Prinzips.



Kein Kommentar
Die Kommentarfunktion ist deaktiviert.