[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdelibs/khtml/misc
From:       Germain Garand <germain () ebooksfrance ! org>
Date:       2010-02-27 3:31:54
Message-ID: 1267241514.032083.32277.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 1096620 by ggarand:

port KHTML to Andrea's excellent scheduler.

This, together with the next patch, greatly improves Konqueror's
objective speed (Page Loading Time) as well as the subjective speed
(Time To First Paint).
Our PLT was already very nice, but this just blows things off.
Will have to explain that in greater details, because it's just
beautiful :-)

 M  +53 -109   loader.cpp  
 M  +5 -14     loader.h  


--- trunk/KDE/kdelibs/khtml/misc/loader.cpp #1096619:1096620
@@ -54,7 +54,6 @@
 
 // default cache size
 #define DEFCACHESIZE 2096*1024
-#define MAX_JOB_COUNT 32
 
 //#include <qasyncio.h>
 //#include <qasyncimageio.h>
@@ -243,8 +242,12 @@
     m_hadError = false;
     m_wasBlocked = false;
     m_err = 0;
-    // load the file
-    Cache::loader()->load(dl, this, false, true /*highPriority*/);
+    // load the file.
+    // Style sheets block rendering, they are therefore the higher priority item.
+    // Do |not| touch the priority value unless you conducted thorough tests and
+    // can back your choice with meaningful data, testing page load time and
+    // time to first paint.
+    Cache::loader()->load(dl, this, false, -8);
     m_loading = true;
 }
 
@@ -349,8 +352,10 @@
     // But some websites think their scripts are <some wrong mimetype here>
     // and refuse to serve them if we only accept application/x-javascript.
     setAccept( QLatin1String("*/*") );
-    // load the file
-    Cache::loader()->load(dl, this, false);
+    // load the file.
+    // Scripts block document parsing. They are therefore second in our list of most
+    // desired resources.
+    Cache::loader()->load(dl, this, false/*incremental*/, -6);
     m_loading = true;
     m_hadError = false;
 }
@@ -652,18 +657,18 @@
 
 void CachedImage::imageHasGeometry(khtmlImLoad::Image* /*img*/, int width, int \
height)  {
-#ifdef LOADER_DEBUG
+
     kDebug(6060) << this << " got geometry "<< width << "x" << height;
-#endif
+
     do_notify(QRect(0, 0, width, height));
 }
 
 void CachedImage::imageChange     (khtmlImLoad::Image* /*img*/, QRect region)
 {
-#ifdef LOADER_DEBUG
+
     kDebug(6060) << "Image " << this << " change " <<
         region.x() << "," << region.y() << ":" << region.width() << "x" << \
                region.height() << endl;
-#endif
+
     //### this is overly conservative -- I guess we need to also specify reason,
     //e.g. repaint vs. changed !!!
     delete bg;
@@ -688,9 +693,9 @@
 
 void CachedImage::imageDone(khtmlImLoad::Image* /*img*/)
 {
-#ifdef LOADER_DEBUG
+//#ifdef LOADER_DEBUG
     kDebug(6060)<<"Image is done:" << this;
-#endif
+//#endif
     m_status = Persistent;
     m_loading = false;
     doNotifyFinished();
@@ -914,9 +919,9 @@
             }
 
             // set size of image.
-#ifdef CACHE_DEBUG
+
             kDebug(6060) << "CachedImage::data(): image is null: " << p->isNull();
-#endif
+
             if(p->isNull())
             {
                 m_hadError = true;
@@ -964,7 +969,7 @@
     : CachedObject(url, Sound, _cachePolicy, 0)
 {
     setAccept( QLatin1String("*/*") ); // should be whatever phonon would accept...
-    Cache::loader()->load(dl, this, false);
+    Cache::loader()->load(dl, this, false/*incremental*/, 2);
     m_loading = true;
 }
 
@@ -1006,7 +1011,10 @@
     : CachedObject(url, Font, _cachePolicy, 0)
 {
     setAccept( QLatin1String("*/*") );
-    Cache::loader()->load(dl, this, true /*highPriority*/);
+    // Fonts are desired early because their absence will lead to a page being \
rendered +    // with a default replacement, then the text being re-rendered with the \
new font when it arrives. +    // This can be fairly disturbing for the reader - more \
than missing images for instance. +    Cache::loader()->load(dl, this, false \
/*incremental*/, -4);  m_loading = true;
 }
 
@@ -1033,6 +1041,7 @@
     // handle decoding of WOFF fonts
     int woffStatus = eWOFF_ok;
     if (int need = WOFF::getDecodedSize( m_font.constData(), m_font.size(), \
&woffStatus)) { +        kDebug(6040) << "***************************** Got WOFF \
FoNT";  m_hadError = true;
         do {
             if (WOFF_FAILURE(woffStatus))
@@ -1051,7 +1060,7 @@
     } else if (m_font.isEmpty()) {
         m_hadError = true;
     }
-
+    else kDebug(6040) << "******** #################### ********************* NON \
WOFF font";  setSize(m_font.size());
 
     m_loading = false;
@@ -1075,11 +1084,12 @@
 
 // ------------------------------------------------------------------------------------------
  
-Request::Request(DocLoader* dl, CachedObject *_object, bool _incremental)
+Request::Request(DocLoader* dl, CachedObject *_object, bool _incremental, int \
_priority)  {
     object = _object;
     object->setRequest(this);
     incremental = _incremental;
+    priority = _priority;
     m_docLoader = dl;
 }
 
@@ -1247,7 +1257,7 @@
     CachedImage* i = Cache::requestObject<CachedImage, CachedObject::Image>( this, \
fullURL, 0);  
     if (i && i->status() == CachedObject::Unknown && autoloadImages())
-        Cache::loader()->load(this, i, true);
+        Cache::loader()->load(this, i, true /*incremental*/);
 
     return i;
 }
@@ -1313,7 +1323,7 @@
             if ( status != CachedObject::Unknown )
                 continue;
 
-            Cache::loader()->load(this, img, true);
+            Cache::loader()->load(this, img, true /*incremental*/);
         }
     }
 }
@@ -1367,85 +1377,52 @@
 
 Loader::Loader() : QObject()
 {
-    connect(&m_timer, SIGNAL(timeout()), this, SLOT( servePendingRequests() ) );
-    m_highPriorityRequestPending = 0;
 }
 
 Loader::~Loader()
 {
-    delete m_highPriorityRequestPending;
-    qDeleteAll(m_requestsPending);
     qDeleteAll(m_requestsLoading);
 }
 
-void Loader::load(DocLoader* dl, CachedObject *object, bool incremental, bool \
highPriority) +void Loader::load(DocLoader* dl, CachedObject *object, bool \
incremental, int priority)  {
-    Request *req = new Request(dl, object, incremental);
-    if (highPriority && !m_highPriorityRequestPending) {
-        m_highPriorityRequestPending = req;
-    } else {
-        if (highPriority) {
-            m_requestsPending.prepend(req);
-        } else {
-            m_requestsPending.append(req);
-        }
-        highPriority = false;
-    }
-
+    Request *req = new Request(dl, object, incremental, priority);
+    scheduleRequest(req);
     emit requestStarted( req->m_docLoader, req->object );
-
-    if (highPriority) {
-        servePendingRequests();
-    } else {
-        m_timer.setSingleShot(true);
-        m_timer.start(0);
-    }
 }
 
-void Loader::servePendingRequests()
+void Loader::scheduleRequest(Request* req)
 {
-    while ( (m_highPriorityRequestPending != 0 || m_requestsPending.count() != 0) && \
                (m_requestsLoading.count() < MAX_JOB_COUNT) )
-    {
-        // get the first pending request
-        Request *req = m_highPriorityRequestPending ? m_highPriorityRequestPending : \
                m_requestsPending.takeFirst();
-
 #ifdef LOADER_DEBUG
   kDebug( 6060 ) << "starting Loader url=" << req->object->url().string();
 #endif
 
-        KUrl u(req->object->url().string());
-        KIO::TransferJob* job = KIO::get( u, KIO::NoReload, KIO::HideProgressInfo \
/*no GUI*/); +    KUrl u(req->object->url().string());
+    KIO::TransferJob* job = KIO::get( u, KIO::NoReload, KIO::HideProgressInfo /*no \
GUI*/);  
-        job->addMetaData("cache", \
                KIO::getCacheControlString(req->object->cachePolicy()));
-        if (!req->object->accept().isEmpty())
-            job->addMetaData("accept", req->object->accept());
-        if ( req->m_docLoader )
+    job->addMetaData("cache", \
KIO::getCacheControlString(req->object->cachePolicy())); +    if \
(!req->object->accept().isEmpty()) +        job->addMetaData("accept", \
req->object->accept()); +    if ( req->m_docLoader )
+    {
+        job->addMetaData( "referrer",  req->m_docLoader->doc()->URL().url() );
+         KHTMLPart *part = req->m_docLoader->part();
+        if (part )
         {
-            job->addMetaData( "referrer",  req->m_docLoader->doc()->URL().url() );
-
-            KHTMLPart *part = req->m_docLoader->part();
-            if (part )
-            {
-                job->addMetaData( "cross-domain", part->toplevelURL().url() );
-                if (part->widget())
-                    job->ui()->setWindow (part->widget()->topLevelWidget());
-            }
+            job->addMetaData( "cross-domain", part->toplevelURL().url() );
+            if (part->widget())
+                job->ui()->setWindow (part->widget()->topLevelWidget());
         }
+    }
 
-        connect( job, SIGNAL( result( KJob * ) ), this, SLOT( slotFinished( KJob * ) \
                ) );
-        connect( job, SIGNAL( mimetype( KIO::Job *, const QString& ) ), this, SLOT( \
                slotMimetype( KIO::Job *, const QString& ) ) );
-        connect( job, SIGNAL( data( KIO::Job*, const QByteArray &)),
-                 SLOT( slotData( KIO::Job*, const QByteArray &)));
+    connect( job, SIGNAL( result( KJob * ) ), this, SLOT( slotFinished( KJob * ) ) \
); +    connect( job, SIGNAL( mimetype( KIO::Job *, const QString& ) ), this, SLOT( \
slotMimetype( KIO::Job *, const QString& ) ) ); +    connect( job, SIGNAL( data( \
KIO::Job*, const QByteArray &)), +             SLOT( slotData( KIO::Job*, const \
QByteArray &)));  
-        if ( req->object->schedule() )
-            KIO::Scheduler::scheduleJob( job );
+    KIO::Scheduler::setJobPriority( job, req->priority );
 
-        m_requestsLoading.insertMulti(job, req);
-        if (m_highPriorityRequestPending) {
-            m_highPriorityRequestPending = 0;
-            break;
-        }
-    }
+    m_requestsLoading.insertMulti(job, req);
 }
 
 void Loader::slotMimetype( KIO::Job *j, const QString& s )
@@ -1523,11 +1500,6 @@
 #endif
 
   delete r;
-
-  if ( (m_highPriorityRequestPending != 0 || m_requestsPending.count() != 0) && \
                (m_requestsLoading.count() < MAX_JOB_COUNT / 2) ) {
-      m_timer.setSingleShot(true);
-      m_timer.start(0);
-  }
 }
 
 void Loader::slotData( KIO::Job*job, const QByteArray &data )
@@ -1550,13 +1522,6 @@
 int Loader::numRequests( DocLoader* dl ) const
 {
     int res = 0;
-    if (m_highPriorityRequestPending && m_highPriorityRequestPending->m_docLoader == \
                dl)
-        res++;
-
-    foreach( Request* req, m_requestsPending )
-        if ( req->m_docLoader == dl )
-            res++;
-
     foreach( Request* req, m_requestsLoading)
         if ( req->m_docLoader == dl )
             res++;
@@ -1566,27 +1531,6 @@
 
 void Loader::cancelRequests( DocLoader* dl )
 {
-    if (m_highPriorityRequestPending && m_highPriorityRequestPending->m_docLoader == \
                dl) {
-        CDEBUG << "canceling high priority pending request for " << \
                m_highPriorityRequestPending->object->url().string() << endl;
-        Cache::removeCacheEntry( m_highPriorityRequestPending->object );
-        delete m_highPriorityRequestPending;
-        m_highPriorityRequestPending = 0;
-    }
-
-    QMutableLinkedListIterator<Request*> pIt( m_requestsPending );
-    while ( pIt.hasNext() ) {
-        Request* cur = pIt.next();
-        if ( cur->m_docLoader == dl )
-        {
-            CDEBUG << "canceling pending request for " << \
                cur->object->url().string() << endl;
-            Cache::removeCacheEntry( cur->object );
-            pIt.remove();
-            delete cur;
-        }
-    }
-
-    //kDebug( 6060 ) << "got " << m_requestsLoading.count() << "loading requests";
-
     QMutableHashIterator<KIO::Job*,Request*> lIt( m_requestsLoading );
     while ( lIt.hasNext() )
     {
--- trunk/KDE/kdelibs/khtml/misc/loader.h #1096619:1096620
@@ -163,7 +163,6 @@
 
 	bool isExpired() const;
 
-        virtual bool schedule() const { return false; }
 	virtual void finish();
 
         /**
@@ -229,7 +228,6 @@
 	virtual void data( QBuffer &buffer, bool eof );
 	virtual void error( int err, const char *text );
 
-        virtual bool schedule() const { return true; }
         void setCharsetHint( const QString& charset ) { m_charsetHint = charset; }
         void setCharset( const QString& charset ) { m_charset = charset; }
         QString checkCharset(const QByteArray& buffer ) const;
@@ -261,8 +259,6 @@
 	virtual void data( QBuffer &buffer, bool eof );
 	virtual void error( int err, const char *text );
 
-        virtual bool schedule() const { return false; }
-
 	void checkNotify();
 
         bool isLoaded() const { return !m_loading; }
@@ -318,8 +314,6 @@
         void pauseAnimations();
         void resumeAnimations();
 
-        virtual bool schedule() const { return true; }
-
 	virtual void finish();
 
 
@@ -379,7 +373,6 @@
 	virtual void ref(CachedObjectClient *consumer);
 	virtual void data( QBuffer &buffer, bool eof );
 	virtual void error( int err, const char *text );
-        virtual bool schedule() const { return false; }
 
 	void checkNotify();
 
@@ -402,7 +395,6 @@
 	virtual void ref(CachedObjectClient *consumer);
 	virtual void data( QBuffer &buffer, bool eof );
 	virtual void error( int err, const char *text );
-        virtual bool schedule() const { return false; }
 
 	void checkNotify();
 
@@ -475,9 +467,10 @@
     class Request
     {
     public:
-	Request(DocLoader* dl, CachedObject *_object, bool _incremental);
+	Request(DocLoader* dl, CachedObject *_object, bool _incremental, int priority);
 	~Request();
 	bool incremental;
+	int priority; // -10 to 10, smaller values mean higher priority
 	QBuffer m_buffer;
 	CachedObject *object;
         DocLoader* m_docLoader;
@@ -495,7 +488,7 @@
 	Loader();
 	~Loader();
 
-	void load(DocLoader* dl, CachedObject *object, bool incremental = true, bool \
highPriority = false); +	void load(DocLoader* dl, CachedObject *object, bool \
incremental = true, int priority = 0);  
         int numRequests( DocLoader* dl ) const;
         void cancelRequests( DocLoader* dl );
@@ -512,13 +505,11 @@
 	void slotFinished( KJob * );
 	void slotMimetype( KIO::Job *, const QString& s);
 	void slotData( KIO::Job *, const QByteArray & );
-	void servePendingRequests();
 
     protected:
-	QLinkedList<Request*> m_requestsPending;
-	Request* m_highPriorityRequestPending;
+        void scheduleRequest(Request* req);
+
 	QHash<KIO::Job*,Request*> m_requestsLoading;
-        QTimer m_timer;     
     };
 
         /**


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic