Results 1 to 9 of 9

Thread: [RESOLVED] Caching Dynamic Content?

  1. #1
    Join Date
    Dec 2007

    resolved [RESOLVED] Caching Dynamic Content?

    Does content that comes from PHP and MySQL, like a forum or blog, get cached by HTTP headers?

  2. #2
    Join Date
    Nov 2008
    By default most servers are not configured to send an Expires or Cache-Control header for anything. A server that's been properly configured (which most aren't) should be sending one or both of these headers for some elements, usually "static" content such as images, scripts, css etc. The actual page/script files themselves normally shouldn't be cached otherwise updated content will never be detected. It's easy enough to check what your particular server is doing by just looking at the response headers though. Caching of dynamic content is normally done server-side by writing evaluated content to disk and serving it from there for a certain time. Obviously this doesn't avoid the HTTP request but does mean you don't have to process once per request.
    Last edited by Mindzai; 10-27-2009 at 04:48 AM.

  3. #3
    Join Date
    Dec 2007
    What I'm concerned about is my vBulletin forum. I've set it up not to cache, but because of that (I think, anyway), it's causing an Amazon ad to have to load every time a new page is requested. I'm worried about setting up caching, though, because I don't want it to keep people from viewing new posts.

  4. #4
    Join Date
    Nov 2008
    Set your server to only send the Expires server for images then You can use the FilesMatch directive with Apache. You should find that the image is not actually being downloaded again though, the server should be sending a 304 response if the user has it in cache and it hasn't changed on the server. The purpose of the Expires header is to prevent the HTTP request all together, which is obviously a performance boost.

  5. #5
    Join Date
    Nov 2008
    I just checked your forum and it's rotating images from amazon so there is an inevitable amount of new requests, but some were sending 304 responses. If you cache these images (and css + js) with a far-future expires header I expect your users will thank you. You could also enable gzipping for the css and js as well.

  6. #6
    Join Date
    Dec 2007
    Quote Originally Posted by Mindzai View Post
    I just checked your forum and it's rotating images from amazon so there is an inevitable amount of new requests, but some were sending 304 responses. If you cache these images (and css + js) with a far-future expires header I expect your users will thank you. You could also enable gzipping for the css and js as well.
    Okay, say that again, but this time a little more slowly and in a bit more detail (code examples would help) Haha, sorry, but I'm not near as good at this as most of the people here.

  7. #7
    Join Date
    Nov 2008
    When a client (eg a web browser) requests a web page, the first thing it asks the server for is the HTML (or whatever) document. It then starts parsing this document looking for other resources such as javascript files, css files, images etc. When it comes across another one of these resources which needs to be loaded, the client fires of another request to the relevant server, which returns the resource.

    Take an <img> tag as an example. The client will send a request to the relevant server (specified in the src attribute of the <img> tag) asking for the image, which the server then returns. When the browser gets the image, it saves it in it's cache (assuming it's cache is enabled, but I expect it's only us web developers who disable caches!).

    The next time it comes across the same image anywhere, the client checks in its cache to see if it already has the image. It does, but how does it know that the image hasn't been changed on the server? To be certain, it takes the modified time of the image (which is sent by the server along with the image) and makes a request to the server along the lines of "I have a version of image x which was modified on this date at this time. Do I have the latest version?". The server then responds by either confirming that the client does indeed have the latest version (by sending a 304 response code), or else if the image has been modified, sending the new version.

    This is the default behaviour of most web servers. It saves bandwidth when a file is cached since the few bytes of text it takes to check that the cached version is current is insignificant compared to just downloading the resource again each time. However, the client still needs to make an HTTP request to check it has a current version, and since browsers only make a limited number of concurrent HTTP requests, this itself is the biggest cause of slow-loading pages.

    The fix for this is to configure the server in such a way that when it sends a resource to the browser, it also sends a HTTP header (a small bit of textual info) which says to the client ("I promise this image wont be modified for x hours/days/weeks/months/years etc"). This means that the client can avoid sending the HTTP request to check it has the latest version, because the server told it right from the start how long the resource would be valid for.

    To set this up, the best way is to use Apache's mod_expires. Say for example you want to specify that all images, css and javascript are valid for the next month, you would add the following to your Apache config:

    <FilesMatch "\.(gif|jpe?g|png|js|css)$">
      ExpiresDefault "access plus 1 month"
    Now the problem you have is that you don't have control of amazon's server configs, so enabling caching for their images is an issue. However on your forum home page, I count 95 image requests coming from your own domain, which took me 6 seconds to load over a 20meg connection with my browser's cache disabled, and almost 2 seconds with the cache enabled - and I'm using a modern browser which runs multiple HTTP requests for images concurrently. If your users are using a (not much) older browser which does 2 at once, they are in for a long wait. Javascript is even worse - since the browser halts all other requests while scripts are being requested (to ensure they load in the correct order), checking 6 scripts took me as long as all of the images.

    In total I spent 4.5 out of 6 seconds on unnecessary requests. 4.5 seconds doesn't sound like a very long time, but it really is quite a lot, and I'm on a very quick connection. Given you could avoid over 100 round trips to the server with just 3 lines of code, it makes sense to do it.

    Even better, if you serve these resources from a subdomain browsers will request more items at once.

    As for gzipping, it is the technique used to compress textual content before sending it to the client. You have over 100KB of textual content (html, css and js) for your forum home page. Gzipping it will probably cut this in half. Gzipping can be enabled via Apache's mod_deflate. To set it up, add the following to your server's config:

    <Location />
    # Insert filter
    SetOutputFilter DEFLATE
    # Netscape 4.x has some problems...
    BrowserMatch ^Mozilla/4 gzip-only-text/html
    # Netscape 4.06-4.08 have some more problems
    BrowserMatch ^Mozilla/4\.0[678] no-gzip
    # MSIE masquerades as Netscape, but it is fine
    # BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
    # NOTE: Due to a bug in mod_setenvif up to Apache 2.0.48
    # the above regex won't work. You can use the following
    # workaround to get the desired effect:
    BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
    # Don't compress images
    SetEnvIfNoCase Request_URI \
    \.(?:gif|jpe?g|png)$ no-gzip dont-vary
    # Make sure proxies don't deliver the wrong content
    Header append Vary User-Agent env=!dont-vary
    Hopefully that clarifies it a bit.
    Last edited by Mindzai; 10-29-2009 at 06:30 AM.

  8. #8
    Join Date
    Dec 2007
    Okay, this is what I have in my .htaccess file for the rest of my site (e.g. not the forum).

    # start caching
    ExpiresActive On
    # expire images by one hour
    ExpiresByType image/gif A3600
    ExpiresByType image/jpeg A3600
    ExpiresByType image/png A3600
    # expire html, css, and javascripp
    ExpiresByType text/html A1800
    ExpiresByType text/css A172800
    ExpiresByType text/javascript A172800
    Could I do the first bit of code you gave me by this method? This is another Apache Module I think. I honestly don't remember what it's called, but I figured it must be different than the syntax in your code.

    And thanks I'll definitely look into mod_deflate.

  9. #9
    Join Date
    Dec 2007
    Actually, now that I think about it, do you need the location tags in the .htaccess file? You said config. I'm not sure if that means .htaccess or a file that only my host has access to.

    **EDIT: Nevermind. I decided to try it, and after removing the location tags, it works, and cut down a fair amount of bytes! Thanks so much Mindzai
    Last edited by Joseph Witchard; 11-01-2009 at 12:01 AM.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
HTML5 Development Center



X vBulletin 4.2.2 Debug Information

  • Page Generation 0.36652 seconds
  • Memory Usage 2,946KB
  • Queries Executed 15 (?)
More Information
Template Usage (34):
  • (1)ad_footer_end
  • (1)ad_footer_start
  • (1)ad_global_above_footer
  • (1)ad_global_below_navbar
  • (1)ad_global_header1
  • (1)ad_global_header2
  • (1)ad_navbar_below
  • (1)ad_showthread_firstpost_sig
  • (1)ad_showthread_firstpost_start
  • (1)ad_thread_first_post_content
  • (1)ad_thread_last_post_content
  • (3)bbcode_code
  • (1)bbcode_quote
  • (1)footer
  • (1)forumjump
  • (1)forumrules
  • (1)gobutton
  • (1)header
  • (1)headinclude
  • (1)headinclude_bottom
  • (9)memberaction_dropdown
  • (1)navbar
  • (4)navbar_link
  • (1)navbar_moderation
  • (1)navbar_noticebit
  • (1)navbar_tabs
  • (2)option
  • (9)postbit
  • (9)postbit_onlinestatus
  • (9)postbit_wrapper
  • (1)spacer_close
  • (1)spacer_open
  • (1)tagbit_wrapper 

Phrase Groups Available (6):
  • global
  • inlinemod
  • postbit
  • posting
  • reputationlevel
  • showthread
Included Files (26):
  • ./showthread.php
  • ./global.php
  • ./includes/class_bootstrap.php
  • ./includes/init.php
  • ./includes/class_core.php
  • ./includes/config.php
  • ./includes/functions.php
  • ./includes/functions_navigation.php
  • ./includes/class_friendly_url.php
  • ./includes/class_hook.php
  • ./includes/class_bootstrap_framework.php
  • ./vb/vb.php
  • ./vb/phrase.php
  • ./includes/functions_facebook.php
  • ./includes/functions_calendar.php
  • ./includes/functions_bigthree.php
  • ./includes/class_postbit.php
  • ./includes/class_bbcode.php
  • ./includes/functions_reputation.php
  • ./includes/functions_notice.php
  • ./packages/vbattach/attach.php
  • ./vb/types.php
  • ./vb/cache.php
  • ./vb/cache/db.php
  • ./vb/cache/observer/db.php
  • ./vb/cache/observer.php 

Hooks Called (70):
  • init_startup
  • friendlyurl_resolve_class
  • init_startup_session_setup_start
  • database_pre_fetch_array
  • database_post_fetch_array
  • init_startup_session_setup_complete
  • global_bootstrap_init_start
  • global_bootstrap_init_complete
  • cache_permissions
  • fetch_threadinfo_query
  • fetch_threadinfo
  • fetch_foruminfo
  • load_show_variables
  • load_forum_show_variables
  • global_state_check
  • global_bootstrap_complete
  • global_start
  • style_fetch
  • global_setup_complete
  • showthread_start
  • showthread_getinfo
  • strip_bbcode
  • friendlyurl_clean_fragment
  • friendlyurl_geturl
  • forumjump
  • cache_templates
  • cache_templates_process
  • template_register_var
  • template_render_output
  • fetch_template_start
  • fetch_template_complete
  • parse_templates
  • fetch_musername
  • notices_check_start
  • notices_noticebit
  • process_templates_complete
  • friendlyurl_redirect_canonical
  • showthread_post_start
  • showthread_query_postids
  • showthread_query
  • bbcode_fetch_tags
  • bbcode_create
  • showthread_postbit_create
  • postbit_factory
  • postbit_display_start
  • bbcode_parse_start
  • postbit_imicons
  • bbcode_parse_complete_precache
  • bbcode_parse_complete
  • postbit_display_complete
  • memberaction_dropdown
  • tag_fetchbit_complete
  • forumrules
  • navbits
  • navbits_complete
  • build_navigation_data
  • build_navigation_array
  • check_navigation_permission
  • process_navigation_links_start
  • process_navigation_links_complete
  • set_navigation_menu_element
  • build_navigation_menudata
  • build_navigation_listdata
  • build_navigation_list
  • set_navigation_tab_main
  • set_navigation_tab_fallback
  • navigation_tab_complete
  • fb_like_button
  • showthread_complete
  • page_templates