From d7f49d64d3e2d808e5fb037faef53ff5a5510909 Mon Sep 17 00:00:00 2001
From: thomascube <thomas@roundcube.net>
Date: Thu, 28 May 2009 16:19:02 -0400
Subject: [PATCH] Speedup UI by using CSS sprites and etags/expires/deflate for static files

---
 skins/default/common.css                   |   40 ++++-----
 skins/default/images/display/icons.png     |    0 
 CHANGELOG                                  |    1 
 INSTALL                                    |   82 ++++++++++++++++++++
 skins/default/images/icons/folders.png     |    0 
 skins/default/mail.css                     |   29 +++----
 skins/default/images/icons/folders.gif     |    0 
 skins/default/images/display/icons.gif     |    0 
 skins/default/images/listheader.gif        |    0 
 skins/default/images/icons/sort.gif        |    0 
 /dev/null                                  |    0 
 skins/default/ie6hacks.css                 |   14 +++
 skins/default/settings.css                 |    3 
 skins/default/images/taskicons.gif         |    0 
 skins/default/images/buttons/inbox_sel.png |    0 
 .htaccess                                  |   18 ++++
 skins/default/addresses.css                |    3 
 17 files changed, 146 insertions(+), 44 deletions(-)

diff --git a/.htaccess b/.htaccess
index 05a2ed7..98c5fec 100644
--- a/.htaccess
+++ b/.htaccess
@@ -28,6 +28,22 @@
 RewriteEngine On
 RewriteRule ^favicon.ico$ skins/default/images/favicon.ico
 </IfModule>
- 
+
+<IfModule mod_deflate.c>
+SetOutputFilter DEFLATE
+</IfModule>
+
+<IfModule mod_headers.c>
+# replace 'append' with 'merge' for Apache version 2.2.9 and later
+Header append Cache-Control public env=!NO_CACHE
+</IfModule>
+
+<IfModule mod_expires.c>
+ExpiresActive On
+ExpiresDefault "access plus 1 month"
+</IfModule>
+
+FileETag MTime
+
 Order deny,allow
 Allow from all
diff --git a/CHANGELOG b/CHANGELOG
index 4cdb5e8..d9d14a2 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
 CHANGELOG RoundCube Webmail
 ===========================
 
+- Speedup UI by using CSS sprites and etags/expires/deflate in Apache config (#1484858,#1485800)
 - Support UID EXPUNGE: remove only moved/deleted messages
 - Add drag cancelling with ESC key (#1484344)
 - Support initial identity name from virtuser_query (#1484003)
diff --git a/INSTALL b/INSTALL
index 42fd4bb..82f01ce 100644
--- a/INSTALL
+++ b/INSTALL
@@ -75,6 +75,11 @@
 an example how you can setup the sqlite.db for roundcube:
 
 # sqlite -init SQL/sqlite.initial.sql sqlite.db
+Loading resources from SQL/sqlite.initial.sql
+SQLite version 2.8.16
+Enter ".help" for instructions
+sqlite> .exit
+# chmod o+rw sqlite.db
 
 Make sure your configuration points to the sqlite.db file and that the
 webserver can write to the file and the directory containing the file.
@@ -119,3 +124,80 @@
 please refer to the instructions in UPGRADING guide.
 
 
+OPTIMISING
+==========
+
+There are two forms of optimisation here, compression and caching, both aimed
+at increasing an end user's experience using RoundCube Webmail. Compression
+allows the static web pages to be delivered with less bandwidth. The index.php
+of RoundCube Webmail already enables compression on its output. The settings
+below allow compression to occur for all static files. Caching sets HTTP 
+response headers that enable a user's web client to understand what is static
+and how to cache it.
+
+The caching directives used are:
+ * Etags - sets at tag so the client can request is the page has changed
+ * Cache-control - defines the age of the page and that the page is 'public'
+   This enables clients to cache javascript files that don't have private 
+   information between sessions even if using HTTPS. It also allows proxies
+   to share the same cached page between users.
+ * Expires - provides another hint to increase the lifetime of static pages.
+
+For more information refer to RFC 2616.
+
+Side effects:
+-------------
+These directives are designed for production use. If you are using this in
+a development environment you may get horribly confused if your webclient
+is caching stuff that you changed on the server. Disabling the expires 
+parts below should save you some grief.
+
+If you are changing the skins, it is recommended that you copy content to 
+a different directory apart from 'default'.
+
+Apache:
+-------
+To enable these features in apache the following modules need to be enabled:
+ * mod_compress
+ * mod_expire
+ * mod_headers
+
+The optimisation is already included in the .htaccess file in the top 
+directory of your installation.
+
+If you are using Apache version 2.2.9 and later, in the .htaccess file
+change the 'append' word to 'merge' for a more correct response. Keeping
+as 'append' shouldn't cause any problems though changing to merge will 
+eliminate the possibility of duplicate 'public' headers in Cache-control.
+
+Lighttpd:
+---------
+With Lightty the addition of Expire: tags by mod_expire is incompatible with
+the addition of "Cache-control: public". Using Cache-control 'public' is 
+used below as it is assumed to give a better caching result.
+
+Enable modules in server.modules:
+    "mod_setenv"
+    "mod_compress"
+
+Mod_compress is a server side cache of compressed files to improve its performance.
+
+$HTTP["host"] == "www.example.com" {
+
+    static-file.etags = "enable"
+    # http://redmine.lighttpd.net/projects/lighttpd/wiki/Etag.use-mtimeDetails
+    etag.use-mtime = "enable"
+
+    # http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:ModSetEnv
+    $HTTP["url"] =~ "^/roundcubemail/(plugins|skins|program)" {
+        setenv.add-response-header  = ( "Cache-Control" => "public, max-age=2592000")
+    }
+
+    # http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:ModCompress
+    # set compress.cache-dir to somewhere outside the docroot.
+    compress.cache-dir   = var.statedir + "/cache/compress"
+
+    compress.filetype = ("text/plain", "text/html", "text/javascript", "text/css", "text/xml", "image/gif", "image/png")
+}
+
+
diff --git a/skins/default/addresses.css b/skins/default/addresses.css
index d864811..70b148a 100644
--- a/skins/default/addresses.css
+++ b/skins/default/addresses.css
@@ -171,8 +171,7 @@
   color: #333;
   font-size: 11px;
   font-weight: bold;
-  background-color: #EBEBEB;
-  background-image: url(images/listheader_aqua.gif);
+  background: url('images/listheader.gif') top left repeat-x #CCC;
   white-space: nowrap;
 }
 
diff --git a/skins/default/common.css b/skins/default/common.css
index 046843e..24762f9 100644
--- a/skins/default/common.css
+++ b/skins/default/common.css
@@ -151,15 +151,13 @@
   z-index: 2;
 }
 
-#taskbar a,
-#taskbar a:active,
-#taskbar a:visited
+#taskbar a
 {
   font-size: 11px;
   color: #666666;
   text-decoration: none;
   padding: 6px 14px 6px 27px;
-  background-repeat: no-repeat;
+  background: url('images/taskicons.gif') no-repeat;
 }
 
 #taskbar a:hover
@@ -167,24 +165,24 @@
   color: #333333;
 }
 
-a.button-mail
+#taskbar a.button-mail
 {
-  background-image: url(images/buttons/mail.gif);
+  background-position: 0 0;
 }
 
-a.button-addressbook
+#taskbar a.button-addressbook
 {
-  background-image: url(images/buttons/addressbook.gif);
+  background-position: 0 -25px;
 }
 
-a.button-settings
+#taskbar a.button-settings
 {
-  background-image: url(images/buttons/settings.gif);
+  background-position: 0 -50px;
 }
 
-a.button-logout
+#taskbar a.button-logout
 {
-  background-image: url(images/buttons/logout.gif);
+  background-position: 0 -75px;
 }
 
 
@@ -203,15 +201,15 @@
 {
   width: 400px;
   margin: 0px auto;
-  height: 24px;
-  min-height: 24px;
+  height: 22px;
+  min-height: 22px;
   padding: 8px 10px 8px 46px;
 }
 
 #message div.notice,
 #remote-objects-message
 {
-  background: url(images/display/info.png) 6px 3px no-repeat;
+  background: url('images/display/icons.png') 6px 3px no-repeat;
   background-color: #F7FDCB;
   border: 1px solid #C2D071;
 }
@@ -219,21 +217,21 @@
 #message div.error,
 #message div.warning
 {
-  background: url(images/display/warning.png) 6px 3px no-repeat;
+  background: url('images/display/icons.png') 6px -97px no-repeat;
   background-color: #EF9398;
   border: 1px solid #DC5757;
 }
 
 #message div.confirmation
 {
-  background: url(images/display/confirm.png) 6px 3px no-repeat;
+  background: url('images/display/icons.png') 6px -47px no-repeat;
   background-color: #A6EF7B;
   border: 1px solid #76C83F;
 }
 
 #message div.loading
 {
-  background: url(images/display/loading.gif) 6px 3px no-repeat;
+  background: url('images/display/loading.gif') 6px 3px no-repeat;
   background-color: #EBEBEB;
   border: 1px solid #CCCCCC;
 }
@@ -274,8 +272,7 @@
   color: #333;
   font-size: 11px;
   font-weight: bold;
-  background-color: #EBEBEB;
-  background-image: url(images/listheader_aqua.gif);
+  background: url('images/listheader.gif') top left repeat-x #CCC;
 }
 
 /***** common table settings ******/
@@ -287,8 +284,7 @@
   vertical-align: middle;
   border-bottom: 1px solid #999999;
   color: #333333;
-  background-color: #EBEBEB;
-  background-image: url(images/listheader_aqua.gif); 
+  background: url('images/listheader.gif') top left repeat-x #CCC;
   font-size: 11px;
   font-weight: bold;
 }
diff --git a/skins/default/ie6hacks.css b/skins/default/ie6hacks.css
index d86fbed..53c2871 100644
--- a/skins/default/ie6hacks.css
+++ b/skins/default/ie6hacks.css
@@ -5,6 +5,15 @@
   behavior: url('skins/default/pngbehavior.htc');
 }
 
+#message div.notice,
+#message div.error,
+#message div.warning,
+#message div.confirmation,
+#remote-objects-message
+{
+  background-image: url(images/display/icons.gif);
+}
+
 ul.toolbarmenu li
 {
   width: 130px;
@@ -15,4 +24,7 @@
   background-image: url('images/messageactions.gif');
 }
 
-
+#mailboxlist li
+{
+  background-image: url('images/icons/folders.gif');
+}
\ No newline at end of file
diff --git a/skins/default/images/buttons/addressbook.gif b/skins/default/images/buttons/addressbook.gif
deleted file mode 100644
index d8c0c17..0000000
--- a/skins/default/images/buttons/addressbook.gif
+++ /dev/null
Binary files differ
diff --git a/skins/default/images/buttons/addressbook.png b/skins/default/images/buttons/addressbook.png
deleted file mode 100644
index 359f33e..0000000
--- a/skins/default/images/buttons/addressbook.png
+++ /dev/null
Binary files differ
diff --git a/skins/default/images/buttons/inbox_sel.png b/skins/default/images/buttons/inbox_sel.png
index ce65ca7..fe1fa05 100644
--- a/skins/default/images/buttons/inbox_sel.png
+++ b/skins/default/images/buttons/inbox_sel.png
Binary files differ
diff --git a/skins/default/images/buttons/mail.gif b/skins/default/images/buttons/mail.gif
deleted file mode 100644
index 712735d..0000000
--- a/skins/default/images/buttons/mail.gif
+++ /dev/null
Binary files differ
diff --git a/skins/default/images/buttons/mail.png b/skins/default/images/buttons/mail.png
deleted file mode 100644
index 30c1e76..0000000
--- a/skins/default/images/buttons/mail.png
+++ /dev/null
Binary files differ
diff --git a/skins/default/images/buttons/settings.gif b/skins/default/images/buttons/settings.gif
deleted file mode 100644
index 9c609b7..0000000
--- a/skins/default/images/buttons/settings.gif
+++ /dev/null
Binary files differ
diff --git a/skins/default/images/display/confirm.png b/skins/default/images/display/confirm.png
deleted file mode 100644
index 27265f8..0000000
--- a/skins/default/images/display/confirm.png
+++ /dev/null
Binary files differ
diff --git a/skins/default/images/display/icons.gif b/skins/default/images/display/icons.gif
new file mode 100644
index 0000000..e6dfb1b
--- /dev/null
+++ b/skins/default/images/display/icons.gif
Binary files differ
diff --git a/skins/default/images/display/icons.png b/skins/default/images/display/icons.png
new file mode 100644
index 0000000..995ac30
--- /dev/null
+++ b/skins/default/images/display/icons.png
Binary files differ
diff --git a/skins/default/images/display/info.png b/skins/default/images/display/info.png
deleted file mode 100644
index 85462e4..0000000
--- a/skins/default/images/display/info.png
+++ /dev/null
Binary files differ
diff --git a/skins/default/images/display/warning.png b/skins/default/images/display/warning.png
deleted file mode 100644
index 9909617..0000000
--- a/skins/default/images/display/warning.png
+++ /dev/null
Binary files differ
diff --git a/skins/default/images/icons/folder-closed.png b/skins/default/images/icons/folder-closed.png
deleted file mode 100644
index 5cbf72a..0000000
--- a/skins/default/images/icons/folder-closed.png
+++ /dev/null
Binary files differ
diff --git a/skins/default/images/icons/folder-drafts.png b/skins/default/images/icons/folder-drafts.png
deleted file mode 100644
index d828b56..0000000
--- a/skins/default/images/icons/folder-drafts.png
+++ /dev/null
Binary files differ
diff --git a/skins/default/images/icons/folder-inbox.png b/skins/default/images/icons/folder-inbox.png
deleted file mode 100644
index 995ca81..0000000
--- a/skins/default/images/icons/folder-inbox.png
+++ /dev/null
Binary files differ
diff --git a/skins/default/images/icons/folder-junk.png b/skins/default/images/icons/folder-junk.png
deleted file mode 100644
index 06fbd49..0000000
--- a/skins/default/images/icons/folder-junk.png
+++ /dev/null
Binary files differ
diff --git a/skins/default/images/icons/folder-open.png b/skins/default/images/icons/folder-open.png
deleted file mode 100644
index 09ba4b3..0000000
--- a/skins/default/images/icons/folder-open.png
+++ /dev/null
Binary files differ
diff --git a/skins/default/images/icons/folder-sent.png b/skins/default/images/icons/folder-sent.png
deleted file mode 100644
index 2968ab5..0000000
--- a/skins/default/images/icons/folder-sent.png
+++ /dev/null
Binary files differ
diff --git a/skins/default/images/icons/folder-trash.png b/skins/default/images/icons/folder-trash.png
deleted file mode 100644
index 0712aaa..0000000
--- a/skins/default/images/icons/folder-trash.png
+++ /dev/null
Binary files differ
diff --git a/skins/default/images/icons/folders.gif b/skins/default/images/icons/folders.gif
new file mode 100644
index 0000000..b5984b8
--- /dev/null
+++ b/skins/default/images/icons/folders.gif
Binary files differ
diff --git a/skins/default/images/icons/folders.png b/skins/default/images/icons/folders.png
new file mode 100644
index 0000000..d244f32
--- /dev/null
+++ b/skins/default/images/icons/folders.png
Binary files differ
diff --git a/skins/default/images/icons/sort.gif b/skins/default/images/icons/sort.gif
new file mode 100644
index 0000000..f8f2756
--- /dev/null
+++ b/skins/default/images/icons/sort.gif
Binary files differ
diff --git a/skins/default/images/listheader.gif b/skins/default/images/listheader.gif
new file mode 100644
index 0000000..e7f5015
--- /dev/null
+++ b/skins/default/images/listheader.gif
Binary files differ
diff --git a/skins/default/images/listheader_aqua.gif b/skins/default/images/listheader_aqua.gif
deleted file mode 100644
index 59f44ea..0000000
--- a/skins/default/images/listheader_aqua.gif
+++ /dev/null
Binary files differ
diff --git a/skins/default/images/listheader_dark.gif b/skins/default/images/listheader_dark.gif
deleted file mode 100644
index cd35555..0000000
--- a/skins/default/images/listheader_dark.gif
+++ /dev/null
Binary files differ
diff --git a/skins/default/images/listheader_light.gif b/skins/default/images/listheader_light.gif
deleted file mode 100644
index 8d9e6ca..0000000
--- a/skins/default/images/listheader_light.gif
+++ /dev/null
Binary files differ
diff --git a/skins/default/images/sort_asc.gif b/skins/default/images/sort_asc.gif
deleted file mode 100644
index 2427311..0000000
--- a/skins/default/images/sort_asc.gif
+++ /dev/null
Binary files differ
diff --git a/skins/default/images/sort_desc.gif b/skins/default/images/sort_desc.gif
deleted file mode 100644
index 244db10..0000000
--- a/skins/default/images/sort_desc.gif
+++ /dev/null
Binary files differ
diff --git a/skins/default/images/taskicons.gif b/skins/default/images/taskicons.gif
new file mode 100644
index 0000000..53376c3
--- /dev/null
+++ b/skins/default/images/taskicons.gif
Binary files differ
diff --git a/skins/default/mail.css b/skins/default/mail.css
index a9c2d8d..649699b 100644
--- a/skins/default/mail.css
+++ b/skins/default/mail.css
@@ -341,8 +341,7 @@
   height: 12px;
   margin: 0;
   padding: 3px 10px 4px 10px;
-  background-color: #EBEBEB;
-  background-image: url(images/listheader_aqua.gif); 
+  background: url('images/listheader.gif') top left repeat-x #CCC;
   border-bottom: 1px solid #999;
   color: #333333;
   font-size: 11px;
@@ -378,8 +377,7 @@
   display: block;
   position: relative;
   font-size: 11px;
-  background: url(images/icons/folder-closed.png) no-repeat;
-  background-position: 5px 1px;
+  background: url('images/icons/folders.png') 5px 1px no-repeat;
   border-bottom: 1px solid #EBEBEB;
 }
 
@@ -401,37 +399,37 @@
 
 #mailboxlist li div.collapsed
 {
-  background: url(images/icons/collapsed.png) bottom right no-repeat;
+  background: url('images/icons/collapsed.png') bottom right no-repeat;
 }
 
 #mailboxlist li div.expanded
 {
-  background: url(images/icons/expanded.png) bottom right no-repeat;
+  background: url('images/icons/expanded.png') bottom right no-repeat;
 }
 
 #mailboxlist li.inbox
 {
-  background-image: url(images/icons/folder-inbox.png);
+  background-position: 5px -15px;
 }
 
 #mailboxlist li.drafts
 {
-  background-image: url(images/icons/folder-drafts.png);
+  background-position: 5px -31px;
 }
 
 #mailboxlist li.sent
 {
-  background-image: url(images/icons/folder-sent.png);
+  background-position: 5px -47px;
 }
 
 #mailboxlist li.junk
 {
-  background-image: url(images/icons/folder-junk.png);
+  background-position: 5px -63px;
 }
 
 #mailboxlist li.trash
 {
-  background-image: url(images/icons/folder-trash.png);
+  background-position: 5px -79px;
 }
 
 #mailboxlist li a
@@ -537,8 +535,7 @@
   vertical-align: middle;
   border-bottom: 1px solid #999999;
   color: #333333;
-  background-color: #EBEBEB;
-  background-image: url(images/listheader_aqua.gif); 
+  background: url('images/listheader.gif') top left repeat-x #CCC;
   font-size: 11px;
   font-weight: bold;
 }
@@ -546,17 +543,17 @@
 #messagelist thead tr td.sortedASC,
 #messagelist thead tr td.sortedDESC
 {
-  background-image: url(images/listheader_dark.gif); 
+  background-position: 0 -20px;
 }
 
 #messagelist thead tr td.sortedASC a
 {
-  background: url(images/sort_asc.gif) top right no-repeat;
+  background: url('images/icons/sort.gif') right 0 no-repeat;
 }
 
 #messagelist thead tr td.sortedDESC a
 {
-  background: url(images/sort_desc.gif) top right no-repeat;
+  background: url('images/icons/sort.gif') right -14px no-repeat;
 }
 
 #messagelist thead tr td a
diff --git a/skins/default/settings.css b/skins/default/settings.css
index f0024fc..e7c6cb5 100644
--- a/skins/default/settings.css
+++ b/skins/default/settings.css
@@ -244,8 +244,7 @@
   color: #333333;
   font-size: 11px;
   font-weight: bold;
-  background-color: #EBEBEB;
-  background-image: url(images/listheader_aqua.gif); 
+  background: url('images/listheader.gif') top left repeat-x #CCC;
 }
 
 div.settingsbox

--
Gitblit v1.9.1