Updates from azaozz RSS Toggle Comment Threads | Keyboard Shortcuts

  • Andrew Ozz 9:14 pm on December 3, 2009 Permalink | Reply  

    WordPress Developer News: WordPress 2.9 Beta 2 

    WordPress 2.9 is currently in beta and is expected to be ready in several weeks.

    Major new features for developers:
    - comments meta table
    - improved support for custom post types
    - register_theme_directory() for additional theme locations
    - back-ported JSON encode/decode for both PHP and JavaScript

    and for users:
    - oEmbed support
    - “Trash” for posts, pages and comments
    - post thumbnails support
    - basic image editor

    More details are available in the Codex http://codex.wordpress.org/Version_2.9 and on trac.

    New feature in the plugin repository: logged in users can enter compatibility information about all plugins – works / doesn’t work for several recent versions of WordPress. It is still in beta and in data collection mode. When it’s released, the collected information will be available from the wordpress.org API.

    As with every release there are hundreds of improvements and bug fixes. 410 tickets have been closed so far for the 2.9 milestone.

    One significant change is the new “trash” status for posts and comments. It works by changing the post_status or the comment_approved field to ‘trash’. If the post or the comment is restored from the trash that field is set back to it’s previous value. By default items in the trash are deleted after 30 days.

    If you use direct SQL queries you may need to exclude posts and comments that are currently in the trash. Simple example: http://core.trac.wordpress.org/changeset/12254

    Please ensure that your plugin(s) or theme(s) work as expected in WordPress 2.9-beta-2. If you have questions or comments please post them on the wp-hackers mailing list or in the Alpha/Beta forum on wordpress.org.

     
  • Andrew Ozz 8:51 pm on December 3, 2009 Permalink | Reply  

    Agenda for the December 3rd Dev Chat 

    • How do we handle security releases in the admin – Matt Martz
    • Create a post on the wp.org dev feed that highlights what breaks to plugin devs – Denis de Bernardy (we’ve started the WordPress Developer News email announcements as discussed here couple of months ago that cover this)
    • Shall we remove Gears support now or in 3.0
    • Minimum intervals between first beta and final release and between first RC and final – demetris
     
  • Andrew Ozz 3:59 am on September 26, 2009 Permalink | Reply
    Tags: ,   

    Image Editor 

    The “first run” of a simple image editor has been in WordPress 2.9-rare for about two weeks. It lets the user crop, flip and rotate an image. It also has an option to scale the original (largest) image and to restore the originally uploaded version. There is a multi-step undo and redo support. Changes can be applied to all image sizes or only the thumbnail. The initial code is by Stephan Reiter author of the Scissors plugin.

    Currently when saving an edited image all previous intermediate image sizes are kept and the meta data for them (filename, width, height) is moved to another postmeta field. This is necessary to avoid breaking any posts or pages where the image was inserted. The editing workflow (multi-undo, preview of each step) makes it unnecessary to edit an image more than once or twice, however if an image is edited 6-7 times the backup files would be 25-30.

    There are couple of ways to avoid keeping unnecessary images, we could either track when an image was used in a post or a page, or we could have “standard” names for the intermediate image sizes. Tracking image use can be somehow problematic considering all the different ways content can be published in WordPress.

    Renaming the resized images from [imagename]-150×100 to [imagename]-thumbnail, etc. seems the more viable option. This would also bring instant image updates in already published posts, however may also have some compatibility problems with plugins that expect the image size to be part of the filename.

    Trac ticket for the image editor, suggestions and patches welcome :)

     
    • Alex (Viper007Bond) 5:02 am on September 26, 2009 Permalink | Reply

      You could also just use a shortcode for the image tag, although that may not be as user friendly. Then again, if you move domains, URLs, etc. you wouldn’t have to edit the post.

      So instead of this:

      [code lang="html" light="true"]<img src="http://blog.com/wp-content/uploads/imagename-thumbnail.jpg" width="150" height="100" title="Cool image" alt="ohai" />[/code]

      You’d do this:

      [code lang="text" light="true"][image id="123" size="thumbnail" title="Cool image" alt="ohai"][/code]

      The URL, width, and height would all be dynamic and change if you changed the thumbnail size, etc. This is opposite of now where even if the filename didn’t contain the dimensions, you’re still left with hard coded width/height parameters in the image tag.

      • scribu 11:49 am on September 26, 2009 Permalink | Reply

        That would be nice. And it’s been requested several times in the past.

      • Xavier 4:47 pm on September 26, 2009 Permalink | Reply

        • Beau 9:30 pm on September 26, 2009 Permalink

          Since both uploads would have a unique id in the DB, it doesn’t matter if they have the same filename. The correct URL would be output dynamically, based on wherever it was stored (as referenced by the DB)

      • Andrew Ozz 12:57 am on September 28, 2009 Permalink | Reply

        Think this came up when we were doing the captions shortcodes a year ago and was rejected. Perhaps we can look at the pro & con again. Since all movies and other embeds will be handled by shortcodes it may make sense to extend that to include images too.

        However I see a possible problem with that. The img tag doesn’t need any processing on display but a shortcode would need quite a lot as it seems we will have to do get_post() for the attachment. Also our shortcode parsing code/API doesn’t seem optimized enough to handle large quantity of shortcodes.

        • aarondcampbell 8:20 pm on October 3, 2009 Permalink

          It is true that it can’t handle really large posts with lots of shortcodes. However, that’s definitely only affecting a very small percentage of people (if we’re really focusing on the 80-20 principle, it’s less than 20%). Do we really think that enough people will be writing stuff this long (and putting enough shortcodes in it) that we should worry about it? (That’s the post where I first ran into the issue…I tried to explain that it was just too long, but apparently it’s quite effective as it is).

          I like the shortcode idea.

        • Andrew Ozz 2:31 am on October 5, 2009 Permalink

          True, this is very rare at the moment but turning img tags into shortcodes would increase that number, perhaps a lot.

          No, don’t think we can apply the 80/20 principle here. Would that mean we can break up to 20% of all published posts? :)

          The problem is that even a shorter post with a lot of images will reach the backtrack limit or be very slow to display.

        • DD32 2:58 am on October 5, 2009 Permalink

          > or be very slow to display.

          Reminds me of the mention of storing filtered post contents along side the raw and serving those up instead of applying the expensive filters every load..

        • Andrew Ozz 3:19 am on October 5, 2009 Permalink

          Yes, post_content_filtered is still in the posts table. Think there are few plugins that do this, not sure how well though as it bypasses all ‘post_content’ filters.

        • Alex (Viper007Bond) 3:38 am on October 5, 2009 Permalink

          Perhaps storing a partially cached version would be best, i.e. just internal shortcodes. You’d break a lot of plugins if you rendered the entire content from a cached copy.

      • Jonathan Dingman 9:22 pm on October 1, 2009 Permalink | Reply

        Would that imply dynamic resizing?

        ie, if someone changed the thumbnail size after already uploading the image, would it resize on the fly? (if specifying a thumbnail in the shortcode)

      • Denis de Bernardy 11:14 pm on October 3, 2009 Permalink | Reply

        Using a shortcode here would hammer the DB unless it’s properly implemented.

        And this “it hammers the database”, btw, is the reason I had opened:

        http://core.trac.wordpress.org/ticket/10882

        I use similar code in two plugins of mine, and since you can’t rely on an attachment from being tied to a single post, I check for a post meta to make sure there are attachments (and which ones) before tossing a query.

      • Alex (Viper007Bond) 6:56 am on October 4, 2009 Permalink | Reply

        We also have to not forget about those who use TinyMCE and expect to see the image as is. A shortcode would be there as text.

        Perhaps a TinyMCE plugin could AJAX fetch the image (based on ID) and replace the shortcode with the image during editing, then put it back to the shortcode on save. That way it’d still stay a WYSIWYG.

        • aarondcampbell 9:53 pm on October 4, 2009 Permalink

          That’s a good point. It’s easy to forget about those using WYSIWYG

    • Barış Ünver 6:33 am on September 26, 2009 Permalink | Reply

      I’m concerned about the fact that WordPress is getting fatter and fatter each version. Is it really necessary? Couldn’t it be done with a plugin or something?

      Or at least, are we gonna be able to se a lighter (official) version of WordPress? LitePress v2.9.0 maybe?

      • Alex (Viper007Bond) 9:14 pm on September 30, 2009 Permalink | Reply

        Filesize (aka fat) is not directly related to performance. The image editor for example has literally zero (no joke on the literally) impact on the front page of your site for example as it’s never loaded except in the admin area.

        • Andrew Ozz 12:15 am on October 1, 2009 Permalink

          On top of that even in the admin it’s only loaded through AJAX so it doesn’t add any overhead anywhere.

      • aarondcampbell 8:22 pm on October 3, 2009 Permalink | Reply

        It’s all about the 80-20 rule. I think more than 80% of the people will use this on a regular basis. I probably won’t, but most of my clients will. I’m all for keeping code as lean as possible, but I’m also all for adding this support in. Let’s trim in other areas. Just my 2 cents.

    • Andrew Ozz 1:37 am on September 28, 2009 Permalink | Reply

      Another solution for the multiple image backup files would be to let the user decide. We can include a checkbox whether to delete the previously edited image (together with all sub-sizes). Since the suffix that is appended to the image filename contains a timestamp, we could do something like “This image was last edited 1 hour ago. If it wasn’t used in a Post since then you can remove the backup files by selecting this checkbox”.

      On the other hand even the cheapest hosting accounts seem to come with a lot of storage so deleting backups would be unnecessary. Also a plugin can add a simple GUI to search the db and return a list of unused backup images that can be deleted. Not sure if something like this would be good for core.

    • Otto 6:07 pm on September 28, 2009 Permalink | Reply

      I think the key to this problem is the following: “This is necessary to avoid breaking any posts or pages where the image was inserted.”

      Why avoid breaking those posts/pages? If somebody edits an image, then change the image itself. That’s what they will probably expect to happen.

      Having to have them go and reinsert the changed image into the page/post is confusing and unnecessary. We don’t need to save the original. The user uploaded the image, presumably they have the original. An in-place editor should simply overwrite the existing files with the new ones, not try to preserve them.

      • Andrew Ozz 12:30 am on October 1, 2009 Permalink | Reply

        True, users that know what they’re doing may expect to break old posts when editing an image. However the majority will most likely complain that “the image editor breaks all old posts!”.

        Also we cannot just replace the originally used image with the edited one as images are inserted with “width” and “height” attribs that in most cases will distort the edited image (as Viper007Bond pointed above).

  • Andrew Ozz 12:54 am on May 3, 2009 Permalink | Reply
    Tags: accessibility   

    Going through some of the accessibility improvements. 2.7 was tested with JAWS but there were some changes in the UI since then. Does anybody use JAWS or another screen reader, or know somebody that uses it? Feedback is welcome.

     
    • Ryan 8:05 am on May 3, 2009 Permalink | Reply

      I do someone who uses Jaws. I’ll send a link to this page to them in case they are keen to help out.
      I’ve sent him an email. Hopefully he’ll be keen to help out.

    • slger 1:22 pm on May 3, 2009 Permalink | Reply

      Yry NVDA http://www.marcozehe.de/articles/how-to-use-nvda-and-firefox-to-test-your-web-pages-for-accessibility/

      Is there a list of accessibility items to test? I’ll work on them.

      My biggest problem: can’t get rid of archieves. Also cannot see theme well enough to know if it looks ok. What’s the most accessible theme?

    • Ryan 10:08 pm on May 3, 2009 Permalink | Reply

      This ticket has some discussion on hidden labels.

    • Lynne 1:30 pm on May 6, 2009 Permalink | Reply

      FWIW, I know of a couple of folk who use assistive devices and who cannot use 2.7. As far as I know, they are still on 2.6.5. JAWS is only one of a number of assistive devices and even with JAWS users, proficiency varies. Accessibility with JAWS depends on the users level of experience and also on which browser they are using. EYES has the same issues. Headwands, voice recognition, etc also rely on the site being accessible and, again, these are things most of us can’t test.

      Having said that, there are a number of people, including people with disabilities, who are keen to see WordPress become fully accessible. Some just walked away after concerns about 2.7 got fobbed off with the comment that it underwent usability testing and was therefore ok. I pretty much shut up about accessibility at that time too, and although I develop sites for others on 2.7/2.7.1, my own site remains on 2.6.5 because of accessibility issues.

      Don’t try to go it alone guys – great coders are not expected to be experts in web app accessibility. If you put accessibility improvements on the roadmap for 2.9 and would consider opening a wp-accessibility mailing list for those in the accessibility field to discuss issues and fixes in, I can get a call out to the Guild of Accessible Web Designers and others I network with and get people working on this.

      Just a thought.

      • Glenda Watson Hyatt 2:40 am on May 8, 2009 Permalink | Reply

        Great point, Lynne! Involve people with disabilities who use various assistive technology in to development and testing.

      • Jane Wells 2:02 am on May 9, 2009 Permalink | Reply

        Lynne, who commented that 2.7 underwent usability testing and was therefore okay? Not any of the core team, I’m sure, as we did have someone from an accessibility company do a review for us during the 2.7 dev cycle, and we fixed as many of the things as we could. Usability and accessibility are not the same, and we all recognize that. There’s definitely room for improvement, but we absolutely are paying attention.

      • Lynne 7:07 am on May 18, 2009 Permalink | Reply

        I put in a request through wp-hackers a few weeks back, asking if we could have a wp-accessibility mailing list set up please. There are enough people interested in contributing to development and testing for accessibility that a dedicated mailing list would, IMO, be very worthwhile.

        Has there been any decision made on this yet? Accessibility discussion just gets lost in the busy wp-hackers list & that list is not perceived as the most inviting for those whose primary interest is in accessibility issues.

        • Barry 3:29 pm on July 2, 2009 Permalink

          This should be done in the next week or so.

    • Lorelle VanFossen 2:32 pm on May 6, 2009 Permalink | Reply

      Don’t forget to include Glenda Watson Hyatt of http://www.doitmyselfblog.com/ as she is an accessibility expert, WordPress fan, and living tester of these things. She has top connections, too, to help. @glendaWH on Twitter.

  • Andrew Ozz 4:43 am on April 22, 2009 Permalink | Reply
    Tags:   

    Widgets redesign 

    All of the redesigned widgets functionality is in place in trunk. Only remaining is some improvement to the visual design for the widgets screen in admin.

    The new way to add widgets to WordPress is by extending WP_Widget. All widgets created that way have support for multiple instances.

    Also all existing widgets will have to be converted to this system as the previous API functions will (most likely) be removed in 2.9. This is quite easy and any of the default widgets can be used as an example.

    A typical widget is constructed as follows:

    class WP_Widget_Archives extends WP_Widget {
    	function WP_Widget_Archives() {
    		$widget_ops = array('classname' => 'widget_archive', 'description' => __( "A monthly archive of your blog's posts") );
    		$this->WP_Widget(false, __('Archives'), $widget_ops);
    	}
    
    	function widget( $args, $instance ) {
    		// displays the widget on the front end
    	}
    
    	function update( $new_instance, $old_instance ) {
    		// update the instance's settings
    	}
    
    	function form( $instance ) {
    		// displays the widget admin form
    	}
    }
    
    // register the widget
    add_action('widgets_init', 'my_super_widget_init');
    function my_super_widget_init() {
    	register_widget('WP_Widget_Archives');
    }
    

    For more details and examples check wp-includes/widgets.php and wp-includes/default-widgets.php.

     
  • Andrew Ozz 4:41 pm on February 6, 2009 Permalink | Reply
    Tags:   

    Script loader updates 

    There are several updates to the script loader currently in WordPress 2.8-bleeding-edge that enhance and optimize loading of external JavaScript and CSS files.

    Probably the most important change is that scripts can be queued for loading in the footer for both the admin and the front-end. This is done with an optional argument. To enqueue a script for the footer:

    wp_enqueue_script( 'name', 'url/to/file.js', array('dependency'), 'version', true );
    

    where “true” means enqueue for the footer (“false” is the default and is optional).

    When a script is enqueued for the footer all dependencies will be added (if not already present) and will be printed before the script. Some may be in the head, others also in the footer. By default only jQuery is printed in the head but when a script is enqueued for the head, all dependencies would also be printed in the head. Almost all external scripts would run onload or after the page has loaded, so there’s no real need to queue anything for the head.

    Scripts queued for the front-end footer depend on wp_footer(); being present in the current theme. Unfortunately some themes don’t include it. The best way to remedy this would be to bring awareness among users and theme designers as suggested by several plugin developers.

    To make queueing of scripts easier two new actions have been added: "wp_enqueue_scripts" that runs in the front-end head where all is_page(), is_home(), etc. functions are available and "admin_enqueue_scripts" that runs in the admin head and has the current page hook as argument, so scripts can be queued only for specific pages.

    Another major new feature is that all core admin scripts are concatenated and compressed before sending them to the browser. This feature can easily be extended to include scripts added by plugins and to use server side caching, however that would require some changes to the server settings (.htaccess on Apache).

    Since compression from php can be problematic on some hosts there are several “switches” (constants) that manage it: define('CONCATENATE_SCRIPTS', false); would turn off both concatenating and compressing of all scripts. It’s intended for script debugging, define('COMPRESS_SCRIPTS', false); can be used to turn off compression for JavaScript and define('COMPRESS_CSS', false); for CSS files. Compression is set to “deflate” by default since it’s faster and uses a little less server resources. Gzip can be forced by setting define('ENFORCE_GZIP', true);

    There is a test if compressing from php works as expected on the server and whether the server compresses scripts by default. It runs only once and saves the result in an option “can_compress_scripts”. It would run again if the option is deleted.

    In addition all core scripts are minified. All custom scripts are included in two versions: .dev.js is the non-minified script and .js is the minified one. The constant define('SCRIPT_DEBUG', true); would load the .dev.js versions of the scripts making them easier to debug.

    Possible changes: removing the COMPRESS_CSS switch and using only COMPRESS_SCRIPTS, using deflate for compression but adding the gzip file header and serving it as “Content-Encoding gzip” since it seems more compatible with the various web servers and proxyes (all modern browsers support deflate well).

     
  • Andrew Ozz 3:07 am on January 15, 2009 Permalink | Reply
    Tags:   

    Optimizing script loading, implementation 

    The “first run” of the script loading optimization is in trunk. It uses both methods: splits the scripts queue in head and footer parts, then concatenates and compresses them before sending them to the browser. Most CSS is also concatenated and compressed.

    There are two new constants that disable concatenating and compression: CONCATENATE_SCRIPTS and COMPRESS_SCRIPTS. Setting the first to false would disable  both concatenating and compression, the second disables compression only. There is also a simple AJAX method to test if compressing from PHP works as expected on the server. It is run only once and the result is saved as an option. It will  run again if that option is deleted.

    For plugin authors there are two new actions in the admin footer: do_action('admin_print_footer_scripts'); and do_action("admin_footer-$hook_suffix");. The order of execution is:

    1. "admin_footer" can be used to print scripts before the default footer scripts
    2. "admin_print_footer_scripts" used to print the default scripts followed by any external scripts that were queued for the footer
    3. "admin_footer-$hook_suffix" can be used to print scripts that should appear on a specific admin page only

    The preferable way for plugins to add scripts to admin pages would be either to enqueue them properly (which is a must if the script depends on a default script) or to use the $hook_suffix hooks to add them only where needed.

    New hook(s) may also be needed in the functions dealing with splitting or concatenating the script queue. Suggestions are welcome either here as comments or on trac as enhancements tickets.

    Update: added do_action('admin_enqueue_scripts', $hook_suffix); allowing plugins to easily queue scripts on the exact pages. To find out the value for $hook_suffix on a specific page, echo it from your function and visit the page.

    Queueing a script for the footer follows the same syntax as in script loader:

    $scripts->add( 'handle', 'full/url/to/file.js', array( 'dependency' ), 'version' );
    $scripts->add_data( 'handle', 'group', 1 );
    

    Group 1 means queue for the footer, group 0 (zero) is the default.

     
    • GaMerZ 8:09 am on January 15, 2009 Permalink | Reply

      Hmm, any idea how do I queue script for the footer?

    • Andrew Ozz 9:00 am on January 15, 2009 Permalink | Reply

      Just updated the post with an example.

    • GaMerZ 9:09 am on January 15, 2009 Permalink | Reply

      Thanks =D What about the footer for the normal pages?

      perhaps modify wp_enqueue_script to accept 1 more argument which is group?

      So that one can do this
      wp_enqueue_script('wp-postratings', plugins_url('wp-postratings/postratings-js.js'), array('jquery'), '1.50', 1);

    • GaMerZ 9:37 am on January 15, 2009 Permalink | Reply

      I managed to enqueue stylesheets to specific pages in WP-Admin with the following code:
      [sourcecode language="php"]
      ### Function: Enqueue Ratings Stylesheet In WP-Admin
      add_action(‘admin_enqueue_scripts’, ‘ratings_stylesheets_admin’);
      function ratings_stylesheets_admin($hook_suffix) {
      $postratings_admin_pages = array(‘wp-postratings/postratings-manager.php’, ‘wp-postratings/postratings-options.php’, ‘wp-postratings/postratings-templates.php’, ‘wp-postratings/postratings-uninstall.php’);
      if(in_array($hook_suffix, $postratings_admin_pages)) {
      wp_enqueue_style(‘wp-postratings-admin’, plugins_url(‘wp-postratings/postratings-admin-css.css’), false, ‘1.50′, ‘all’);
      }
      }[/sourcecode]
      As stylesheet will always be in the head, this will work beautifully.

      Most people register JavaScripts via wp_enqueue_script() or a combination of wp_register_script() and wp_print_scripts(). Accessing $wp_scripts and setting the group via add_data() is a little bit weird at least from a plugin author point of view.

      If we can get wp_enqueue_script() to have a “group” argument. The script loader will know whether when the JavaScript will be loaded at the header or footer and load it accordingly while still hooking onto “wp_print_styles” or even “init”.

      In order to print JavaScript onto a normal page (outside WP-Admin), currently I have to hooked onto “wp_footer”, calling wp_register_script() and then calling wp_print_scripts().

    • Andrew Ozz 10:44 am on January 15, 2009 Permalink | Reply

      Agreed, will add the extra param to wp_enqueue_script() and wp_register_script().

      The front-side problem is a harder one. Many themes don’t seem to have the “wp_footer” call. The “get_footer” action can be used instead but that makes printing scripts there less effective as it runs too early, before the footer HTML. Even seen a few themes that don’t have a consistent footer and don’t use “get_footer”.

    • Frank 11:13 am on January 15, 2009 Permalink | Reply

      Thanks, i wait so long for this function.

    • GaMerZ 1:33 pm on January 15, 2009 Permalink | Reply

      @Andrew: Yea, some themes does not even have wp_head() in their header.php as well. The only way around this is to bring awareness I think.

    • Frank 6:33 pm on January 15, 2009 Permalink | Reply

      Hello Andrew,
      i hope you write over the new paramters for hook in the footer of frontend. This is very nice for better perfromance and control the js in footer. I like the wp_enqueue_* functions and i hope more themes-developer use thsi for intecrate the js-libraries. I see so much themes with a lot of plugins and many plugins load the sam js-library in the head and the site is slow and the user can not read the content. T think, wp_enqueue* is a very nice function for control js and css in the site. Very good for backend in plugins and also for hook in frontend.
      *sorry for my bad english

    • bttv 3:43 pm on May 9, 2009 Permalink | Reply

      I hope this optimization work without errors in version 2.8.

  • Andrew Ozz 12:35 pm on January 7, 2009 Permalink | Reply
    Tags:   

    Optimizing script loading, part II 

    After more tests and research it seems the best two options for the WordPress admin are either minifying all scripts and loading most in the footer or concatenating and compressing them on per page basis.

    Minifying and loading scripts in the footer gives slightly slower performance with both cold and primed cache and would depend on the ability to set appropriate caching headers on the server. On the plus side this method would be compatible with the current plugins and wouldn’t introduce higher server load.

    On the down side the loading speed improvement with primed cache would depend on the availability of mod_headers and/or mod_expires (presuming most installations are on Apache). It seems many hosts have either one or both modules installed but that still leaves a lot of installations without proper caching headers. In these cases the browser would keep checking for updated content which would increase the loading time with primed cache considerably.

    Concatenating and compressing all scripts would give better speed improvement and we will be able to set all needed headers. The last couple of days I’ve been testing a method that uses a separate php file similar to how the Gears manifest is produced. This is the same basic method used by many “website php compressors”, a stand-alone php function that gets as argument the names of the needed scripts then concatenates and compresses them. It doesn’t use server side caching (that proved to be problematic on some servers) since the cold cache page hits on the admin are relatively few.

    The advantage is that WordPress is not run second time on every cold cache page load so it uses a lot less server CPU time and memory. The disadvantage is that it would work only for the default scripts whose paths are included in the script loader. This also seems to be compatible with all existing plugins as any additional scripts are loaded after the single script and all requirements are satisfied.

    Another disadvantage is that a few hosts seem to compress all php output in a non-standard way that may result in double compression. This method would also need “Optimization options” screen with a few checkboxes that would allow the user to enable/disable the concatenating and compression as it won’t be needed when using Gears.

     
  • Andrew Ozz 3:12 am on December 27, 2008 Permalink | Reply
    Tags:   

    Optimizing script loading 

    WordPress is using more and more JavaScript. A lot of features use AJAX and nearly all UI customizations and enhancements depend on it. In 2.7 there is some optimization for caching, especially when Turbo (Gears) is used all pages load in under 1 sec. However the cache control was left to the server and there seem to be a lot of servers with less than perfect settings for it.

    There are many ways to optimize script loading  in 2.8. Listing several of them roughly in order of ease of implementation/most effective:

    • Minify (but not “pack”) all js files. Although the file size is larger, minified js loads faster than “packed” js, as it takes the browser some time to “unpack” it. Here’s a nice post on the subject. In 2.8 we should replace all “packed” js with minified and also minify all custom js when building the release.
    • Load most js in the footer. Even with 15 – 20 js files a page will load a lot faster when most are in the footer. In theory we can load all but jQuery in the footer. There’s a ticket and patch for the script loader to do this. However in practice that will interfere with many plugins that load any of the default js files on admin pages. Seems that if we load jQuery and any jQuery UI parts in the head, the great majority of plugins won’t be affected. Another option would be to queue all UI parts for the footer but move them to the head if a plugin loaded js lists them as dependencies (that would complicate the script loader a bit).
    • Setting custom caching headers in .htaccess. Although this may not work on all servers, chances are that the great majority of installations would benefit. There are several settings that can be added: the “expire far in the future” is a must, either configuring or disabling Etags for the js, css and image files is advisable, also several of the HTTP 1.0 cache control headers would be beneficial. Of course this would need testing on different production servers, but it would degrade gracefully (just wouldn’t work), so counting it as “must implement”.
    • Adding all js and css files in both compressed and uncompressed state and setting the server (.htaccess) to use the compressed versions whenever possible. This would greatly improve the initial loading of all scripts (cold cache), but is not as trivial to set up as the cache control headers. Still worth a try even if not all WordPress installations would benefit. It is possible to set the server to compress “on the fly” or compress by using php, but both methods use a lot more of server CPU time/memory on each page load. Since this affects only cold cache hits, not sure if it’s worth it. The typical user case for the admin is the same user on the same computer and in the same browser accessing the admin at least several times per week. So making sure caching works best is a priority.
    • Concatenating all default js files on per page basis so there’s only one js file to load. This combined with compressing the file would give the fastest loading time for both cold and hot cache, although for hot cache with proper cache control the difference is almost unnoticeable. It is possible to do this when building the release and include two versions of each file: compressed and uncompressed, then use .htaccess to output the compressed version when possible. However when there is a plugin that loads js and depends on other default js files, the performance degrades quickly and most blogs seem to have at least one such plugin. The workaround is to dynamically generate the concatenated file for each page, compress it and store it on the server. That would mean doing something similar to WP Super Cache but only for the js and css files in the admin. There seem to be at least one plugin that attempts to do this, also several regular WordPress contributors are interested in making such plugins. Perhaps for now it’s better to leave this for a plugin as there seem to be many server configurations where it would be difficult to set up or won’t work properly. We can also add some hooks in script loader to facilitate this if needed.

    In terms of performance the concatenating and compressing of all js and css files for each page gives the best results, closely followed by the loading of most js files in the footer. If we decide not to do the concatenating/compressing, we should revisit it in about a year (for WordPress 3.0?) as most Web hosts would have upgraded to php 5 by then. The actual php version wouldn’t affect this, but it seems that while upgrading the hosts also improve their server and php configurations too.

     
    • Gregory 3:57 am on December 29, 2008 Permalink | Reply

      It would be great if wordpress was compatable with mod_concat and mod_jsmin. I have attempted to implement both apache modules with 2.7 with limited results

    • Jacob Santos 3:58 pm on December 29, 2008 Permalink | Reply

      If hosting servers don’t support PHP5 now, then they’ll probably won’t in another year or two.

    • Rahul Boss 10:44 am on December 30, 2008 Permalink | Reply

      mainly now all hosting servers support php5.

    • miloandrew 11:03 pm on December 31, 2008 Permalink | Reply

      Many of your ruminations are understandably taking into account the huge array of available WP plugins. While this is absolutely necessary, maybe taking a bit of a different tack can open up some options?

      I have often wished that I could manage the load order of plugins and control which loads before another, or even WHEN a plugin loads at all. Could it be that implementing more internal plugin declaration and control could help with the overall compatibility of this optimization initiative?

      If we make it possible for the system to detect the way certain plugin scenarios will affect optimization efforts, then the system can adapt on its own. Rather than making global decisions on optimization based upon what COULD exist with certain plugins, maybe taking the tack of allowing the plugins to tell the system what they load and require would do the trick?

      The plugin header could potentially be extended to either allow the developer to state when the plugin should be loaded, or at least to specify other items that it either requires or loads itself. A “Loads:” field along with a “Requires:” field could go a long way to helping WP understand what the activated plugins require. It could also help the user make intelligent decisions by allowing the system to report if the activation of a specific plugin will necessitate the disabling of a specific optimization technique that would otherwise be used by the core.

      Alternatively (or in addition to the above), you could allow the WP admin to specify where and when all active plugins are loaded. While I would love to see this type of completely configurable plugin management, I think that even just the additional declarations could be extremely helpful.

      Sorry – I don’t mean to digress from optimization to plugin management, but it seems that there may be a few strong ties between the two.

      Thanks for listening!

      Cheers,
      A

    • Andrew Ozz 10:22 am on January 3, 2009 Permalink | Reply

      @Jacob Santos, @Rahul Boss yes, but most hosts require the user to manually switch to php 5, sometimes by directly editing .htaccess. Don’t think that most users are comfortable doing that or even aware of it.

      @miloandrew almost all of these features already exist in the API. In the case of script loading, plugins can enqueue both js and css and require any of the scripts included in WordPress. Unfortunately not all plugins use the script loader, but most do.

      The optimization will have to be transparent for the plugins. For example setting appropriate caching headers for js, css and images in .htaccess would affect all scripts.

      The load order can be managed from the filter/action priority quite well. The blog admin can edit the plugin’s file and change that if needed or have a small plugin that would set it up for the rest.

      BTW the first step is already implemented. All js has been minified reducing the size by about 30% – 35%.

    • Milan 1:31 pm on March 22, 2009 Permalink | Reply

      I am not sure where to post this, but I’ll start from here since title of this post describes my intention.

      When new comment threading for 2.7 was introduced, you recommended call to comment-reply.js in this form.

      But problem with this is that comment-reply.js is called on all pages in all cases even there are many cases when it shouldn’t be called because it is simply not needed:
      - when comments are turned off on site wide level
      - when threaded comments are not enabled (this is default option)
      - when comments are not enabled on that entry
      - when there is no comments on that entry
      - when page is used as front page (in reading options)

      In all those situations comment-reply.js is loaded even though there is no need for it. Yes, it is cached after first page view, but what if visitor lands on that particular page that doesn’t need this file and that page already has ten javascript files? It will just increase page load time and you know that visitors that come from search engines or from links on other sites have low tolerance and don’t want to wait to much.

      So what we need is that this script is loaded only when there is need for it and my suggestion is that you make some function that should be checked and that will return true or false value when asked if there is need for comment-reply.js. Maybe that script can’t solve all problems but at least it can return false value if comments are globally turned off or comment threading is not enabled (I’m quite sure it can do this).

      Example of how this should work in theme’s files:

      if ( comment_threading_entry_status() ) wp_enqueue_script( 'comment-reply' );

      Example of functions:
      function comment_threading_entry_status() {
      if (((get_option('default_comment_status')) == "open") && ((get_option('thread_comments')) == "1") && ( !is_front_page() ) && ( comments_open() ) && ( have_comments() )) {
      return true;
      } else
      return false;
      }

      This function doesn’t work like this (it works without last two conditions), but you got a point.

      I hope that you’ll at least respond me in reasonable time :)

      (btw, why we don’t have subscribe to comments here, it should be enabled on wp.com?)

    • John Biddle 8:39 pm on April 2, 2009 Permalink | Reply

      This is a great idea. The problem is even bigger than you describe. It’s true that for second and subsequent pageloads the javascript is is the cache, it’s also true that unless the files has an expired header the browser still has to contact the host to determine if the file in cache is current. There won’t be a download for current files, but the round trip to the server just to check the currentness wastes time for every page. This problem exists for losts of files in lots of plugins and probably contributes to a 1 or 2 second page delay for the average page.

  • Andrew Ozz 12:33 am on October 11, 2008 Permalink | Reply
    Tags:   

    Some changes and improvements to threaded comments: allows replying without JavaScript (patch contributed by Viper007Bond) and removes script dependency on jQuery. If the script fails for some reason (missing base css blocks, IDs, etc.) the no-js replying will be used instead.

    Added 2 new template tags used to allow replying without js, comment_parent_field() comment_id_fields() outputs the hidden form fields holding the reference to the comment’s parent and the comment_post_ID, and comment_form_title() outputs a different title above the form when replying (optional).

    Changes: cancel_comment_reply_link() takes only one argument text = ‘ ‘, the rest is set from js. The DIV surrounding it shouldn’t be hidden (for supporting no-js mode) and is optional.

     
    • Ryan 1:28 am on October 11, 2008 Permalink | Reply

      Maybe bundle the comment ID in with the parent ID inside comment_parent_field() and rename comment_id_fields()? That way it takes care of both of the required hidden fields.

    • Andrew Ozz 1:44 am on October 11, 2008 Permalink | Reply

      Good idea. The comments.php templates will have to be adjusted there a bit anyways, better to have one template tag that will output all necessary fields.

    • Ryan 7:06 pm on October 14, 2008 Permalink | Reply

      Done

    • monika 2:19 pm on November 2, 2008 Permalink | Reply

      ok there is one template tag and where can I translate all this in an individual way? the main gettext file -but now I can’t translate via theme .mo / .pot :( or?

c
compose new post
j
next post/next comment
k
previous post/previous comment
r
reply
e
edit
o
show/hide comments
t
go to top
l
go to login
h
show/hide help
esc
cancel