Beim fortschreitenden Laden von XML-Seiten werden bereits geladene und verarbeitete Teile einer XML-Seite geladen und gleichzeitig angezeigt, während die XSLT-Vorlage den Rest der Teile noch verarbeitet.
Wir haben ein sehr großes XML. Dies ist ein Artikel mit vielen Kommentaren. In einem langsamen und instabilen mobilen Internet warten Sie möglicherweise nicht darauf, dass es geladen wird. Während des Downloads wird die Verbindung unterbrochen und das XML bleibt nicht geladen. Es scheint, dass Sie die Seite einfach aktualisieren können und der Browser nur den fehlenden Teil lädt. Aber nein. Der Browser lädt die Seite immer wieder und es schlägt fehl und wir sehen einen Fehler anstelle der Seite.
Aber es gibt einen Ausweg aus dieser Situation. Wir werden das XML in kleine Teile aufteilen, die Zeit haben, auf einem langsamen Kanal zu laden und in den Cache zu gelangen. Als Bonus erhalten wir Unterlastschutz und progressives Laden.
Womit werden wir arbeiten?
XML-Artikel
Diese Datei enthält einen Titel, eine Beschreibung, einen Artikeltext und viele, viele Kommentare. Genauer gesagt gibt es 5962 Kommentare.
Jeder Kommentar hat ein 'Index'-Attribut. Dieser Index wird von anderen Kommentaren im Attribut 'to' verwendet, um anzuzeigen, dass der Kommentar eine Antwort auf den Kommentar ist, dessen Index angegeben ist.
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href=".xslt" type="text/xsl"?>
<>
<title xmlns="http://www.w3.org/1999/xhtml">Lorem Ipsum</title>
<meta name="description" content="Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit..." xmlns="http://www.w3.org/1999/xhtml"/>
<>Quisque sollicitudin malesuada urna, id tincidunt quam. Pellentesque luctus, sem vel posuere efficitur, est enim pulvinar orci, et vulputate orci dui a libero. Nam eget mauris sed diam pretium fermentum. Proin euismod ultrices justo, non aliquet ipsum bibendum at. Duis eget laoreet mauris. Morbi tristique arcu libero, quis pharetra justo bibendum eget. In at quam sed lacus vestibulum tincidunt quis ut ex.</>
< ="1">
Nunc sit amet ligula mauris. Integer vel nisi ac turpis rhoncus suscipit. Fusce elementum ut elit quis rutrum. Nulla bibendum placerat ex pulvinar accumsan. Praesent vestibulum hendrerit accumsan. Sed quis ligula pretium, condimentum enim in, cursus elit. Phasellus quis mauris arcu. Integer congue ex et ante porttitor vestibulum. Donec vel mauris venenatis, ultrices leo in, dapibus metus. Morbi pharetra eleifend libero nec efficitur. Fusce efficitur et ligula quis scelerisque. Curabitur eget nibh at nunc lacinia fringilla et eget quam. Praesent malesuada, odio in pulvinar semper, libero nunc consectetur lorem, vel egestas erat tellus nec ipsum.
</>
<!-- ... -->
< ="1" ="4">
Praesent varius vitae arcu sed imperdiet. Proin pulvinar a augue blandit scelerisque. Pellentesque lectus erat, gravida lobortis lorem ut, dignissim tempor felis. Nunc porttitor libero quis est sodales, non ornare metus eleifend. Cras orci lacus, auctor non sollicitudin lacinia, ultricies vitae diam. Fusce eu leo varius, interdum sapien ac, vestibulum orci. Sed placerat feugiat odio, vitae tempor tellus volutpat tincidunt. Cras dapibus est et mi euismod ornare. Vestibulum accumsan justo non volutpat dictum. Curabitur porttitor, magna id euismod tincidunt, metus nisl fermentum tellus, id pulvinar leo nibh vel velit. Sed gravida gravida sapien et porttitor. Nam volutpat, ex id faucibus commodo, arcu arcu fringilla mi, et volutpat nunc turpis at ligula. Pellentesque et vulputate ligula, lobortis dignissim ligula. Nulla laoreet auctor ultricies. Interdum et malesuada fames ac ante ipsum primis in faucibus.
</>
<!-- ... -->
</>Grundlegende XSLT-Vorlage
Dies ist eine kleine XSLT-Vorlage, die XML in vollwertiges xHTML umwandelt und Kommentarthreads aus einer Liste sammelt.
<xsl:stylesheet
version="1.0"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:x="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<!-- -->
<xsl:key name="" match="" use="@"/>
<!-- -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<!-- xHTML -->
<xsl:template match="">
<html>
<head>
<!-- xHTML title meta -->
<!-- -->
<xsl:copy-of select="x:title | x:meta[@name = 'description']"/>
<style>
. {
padding: 1vw;
min-width: 20em;
border: 1px solid gray;
color: black;
background-color: white;
}
. {
max-width: 46em;
margin: auto;
text-align: justify;
}
</style>
</head>
<body>
<!-- ( )-->
<xsl:apply-templates select="@*" />
<div class="">
<!-- 'title' -->
<h1><xsl:value-of select="x:title"/></h1>
<!-- 'content' 'meta' -->
<i><xsl:value-of select="x:meta[@name = 'description']/@content"/></i>
<!-- '' -->
<p><xsl:apply-templates select="/node()" /></p>
</div>
<!-- -->
<xsl:apply-templates select="." mode=""/>
</body>
</html>
</xsl:template>
<!-- -->
<xsl:template match="" mode="">
<details id="" open=''>
<summary></summary>
<!-- @ -->
<xsl:apply-templates select="[not(@)]"/>
</details>
</xsl:template>
<!-- -->
<xsl:template match="">
<!-- "" -->
<div class="" id="{@}">
<!-- -->
<xsl:apply-templates select="@*" />
<!-- -->
<a href="#{@}"><xsl:value-of select="@"/></a><xsl:text>: </xsl:text>
<div class="">
<!-- -->
<xsl:apply-templates select="node()" />
</div>
<!-- -->
<xsl:apply-templates select="." mode=""/>
</div>
</xsl:template>
<!-- -->
<xsl:template match="" mode="">
<!-- -->
<xsl:if test="key('', @)">
<details open=''>
<summary></summary>
<!-- -->
<xsl:apply-templates select="key('', @)"/>
</details>
</xsl:if>
</xsl:template>
</xsl:stylesheet>Testen
GPRS. . , , XML XSLT .
: 10,77
XML
.
.
XML , XSLT .
XML '-', XML , .
xslt\--.xslt:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8"/>
<xsl:key name="" match="" use="@"/>
<!-- -->
<xsl:param name="" />
<!-- -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<!-- -->
<xsl:template match="">
<!-- -->
<xsl:param name="-" select="floor(@ div $)" />
<!-- -->
<xsl:param name="-" select="key('', @)[floor(@ div $) > $-]"/>
<!-- -->
<xsl:copy>
<!-- "" "" -->
<xsl:apply-templates select="@*" />
<!-- -->
<xsl:if test="$-">
<!-- "-" -->
<xsl:attribute name="-">
<!-- -->
<xsl:call-template name="-">
<!-- -->
<xsl:with-param name="" select="$-" />
</xsl:call-template>
</xsl:attribute>
</xsl:if>
<!-- -->
<xsl:apply-templates select="node()" />
</xsl:copy>
</xsl:template>
<xsl:template name="-">
<!-- -->
<xsl:param name=""/>
<!-- -->
<xsl:param name="-" select="floor($[1]/@ div $)"/>
<!-- -->
<xsl:param name="-" select="$[floor(@ div $) > $-]"/>
<!-- -->
<xsl:value-of select="$-"/>
<!-- -->
<xsl:if test="$-">
<!-- -->
<xsl:text> </xsl:text>
<!-- -->
<xsl:call-template name="-">
<!-- -->
<xsl:with-param name="" select="$-" />
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
XML
.
xslt\--.xslt:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- 'method' 'text' -->
<xsl:output method="text" encoding="UTF-8"/>
<!-- XML -->
<xsl:param name="" select="100" />
<xsl:template match="/">
<!-- XML -->
<xsl:value-of select="floor(count(//) div $)"/>
</xsl:template>
</xsl:stylesheet>
('') XML .
xslt\-.xslt:
<xsl:stylesheet
version="1.0"
xmlns:x="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8"/>
<xsl:param name="" />
<!-- -->
<xsl:param name=""/>
<!-- -->
<xsl:param name=""/>
<xsl:template match="/">
<!-- -->
<xsl:processing-instruction name="xml-stylesheet">href="../-.xslt" type="text/xsl"</xsl:processing-instruction>
<!-- -->
<xsl:apply-templates select="" />
</xsl:template>
<xsl:template match="">
< ="{$}">
<!-- title meta -->
<xsl:copy-of select="x:title | x:meta[@name = 'description']"/>
<!-- -->
<xsl:copy-of select="[floor(@ div $) = $]" />
</>
</xsl:template>
</xsl:stylesheet>
, .
xslt\-.xslt:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8"/>
<!-- -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<!-- -->
<xsl:processing-instruction name="xml-stylesheet">href="../-.xslt" type="text/xsl"</xsl:processing-instruction>
<!-- -->
<xsl:apply-templates select="" />
</xsl:template>
<!-- -->
<xsl:template match=""/>
</xsl:stylesheet>
msxsl.exe
msxsl.exe. XML XSLT stdout .
CMD
XML .
progressive.cmd lorem-ipsum.xml 100
progressive.cmd:
chcp 65001
rem XML
md "%~dpn1"
rem
msxsl.exe %1 "%~dp0xslt\--.xslt" -xw -o "%~dpn1\index.xml" =%2
rem XML
for /f "delims=" %%a in ('msxsl.exe %1 ^"%~dp0xslt\--.xslt^" ^=%2') do set =%%a
rem
for /l %%i in (0,1,%%) do msxsl.exe -o "%~dpn1\%%i.xml" "%~dpn1\index.xml" "%~dp0xslt\-.xslt" =%2 =%%i ="%~n1"
rem
msxsl.exe "%~dpn1\index.xml" "%~dp0xslt\-.xslt" -o "%~dpn1\index.xml"
. . .
-.xslt
<xsl:stylesheet
version="1.0"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:x="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<!-- ".xslt" -->
<xsl:include href="%D1%81%D1%82%D0%B0%D1%82%D1%8C%D1%8F.xslt"/>
<xsl:template match="" mode="">
<!-- -->
<iframe style="display:none;" id="-" src="0.xml"/>
<script><![CDATA[
setTimeout(function(){
var = document.querySelector("#-");
if ( && .contentDocument)
{
var = .contentDocument.getElementById('');
//
if ()
{
//
document.body.appendChild();
return;
}
}
// Timeout
setTimeout(arguments.callee, 100);
}, 100)]]>
</script>
<noscript>
<!-- JavaScript -->
<a href="0.xml"></a>
</noscript>
</xsl:template>
</xsl:stylesheet>
XML .
-.xslt
<xsl:stylesheet
version="1.0"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:x="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" encoding="UTF-8"/>
<!-- ".xslt" -->
<xsl:include href="%D1%81%D1%82%D0%B0%D1%82%D1%8C%D1%8F.xslt"/>
<!-- -->
<xsl:key name="" match="" use="@"/>
<xsl:param name="" select="/@"/>
<xsl:template match="/">
<!-- ".xslt" -->
<xsl:apply-templates select="document(concat($, '/index.xml'))/"/>
</xsl:template>
<!-- -->
<xsl:template match="" mode="">
<details id="" open=''>
<!-- -->
<summary></summary>
<!-- -->
<xsl:call-template name="-"/>
</details>
</xsl:template>
<xsl:template name="-">
<!-- XML 0 -->
<xsl:param name="" select="0"/>
<!-- XML -->
<xsl:param name="" select="document(concat($, '/', $, '.xml'))"/>
<!-- XML -->
<xsl:if test="$">
<!-- -->
<xsl:apply-templates select="$//[not(@)]" />
<!-- XML -->
<xsl:call-template name="-">
<!-- XML -->
<xsl:with-param name="" select="$ + 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
<!-- -->
<xsl:template match="" mode="">
<!-- XML -->
<xsl:if test="key('', @) or @-">
<details open=''>
<summary></summary>
<!-- XML -->
<xsl:apply-templates select="key('', @)"/>
<!-- XML -->
<xsl:call-template name="-"/>
</details>
</xsl:if>
</xsl:template>
<xsl:template name="-">
<!-- -->
<xsl:param name="" select="concat(@-, ' ')"/>
<!-- -->
<xsl:param name="" select="substring-before($, ' ')"/>
<!-- -->
<xsl:if test="$">
<!-- XML -->
<xsl:apply-templates select="document(concat($, '/', $, '.xml'))" mode="">
<!-- -->
<xsl:with-param name="" select="@"/>
</xsl:apply-templates>
<!-- -->
<xsl:call-template name="-">
<!-- -->
<xsl:with-param name="" select="substring-after($, ' ')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="/" mode="">
<!-- -->
<xsl:param name=""/>
<!-- -->
<xsl:apply-templates select="key('', $)"/>
</xsl:template>
</xsl:stylesheet>
Aktivieren Sie das GPRS-Tempolimit im Browser und starten Sie das Laden der Seite.
Laden des Artikeltextes: 2.28s
Laden der ersten Kommentare: 14.41s (nur in FireFox)
Volles Laden: 11.33 Minuten