diff --git a/src/declarative/items/qsgtextnode.cpp b/src/declarative/items/qsgtextnode.cpp
index 2eb705fbf60ee3beb9304602dffa21aea66bf850..d36db1b6b6a3f440107adcec8e067c0b0413f5ef 100644
--- a/src/declarative/items/qsgtextnode.cpp
+++ b/src/declarative/items/qsgtextnode.cpp
@@ -162,9 +162,13 @@ QSGGlyphNode *QSGTextNode::addGlyphs(const QPointF &position, const QGlyphRun &g
             dfNode->setStyleColor(styleColor);
         }
         node->setColor(color);
-        appendChildNode(node);
     }
 
+    node->update();
+
+    if (node != prevNode)
+        appendChildNode(node);
+
     return node;
 }
 
diff --git a/src/declarative/scenegraph/qsgadaptationlayer_p.h b/src/declarative/scenegraph/qsgadaptationlayer_p.h
index 33f664f1504be3ca0b895f49fc79714b2165d08e..81b17a9000a3f30d005f11c04cda2c0fdf776810 100644
--- a/src/declarative/scenegraph/qsgadaptationlayer_p.h
+++ b/src/declarative/scenegraph/qsgadaptationlayer_p.h
@@ -112,6 +112,8 @@ public:
 
     virtual void setPreferredAntialiasingMode(AntialiasingMode) = 0;
 
+    virtual void update() = 0;
+
 protected:
     QRectF m_bounding_rect;
 };
diff --git a/src/declarative/scenegraph/qsgdefaultglyphnode_p.h b/src/declarative/scenegraph/qsgdefaultglyphnode_p.h
index 8d79d1109d9435a28a006edf0989ca2e19958a5f..16e267b605ec243695fde2c052047df66959ffa9 100644
--- a/src/declarative/scenegraph/qsgdefaultglyphnode_p.h
+++ b/src/declarative/scenegraph/qsgdefaultglyphnode_p.h
@@ -65,6 +65,8 @@ public:
 
     virtual void setPreferredAntialiasingMode(AntialiasingMode) { }
 
+    virtual void update() { }
+
 private:
     QGlyphRun m_glyphs;
     QPointF m_position;
diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp b/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp
index 343487bd30b4d24e6aa5adc3bea721510de601e9..26326d0c75b4c06174a5ce5727ee336dc6469fef 100644
--- a/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp
+++ b/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp
@@ -52,6 +52,9 @@ QSGDistanceFieldGlyphNode::QSGDistanceFieldGlyphNode()
     , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0)
     , m_style(QSGText::Normal)
     , m_antialiasingMode(GrayAntialiasing)
+    , m_dirtyFont(false)
+    , m_dirtyGeometry(false)
+    , m_dirtyMaterial(false)
 {
     m_geometry.setDrawingMode(GL_TRIANGLES);
     setGeometry(&m_geometry);
@@ -84,7 +87,7 @@ void QSGDistanceFieldGlyphNode::setPreferredAntialiasingMode(AntialiasingMode mo
     if (mode == m_antialiasingMode)
         return;
     m_antialiasingMode = mode;
-    updateMaterial();
+    m_dirtyMaterial = true;
 }
 
 void QSGDistanceFieldGlyphNode::setGlyphs(const QPointF &position, const QGlyphRun &glyphs)
@@ -93,23 +96,35 @@ void QSGDistanceFieldGlyphNode::setGlyphs(const QPointF &position, const QGlyphR
     m_position = QPointF(position.x(), position.y() - font.ascent());
     m_glyphs = glyphs;
 
-    updateFont();
-    updateGeometry();
-    updateMaterial();
-
-#ifdef QML_RUNTIME_TESTING
-    description = QLatin1String("glyphs");
-#endif
+    m_dirtyFont = true;
+    m_dirtyGeometry = true;
+    m_dirtyMaterial = true;
 }
 
 void QSGDistanceFieldGlyphNode::setStyle(QSGText::TextStyle style)
 {
+    if (m_style == style)
+        return;
     m_style = style;
+    m_dirtyMaterial = true;
 }
 
 void QSGDistanceFieldGlyphNode::setStyleColor(const QColor &color)
 {
+    if (m_styleColor == color)
+        return;
     m_styleColor = color;
+    m_dirtyMaterial = true;
+}
+
+void QSGDistanceFieldGlyphNode::update()
+{
+    if (m_dirtyFont)
+        updateFont();
+    if (m_dirtyGeometry)
+        updateGeometry();
+    if (m_dirtyMaterial)
+        updateMaterial();
 }
 
 void QSGDistanceFieldGlyphNode::updateGeometry()
@@ -225,11 +240,13 @@ void QSGDistanceFieldGlyphNode::updateGeometry()
 
     setBoundingRect(boundingRect);
     markDirty(DirtyGeometry);
+    m_dirtyGeometry = false;
 }
 
 void QSGDistanceFieldGlyphNode::updateFont()
 {
     m_glyph_cache = QSGDistanceFieldGlyphCache::get(QGLContext::currentContext(), m_glyphs.rawFont());
+    m_dirtyFont = false;
 }
 
 void QSGDistanceFieldGlyphNode::updateMaterial()
@@ -260,6 +277,7 @@ void QSGDistanceFieldGlyphNode::updateMaterial()
     m_material->setGlyphCache(m_glyph_cache);
     m_material->setColor(m_color);
     setMaterial(m_material);
+    m_dirtyMaterial = false;
 }
 
 QT_END_NAMESPACE
diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.h b/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.h
index 5d6ddd0c15d69f844b3e3664894f66d3c7c4a1ab..926a84383cf7340b711e11eb8da1324f599c4248 100644
--- a/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.h
+++ b/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.h
@@ -69,6 +69,8 @@ public:
     void setStyle(QSGText::TextStyle style);
     void setStyleColor(const QColor &color);
 
+    virtual void update();
+
 private:
     void updateGeometry();
     void updateFont();
@@ -84,6 +86,10 @@ private:
     QSGText::TextStyle m_style;
     QColor m_styleColor;
     AntialiasingMode m_antialiasingMode;
+
+    uint m_dirtyFont: 1;
+    uint m_dirtyGeometry: 1;
+    uint m_dirtyMaterial: 1;
 };
 
 QT_END_HEADER