HTML Logo by World Wide Web Consortium (www.w3.org). Click to learn more about our commitment to accessibility and standards.

Moving forward with Composr

ocPortal has been relaunched as Composr CMS, which is now in beta. ocPortal 9 will be superseded by Composr 10.

Head over to compo.sr for our new site, and to our migration roadmap. Existing ocPortal member accounts have been mirrored.


Improving page load times

Login / Search

 [ Join | More ]
 Add topic 
Posted
Rating:
#85332 (In Topic #17543)
Avatar

Community saint

While Chris is working on the CSS, I wanted to bring attention to general page load times. Here is the PageSpeed report for my site's home page  (as run at GTMetrix.com):


Chris has already weighed in on how he thinks that using CSS sprites for images is not a good idea. I can't comment on "Inline small CSS" other than to say that it sounds like it might save some time but introduce other headaches.

I am wondering what is meant by "Use efficient CSS selectors" and how this might tie into Chris's reworking of the CSS. This is what was singled out as issues by Page Speed, but I defer to others who really understand this stuff:

Code

http://DOMAIN/themes/theme_name/templates_cached/EN/global.css has 10 very inefficient rules, 64 inefficient rules, and 31 potentially inefficient uses of :hover out of 709 total rules.
Very inefficient rules (good to fix on any page):
.no_stbox_padding .dottedborder thead tr:last-child td    Tag key with 4 descendant selectors
.no_stbox_padding .dottedborder thead tr:last-child th    Tag key with 4 descendant selectors
#splurgh ul ul ul ul    Tag key with 4 descendant selectors
ul.sitemap li li    Tag key with 2 descendant selectors and Class overly qualified with tag
.menu_type__dropdown ul.nlevel li a    Tag key with 3 descendant selectors and Class overly qualified with tag
.menu_type__dropdown li.toplevel a    Tag key with 2 descendant selectors and Class overly qualified with tag
.menu_type__top li.last a    Tag key with 2 descendant selectors and Class overly qualified with tag
.menu_type__dropdown li.toplevel.last a    Tag key with 2 descendant selectors and Class overly qualified with tag
.menu_type__zone li *    Universal key with 2 descendant selectors
a[title=%Go to this as a virtual root%]:hover    Tag key with 6 descendant selectors
Inefficient rules (good to fix on interactive pages):
.no_stbox_padding .dottedborder td    Tag key with 2 descendant selectors
.no_stbox_padding .dottedborder th    Tag key with 2 descendant selectors
.no_stbox_padding .forcedottedborder div    Tag key with 2 descendant selectors
.do_next_section table td    Tag key with 2 descendant selectors
ul.compact_list li    Tag key with descendant selector and Class overly qualified with tag
ol.compact_list li    Tag key with descendant selector and Class overly qualified with tag
ul.tick_list li    Tag key with descendant selector and Class overly qualified with tag
.category_entry a img    Tag key with 2 descendant selectors
ul.actions_list li    Tag key with descendant selector and Class overly qualified with tag
ul.actions_list_compact li    Tag key with descendant selector and Class overly qualified with tag
ul.actions_list_super_compact li    Tag key with descendant selector and Class overly qualified with tag
ul.actions_list h4    Tag key with descendant selector and Class overly qualified with tag
a.poster_member em    Tag key with descendant selector and Class overly qualified with tag
.ocf_post_buttons a[rel=%add reply%]    Tag key with 2 descendant selectors
#splurgh ul ul    Tag key with 2 descendant selectors
#splurgh li li    Tag key with 2 descendant selectors
#splurgh ul ul ul    Tag key with 3 descendant selectors
ul.sitemap ul    Tag key with descendant selector and Class overly qualified with tag
ul.sitemap li    Tag key with descendant selector and Class overly qualified with tag
.menu_type__dropdown .nlevel .has_img img    Tag key with 3 descendant selectors
.menu_type__popup .has_img img    Tag key with 2 descendant selectors
.menu_type__tree ul li a    Tag key with 3 descendant selectors
.menu_type__popup ul li a    Tag key with 3 descendant selectors
.menu_type__tree .current a    Tag key with 2 descendant selectors
.menu_type__popup .current a    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel .current a    Tag key with 3 descendant selectors
.menu_type__popup .has_img.current a    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel .has_img.current a    Tag key with 3 descendant selectors
.menu_type__tree .non_current a    Tag key with 2 descendant selectors
.menu_type__popup .non_current a    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel .non_current a    Tag key with 3 descendant selectors
.menu_type__tree .non_current a:hover    Tag key with 2 descendant selectors
.menu_type__popup .non_current a:hover    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel .non_current a:hover    Tag key with 3 descendant selectors
.menu_type__dropdown .nlevel li    Tag key with 2 descendant selectors
.menu_type__popup .nlevel li    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel li    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel li    Tag key with 2 descendant selectors
.menu_type__popup li a:link    Tag key with 2 descendant selectors
.menu_type__popup li a:visited    Tag key with 2 descendant selectors
.menu_type__popup li a:active    Tag key with 2 descendant selectors
.menu_type__popup li a:hover    Tag key with 2 descendant selectors
.menu_type__popup ul ul    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel a:link    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel a:visited    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel a:active    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel a:hover    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel li    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel li:hover    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel a:active    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel a:link    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel a:visited    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel a:hover    Tag key with 2 descendant selectors
.menu_type__top li a    Tag key with 2 descendant selectors
.menu_type__dropdown .toplevel_link img    Tag key with 2 descendant selectors
.menu_type__tree ul ul    Tag key with 2 descendant selectors
#global_zones .menu_type__zone a:link    Tag key with 2 descendant selectors
#global_zones .menu_type__zone a:visited    Tag key with 2 descendant selectors
#global_zones .menu_type__zone a:active    Tag key with 2 descendant selectors
#global_zones .menu_type__zone a:hover    Tag key with 2 descendant selectors
.menu_block .edit_menu_link a    Tag key with 2 descendant selectors
.menu_block:hover .edit_menu_link a    Tag key with 2 descendant selectors
#screen_actions div a    Tag key with 2 descendant selectors
body link_exempt_wrap a    Tag key with 2 descendant selectors
Rules that use the :hover pseudo-selector on non-anchor elements. This can cause performance problems in Internet Explorer versions 7 and 8 when a strict doctype is used.
.buttonhyperlink:hover
.non_link:hover
input.wide_button[type=%reset%]:hover
input.button_micro[type=%reset%]:hover
input.button_page[type=%reset%]:hover
input.button_pageitem[type=%reset%]:hover
input.wide_button[type=%submit%]:hover
input.button_micro[type=%submit%]:hover
input.button_page[type=%submit%]:hover
input.button_pageitem[type=%submit%]:hover
input.wide_button[type=%button%]:hover
input.button_micro[type=%button%]:hover
input.button_page[type=%button%]:hover
input.button_pageitem[type=%button%]:hover
button.wide_button:hover
button.button_micro:hover
button.button_page:hover
button.button_pageitem:hover
.ocf_post_buttons:hover a
.tab:hover
.menu_type__tree .has_no_img .drawer:hover
.menu_type__popup .has_no_img .drawer:hover
.global_bottom img:hover
.menu_type__dropdown .nlevel li:hover
.menu_type__zone .current:hover
.menu_block:hover .edit_menu_link a
#global_zones:hover .edit_menu_link_inline
#panel_top:hover .edit_menu_link_inline
#panel_bottom:hover .edit_menu_link_inline
:hover>.edit_menu_link_inline
a[title=%Go to this as a virtual root%]:hover
http://DOMAIN/themes/theme_name/templates_cached/EN/news.css has 0 very inefficient rules, 4 inefficient rules, and 0 potentially inefficient uses of :hover out of 16 total rules.
Inefficient rules (good to fix on interactive pages):
.standardbox_wrap_classic .news_piece_summary h3    Tag key with 2 descendant selectors
.standardbox_wrap_classic .news_goto a:link    Tag key with 2 descendant selectors
.standardbox_wrap_classic .news_goto a:visited    Tag key with 2 descendant selectors
.standardbox_wrap_classic .news_goto a:active    Tag key with 2 descendant selectors
http://DOMAIN/themes/theme_name/templates_cached/EN/ocf.css has 3 very inefficient rules, 12 inefficient rules, and 1 potentially inefficient uses of :hover out of 178 total rules.
Very inefficient rules (good to fix on any page):
table.ocf_profile_fields tr:last-of-type th    Tag key with 2 descendant selectors and Class overly qualified with tag
table.ocf_profile_fields tr:last-of-type td    Tag key with 2 descendant selectors and Class overly qualified with tag
ul.ocf_profile_friends li a    Tag key with 2 descendant selectors and Class overly qualified with tag
Inefficient rules (good to fix on interactive pages):
table.ocf_profile_details th    Tag key with descendant selector and Class overly qualified with tag
table.ocf_profile_details td    Tag key with descendant selector and Class overly qualified with tag
table.ocf_profile_fields th    Tag key with descendant selector and Class overly qualified with tag
table.ocf_profile_fields th    Tag key with descendant selector and Class overly qualified with tag
table.ocf_profile_fields td    Tag key with descendant selector and Class overly qualified with tag
table.ocf_profile_fields th    Tag key with descendant selector and Class overly qualified with tag
table.ocf_profile_fields td    Tag key with descendant selector and Class overly qualified with tag
table.ocf_profile_statistics th    Tag key with descendant selector and Class overly qualified with tag
table.ocf_profile_statistics th    Tag key with descendant selector and Class overly qualified with tag
table.ocf_profile_statistics td    Tag key with descendant selector and Class overly qualified with tag
ul.ocf_profile_friends li    Tag key with descendant selector and Class overly qualified with tag
ul.ocf_profile_friends li:hover    Tag key with descendant selector and Class overly qualified with tag
Rules that use the :hover pseudo-selector on non-anchor elements. This can cause performance problems in Internet Explorer versions 7 and 8 when a strict doctype is used.
ul.ocf_profile_friends li:hover
http://DOMAIN/themes/theme_name/templates_cached/EN/global.css has 10 very inefficient rules, 64 inefficient rules, and 31 potentially inefficient uses of :hover out of 709 total rules.
Very inefficient rules (good to fix on any page):
.no_stbox_padding .dottedborder thead tr:last-child td    Tag key with 4 descendant selectors
.no_stbox_padding .dottedborder thead tr:last-child th    Tag key with 4 descendant selectors
#splurgh ul ul ul ul    Tag key with 4 descendant selectors
ul.sitemap li li    Tag key with 2 descendant selectors and Class overly qualified with tag
.menu_type__dropdown ul.nlevel li a    Tag key with 3 descendant selectors and Class overly qualified with tag
.menu_type__dropdown li.toplevel a    Tag key with 2 descendant selectors and Class overly qualified with tag
.menu_type__top li.last a    Tag key with 2 descendant selectors and Class overly qualified with tag
.menu_type__dropdown li.toplevel.last a    Tag key with 2 descendant selectors and Class overly qualified with tag
.menu_type__zone li *    Universal key with 2 descendant selectors
a[title=%Go to this as a virtual root%]:hover    Tag key with 6 descendant selectors
Inefficient rules (good to fix on interactive pages):
.no_stbox_padding .dottedborder td    Tag key with 2 descendant selectors
.no_stbox_padding .dottedborder th    Tag key with 2 descendant selectors
.no_stbox_padding .forcedottedborder div    Tag key with 2 descendant selectors
.do_next_section table td    Tag key with 2 descendant selectors
ul.compact_list li    Tag key with descendant selector and Class overly qualified with tag
ol.compact_list li    Tag key with descendant selector and Class overly qualified with tag
ul.tick_list li    Tag key with descendant selector and Class overly qualified with tag
.category_entry a img    Tag key with 2 descendant selectors
ul.actions_list li    Tag key with descendant selector and Class overly qualified with tag
ul.actions_list_compact li    Tag key with descendant selector and Class overly qualified with tag
ul.actions_list_super_compact li    Tag key with descendant selector and Class overly qualified with tag
ul.actions_list h4    Tag key with descendant selector and Class overly qualified with tag
a.poster_member em    Tag key with descendant selector and Class overly qualified with tag
.ocf_post_buttons a[rel=%add reply%]    Tag key with 2 descendant selectors
#splurgh ul ul    Tag key with 2 descendant selectors
#splurgh li li    Tag key with 2 descendant selectors
#splurgh ul ul ul    Tag key with 3 descendant selectors
ul.sitemap ul    Tag key with descendant selector and Class overly qualified with tag
ul.sitemap li    Tag key with descendant selector and Class overly qualified with tag
.menu_type__dropdown .nlevel .has_img img    Tag key with 3 descendant selectors
.menu_type__popup .has_img img    Tag key with 2 descendant selectors
.menu_type__tree ul li a    Tag key with 3 descendant selectors
.menu_type__popup ul li a    Tag key with 3 descendant selectors
.menu_type__tree .current a    Tag key with 2 descendant selectors
.menu_type__popup .current a    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel .current a    Tag key with 3 descendant selectors
.menu_type__popup .has_img.current a    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel .has_img.current a    Tag key with 3 descendant selectors
.menu_type__tree .non_current a    Tag key with 2 descendant selectors
.menu_type__popup .non_current a    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel .non_current a    Tag key with 3 descendant selectors
.menu_type__tree .non_current a:hover    Tag key with 2 descendant selectors
.menu_type__popup .non_current a:hover    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel .non_current a:hover    Tag key with 3 descendant selectors
.menu_type__dropdown .nlevel li    Tag key with 2 descendant selectors
.menu_type__popup .nlevel li    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel li    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel li    Tag key with 2 descendant selectors
.menu_type__popup li a:link    Tag key with 2 descendant selectors
.menu_type__popup li a:visited    Tag key with 2 descendant selectors
.menu_type__popup li a:active    Tag key with 2 descendant selectors
.menu_type__popup li a:hover    Tag key with 2 descendant selectors
.menu_type__popup ul ul    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel a:link    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel a:visited    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel a:active    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel a:hover    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel li    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel li:hover    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel a:active    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel a:link    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel a:visited    Tag key with 2 descendant selectors
.menu_type__dropdown .nlevel a:hover    Tag key with 2 descendant selectors
.menu_type__top li a    Tag key with 2 descendant selectors
.menu_type__dropdown .toplevel_link img    Tag key with 2 descendant selectors
.menu_type__tree ul ul    Tag key with 2 descendant selectors
#global_zones .menu_type__zone a:link    Tag key with 2 descendant selectors
#global_zones .menu_type__zone a:visited    Tag key with 2 descendant selectors
#global_zones .menu_type__zone a:active    Tag key with 2 descendant selectors
#global_zones .menu_type__zone a:hover    Tag key with 2 descendant selectors
.menu_block .edit_menu_link a    Tag key with 2 descendant selectors
.menu_block:hover .edit_menu_link a    Tag key with 2 descendant selectors
#screen_actions div a    Tag key with 2 descendant selectors
body link_exempt_wrap a    Tag key with 2 descendant selectors
Rules that use the :hover pseudo-selector on non-anchor elements. This can cause performance problems in Internet Explorer versions 7 and 8 when a strict doctype is used.
.buttonhyperlink:hover
.non_link:hover
input.wide_button[type=%reset%]:hover
input.button_micro[type=%reset%]:hover
input.button_page[type=%reset%]:hover
input.button_pageitem[type=%reset%]:hover
input.wide_button[type=%submit%]:hover
input.button_micro[type=%submit%]:hover
input.button_page[type=%submit%]:hover
input.button_pageitem[type=%submit%]:hover
input.wide_button[type=%button%]:hover
input.button_micro[type=%button%]:hover
input.button_page[type=%button%]:hover
input.button_pageitem[type=%button%]:hover
button.wide_button:hover
button.button_micro:hover
button.button_page:hover
button.button_pageitem:hover
.ocf_post_buttons:hover a
.tab:hover
.menu_type__tree .has_no_img .drawer:hover
.menu_type__popup .has_no_img .drawer:hover
.global_bottom img:hover
.menu_type__dropdown .nlevel li:hover
.menu_type__zone .current:hover
.menu_block:hover .edit_menu_link a
#global_zones:hover .edit_menu_link_inline
#panel_top:hover .edit_menu_link_inline
#panel_bottom:hover .edit_menu_link_inline
:hover>.edit_menu_link_inline
a[title=%Go to this as a virtual root%]:hover

It does seem like providing the image dimensions would be a good idea since this is marked as a high priority item and we failed with an "F". Of course, this sounds reasonable to me, the guy who doesn't have to code it, but it doesn't seem like this would be that difficult to code into most places.

The idea to defer parsing of JavaScript is covered in feature tracker item 423: 0000423: Performance improvements: frontend technologies - ocPortal feature tracker . This is a high-priority fix according to the PageSpeed report which is one more reason we need to get this item sponsored.

I know Chris has cautioned on using these automated optimization tools, but I do think it is worth noting what they perceive as issues. This is especially true for PageSpeed since Google is now using page load times as a factor in their ranking algorithms and these are what they consider problem areas.

Anyway, it will be interesting to hear what people with the actual knowledge and skills to work with this stuff have to say.

Bob
Back to the top
 
Posted
Rating:
#85334
Avatar

Most of this is a bit silly really. I'll quickly weigh in.

I am a bit speed obsessed too, but these metrics give you really the wrong idea in some areas. When I think about performance, I think about making the PHP code faster first, that's the real bottleneck, and that's also a scaling issue (frontend optimisation doesn't reduce server load).

"Image dimensions" - that's a bit extreme really. It is about stopping the page rendering more than once. The page renders in milliseconds, faster than the eye can see. And when part of the page re-renders, it doesn't redraw everything in most cases. We do specify dimensions for the logo, which is the main thing that would cause a big re-draw. We do actually have support in Tempcode now for specifying image dimensions for anything, however to pull these out would be server-side performance hit, or an exercise in hard-coding – neither are desirable.

"CSS sprites" - as discussed before, that's poor engineering.

"inline small CSS" - that's also poor engineering, there are many reasons to not want to inline CSS. In fact, it probably hurts performance because that needs downloading on every page view.

"Defer parsing of Javascript" - we don't do badly there already (since v6 IIRC)

"Efficiency selectors" - that's really really moronic. If we did what they said, we'd need to increase page size (due to inventing extra CSS classes), we'd make the CSS uglier, more complex, less maintainable - and I would not be surprised if after changing all that we shave off maybe 1 millisecond off the rendering time.

This is especially true for PageSpeed since Google is now using page load times as a factor in their ranking algorithms and these are what they consider problem areas.

I doubt it's anything to do with these things actually. It's probably to do with download times, most of these are render times (the crawler won't likely be rendering the page, or if it does, measuring it).


Become a fan of ocPortal on Facebook or add me as a friend. Add me on on Twitter.
Was I helpful?
  • If not, please let us know how we can do better (please try and propose any bigger ideas in such a way that they are fundable and scalable).
  • If so, please let others know about ocPortal whenever you see the opportunity.
  • If my reply is too Vulcan or expressed too much in business-strategy terms, and not particularly personal, I apologise. As a company & project maintainer, time is very limited to me, so usually when I write a reply I try and make it generic advice to all readers. I'm also naturally a joined-up thinker, so I always express my thoughts in combined business and technical terms. I recognise not everyone likes that, don't let my Vulcan-thinking stop you enjoying ocPortal on fun personal projects.
  • If my response can inspire a community tutorial, that's a great way of giving back to the project as a user.
Back to the top
 
Posted
Rating:
#85336
Avatar

Community saint

Thanks for weighing in, Chris.

What you say makes sense to me. There is already a tracker item to move the JS to the bottom and, as you said, we did okay with a "C" grade here.

The "Inline CSS" seemed silly to me as something that you create a ball of yarn for whatever speed improvements it might bring.

I honestly did not know what to think about the "efficient CSS selectors" which is the reason I copied in their list of issues. That's way over my head but it is clear you have both an understanding and a reason for doing things as you do.

The only one which really resonated with me was the image dimensions because it potentially speeds page rendering (I'm old enough to remember manual layout where all you had was an image's dimension which someone would later drop in the actual image). But, as you point out, that thinking is taking your eye off the ball as the render is almost instantaneous.

Thanks for once again setting me straight.

Bob

Back to the top
 
Posted
Rating:
#85338
Avatar

Community saint

I wish I had found this before my original post:
0000482: New kind of performance review - ocPortal feature tracker

Bob
Back to the top
 
Posted
Rating:
#85340
Avatar

Community saint

One important thing to note about using "Inline CSS" it that it would make theaming such a pain. No only would a lot of your css not be centralised in the likes of global.css, but it would be duplicated in-line in so many places as to burn a lot more of your time finding/changing them all.

Use of "efficient CSS selectors" is fine in principle but not practical for a cms. The selectors (i.e. the rule that identifies a given bit of html) have to be robust enough that if you move your html from say a div on the main page to a div within a table within a span on another page that it will still find it and apply the styles to it correctly. Robust code is not always 100% efficient.

Do you have a Samsung Galaxy S / Galaxy S II ? If so, why not check out my ScreenFree FM Radio .
Back to the top
 
There are too many online users to list.
Control functions:

Quick reply   Contract

Your name:
Your message: