title: How to improve Qt's QSS/CSS performance on embedded devices?
body: <p>this post is basically a copy of <a href="https://forum.qt.io/topic/74733/how-to-improve-qt-s-qss-css-performance-on-embedded-devices" rel="nofollow noreferrer">this Qt forum entry</a>.</p>
  
  <p>I ran into performance problems with Qt for embedded Linux 4.8.3 on custom hardware. The styling of the UI is done with QSS and no custom painting code. There is various information on stackoverflow and in this forum about the performance of QSS. A few things can be summerized:</p>
  
  <ul>
  <li>A single file of QSS set for the whole application is used in almost all samples. Some people suggest that the performance of multiple files could be slightly better.</li>
  <li>The QSS file should be set a single time and dynamic styling should happen through dynamic style sheet properties. So it's basically a special selector in the already set stylesheet.</li>
  <li>The performance of QSS is known to be worse than custom painting code and some even suggest to avoid the use of QSS comepletely.</li>
  </ul>
  
  <p>In our project we use dynamic styling, a single large QSS file and the performance during run-time is actually fine. Even compared to not using a stylesheet and letting the default style draw itself. The problem is the startup time. It is vastly different when we use the QSS. I have created the following measurements:</p>
  
  <p><a href="https://i.stack.imgur.com/PJBbN.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/PJBbN.png" alt="QSS performance chart"></a></p>
  
  <p>Interesting observations:</p>
  
  <ul>
  <li><strong>Original</strong>: Single, large QSS file which is set for the whole application at startup before the widgets are instatiated</li>
  <li><strong>Empty QSS</strong>: Using a empty QSS file (removing all the styling information) results in a startup time reduction of about 4 seconds. The UI is then drawn with the default styling and looks exactly the same as if no QSS file was set in the application at all.</li>
  <li><strong>No QSS at all</strong>: This shows how much impact the styling has on the startup time. Not setting any QSS file for any widget results in a huge performance gain.</li>
  <li><strong>Single example widget in global QSS</strong>: In this scenario the application-wide QSS contained only styling information for a single widget. You can see that the single widget already increases the startup time a bit (compared to an empty QSS file). This is understandable and fine.</li>
  <li><strong>Single example widget directly in C++</strong>: In this scenario the same widget as before is styled but this time the styling string is read and set directly in the constructor of the mentioned widget. So there was no application-wide QSS file set. This seems to work extremely fast (only at the first glance, see below!)</li>
  <li><strong>No "global" QWidget styles</strong>: I thought that I could maybe improve the performance by being more specific in the QSS file, for example, by not setting the font in a global QWidget selector but for each of the widgets separately. I just visualized the impact of commenting out the global rule. So the performance improvement could also be a font difference. But the point is that the impact of such "global" styling selectors is rather small.</li>
  <li><strong>Split files</strong>: In this scenario I added separate styling information to 7 different, heavily used widgets. So again no application-wide stylesheet. You can see that the startup time is already high. I did not try to set the styling for all my widgets because this graph already shows that there is no promising performance gain anymore.</li>
  <li><strong>app.setStylesheet() after widget construction</strong>: Then I had the idea to first construct all the widgets and apply the stylesheet afterwards. This actually improved the startup time BUT I did not account for such updates in some of the widgets. In order to get this approach running I would need to update some of the widgets which would reduce the gain again. But 2 seconds are not that impressive anyways.</li>
  </ul>
  
  <p><strong>So:</strong></p>
  
  <ul>
  <li>Why has even an empty QSS file such a huge impact on the performance and can I do anything about that?</li>
  <li>Does that mean that the whole styling framework has bad performance and there is no way to get it running faster?</li>
  <li>I would like to somehow pre-load/bake the styling information. This does not have to be done at every startup. All the file parsing etc. is done on every startup although this is not necessary. Any ideas on that?</li>
  <li>Do I really need to re-write all the styling using custom painting code? Does anybody know if the performance is actually near the "default" style. So does custom painting code still has impact on the performance or is it more or less "for free" compared to the default style?</li>
  <li>Does anyone has experience with single/multiple QSS files? Using specific styling per widget seems to improve the performance immensely at the first glance but adding all the stlying step by step seems to result in more or less the same startup time in the end?!</li>
  </ul>
  
  <p>Thank you for any hints!</p>