layers-wp / layerswp

Layers WordPress theme by Obox
http://www.layerswp.com
Other
23 stars 10 forks source link

Performance problems (WordPress customizer) #246

Open frabrunelle opened 9 years ago

frabrunelle commented 9 years ago

Hi, I manage a couple of Layers site and I like Layers a lot :smile:

But one of the website I manage has a lot of content (33 Layers pages so far and I still have a few more to create).

The problem is that for many weeks (maybe even a few months I think), I've been experiencing some major performance issues when I load a Layers page in the WordPress customizer in order to edit its content.

For example, a very simple Layers page with almost no content will take more than 1 minute to load, sometimes close to 2 minutes.

And when it finally loads, it takes many seconds to execute an action whenever I click on something.

I don't have this problem on my other sites, but I think it's because they don't have that much content on them.

I would really appreciate if you could help me find and solve the performance issue. I really hope I am able to solve the issue, because it takes me a lot of time just to do very minor changes.

To give more context, the site I am having issues with is seasteading.org.

The technology to foster the fluid mechanics of voluntary societies is at hand. The Seasteading Institute is a nonprofit think-tank working to provide a machinery of freedom to choose new societies on the blue frontier. The most successful floating cities can then inspire change around the world.

Here are some screenshots of what happens when I load the WordPress customizer for a Layers page that has almost no content:

screen shot 2015-08-24 at 6 23 52 pm

screen shot 2015-08-24 at 6 39 42 pm

As you can see, it loads many images that are not necessary. In fact it seems that it loads thumbnails of all the images that are contained in my other Layers pages. 500 requests for a total of 28.9 MB, that's quite a lot for an empty page!

I suspect it's a performance issue related to Layers (I am running Layers 1.2.4), but it might also be related to WordPress (I am running WordPress 4.3). It's hosted on the Professional plan of WP Engine. And although I do have a couple of plugins that are activated, I highly doubt the issue is related to one of my plugins.

Let me know if there is any way you could help me debug this issue and also if you are able to reproduce it. I would be ready to give you access to my WordPress admin so that you can debug the issue yourself. Thank you very much :smiley:

marcperel commented 9 years ago

Hey @frabrunelle,

This is fantastic, thanks for bringing the issues up. It's known that WordPress loads all your pages in one bulk array so that they can do the in-site page navigation and update the sidebars as you traverse different pages.

What that means is that all the widgets are loaded in the page at once. We've considered that affect by lazy loading the color pickers and draggable elements, which helped a ton, but we did not consider lazy loading images inside background and feature image controllers, I think it's definitely worth playing with and seeing what gains we can accomplish by doing so.

~ Marc

marcperel commented 9 years ago

@frabrunelle I've created a branch called image-lazy-load, can you pull on that branch and let me know how that affects the load time for your site? It essentially lazy loads images instead of loading them all at the same time as the customizer.

vailjoy commented 9 years ago

In addition to our attempts to improve performance code--wise, please also check the workarounds here to ensure inactive widgets are cleared etc: http://docs.layerswp.com/doc/troubleshooting-customizer-errors/

frabrunelle commented 9 years ago

we did not consider lazy loading images inside background and feature image controllers, I think it's definitely worth playing with and seeing what gains we can accomplish by doing so.

Yes, I think lazy loading the feature images would make a huge difference because I have quite a lot!

I've created a branch called image-lazy-load, can you pull on that branch and let me know how that affects the load time for your site? It essentially lazy loads images instead of loading them all at the same time as the customizer.

That would be amazing!!

But I am looking at that branch and I don't see any specific changes: https://github.com/Obox/layerswp/compare/image-lazy-load. Maybe you forgot to push them? Or I just don't see them? :smile:

Thank you very much!

marcperel commented 9 years ago

@frabrunelle My bad! The changes are in develop +1 thanks for pointing that out!

frabrunelle commented 9 years ago

I just tried it and it's a good improvement!

Before

screen shot 2015-08-30 at 4 45 28 pm

After

screen shot 2015-08-30 at 4 44 56 pm

Instead of transferring 29 MB it's only transferring 4.2 MB. And 125 requests instead of 508 requests.

I'll see if I can maybe disable more plugins. I am also thinking of contacting WPEngine to see if they can help me improve the performance.

Otherwise I am thinking of switching to a DigitalOcean server because on my other sites I think it takes just a few seconds to load instead of 1.2 minutes.

YK7479 commented 9 years ago

Hi, I am YK and I would like to know about Loading speed of my website and I compressed all images. I am bit worried about it. image

Can anyone help me out this please..

Thank you very much..

carlosvarela commented 9 years ago

Try https://developers.google.com/speed/pagespeed/

Em quinta-feira, 3 de setembro de 2015, YK7479 notifications@github.com escreveu:

Hi, I am YK and I would like to know about Loading speed of my website and I compressed all images. I am bit worried about it. [image: image] https://cloud.githubusercontent.com/assets/14104501/9651369/6dd37812-522d-11e5-944f-c590f487e78a.png

Can anyone help me out this please..

Thank you very much..

— Reply to this email directly or view it on GitHub https://github.com/Obox/layerswp/issues/246#issuecomment-137343174.

frabrunelle commented 8 years ago

I did a new install on WP Engine and the performance was very good. It was running WordPress 4.4 and Layers 1.2.10.

Instead of taking 1.2 minutes, it took 5.67 seconds to load the WordPress customizer!

screen shot 2015-12-10 at 2 23 35 am

So my plan at this point is to migrate the content from the old install to the new install.

marcperel commented 8 years ago

We are so excited about this update and the performance improvements. It seems that the refresh on the customizer is a bit slower, but the JS is waaay faster.

frabrunelle commented 8 years ago

Like I said in my last post, I had been having performance issues with one of my Layers site: seasteading.org. I decided that the best strategy would be to do a clean install, so that’s what I am currently working on at another URL: http://seasteadingorg.wpengine.com.

At first I was really impressed by the performance (you can see a screenshot in my last post), but as I started creating more and more pages (I'm now at 70 pages), the time to load the customizer got increasingly long (more than 20 seconds), to the point where I just wasn’t able to load the customizer anymore: "PHP Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 40048705 bytes)".

I contacted WP Engine support and asked them to increase the WordPress Memory Limit from 256 MB to 512 MB, which they just did. I am now able to load the customizer again and I think I should be okay to finish the rest of the pages and release the new version of seasteading.org.

WordPress 4.4 definitely improves the performance of the Customizer once it’s loaded, but the problem of actually loading it in the first place remains. I was hoping this would be fixed in WordPress 4.4, but after looking more closely at the tickets on WordPress Core, I can't find any discussions related to this issue.

@marcperel: In a previous comment, you said:

It's known that WordPress loads all your pages in one bulk array so that they can do the in-site page navigation and update the sidebars as you traverse different pages.

What that means is that all the widgets are loaded in the page at once.

I’m curious if you think that this situation is likely to improve in the upcoming months? Do you know if WordPress Core is planning to fix this (e.g. not load all widgets at once)?

It would be nice to be able to associate widgets with specific pages. That way, we would be able to load only the widgets for the current page when we click on the “Customize” button. Even if it takes until the next release of WordPress before this is fixed, that would be okay with me. It’s just a bit inconvenient that it takes a long time (about 20 seconds) to load the customizer, but at least it works much better than before once it’s loaded.

My backup solution would be to redesign the whole site using Make Plus, which I am not very keen to do because I already invested hundreds of hours migrating seasteading.org to Layers. I might do it in a year from now if the situation is still not improved, but I hope I don't have to. I still like Layers a lot and I use it for dozen of other websites, but in the future I will think twice about using it for websites with a lot of pages.

marcperel commented 8 years ago

Once again @frabrunelle thanks for the feedback, the reason that this happens is down to the way that WordPress stores the widgets, which they are looking to fix in their patch for "Widgets as Posts" https://core.trac.wordpress.org/ticket/32474

westonruter commented 8 years ago

@frabrunelle I got your email. Replying here.

I don't think that storing widgets as posts will help with the specific performance problem here. In fact, it could make performance worse if there is not a persistent object cache. In any case, the Widget Posts module of the Customize Widgets Plus plugin is an implementation of storing widgets in a widget_instance post type. (This plugin needs more documentation and it needs an update on WordPress.org.)

I think the specific problem you are facing is the fact that widgets in Core are still very PHP-centric. PHP is currently required to render the widget control forms, handle processing and sanitization of widget instance data, in addition to rendering the form into the page. PHP should not be required for rendering the form and handling the sanitization in the UI. Server-side sanitization should be applied only when the instance data is sent to the preview.

The core Trac ticket for this is #33507: Allow widget controls to be JS-driven. A big problem of running out of memory is that widgets in Core currently require the WP_Widget::form() method to be called for each and every widget that has a Customizer control. This can greatly balloon the HTML response size. If JS-driven widgets are used, then there would only be one HTML template for a given widget which could be re-used for each widget instance output.

Another issue in Core is that all widgets get rendered up-front regardless of whether they are going to be used. #23909 (Widgets settings loaded and instances registered unnecessarily) is the Trac ticket focused on this, along with #28580 (Speed up customizer by lazy-loading controls and settings as needed).

There are not firm timetables on implementing these Trac tickets, though it's all definitely something I'm interested in for 4.6 if time and resources allow.

frabrunelle commented 8 years ago

@westonruter: Thank you very much for the information! I am now watching the Trac tickets you mentioned :smiley:

westonruter commented 8 years ago

The core Trac ticket for this is #33507: Allow widget controls to be JS-driven. A big problem of running out of memory is that widgets in Core currently require the WP_Widget::form() method to be called for each and every widget that has a Customizer control. This can greatly balloon the HTML response size. If JS-driven widgets are used, then there would only be one HTML template for a given widget which could be re-used for each widget instance output.

There is now a feature plugin for this: https://github.com/xwp/wp-js-widgets/

westonruter commented 8 years ago

Duplicate: wp#37006 (Extremely poor customizer performance)

jessecurry commented 8 years ago

We're encountering this issue on a multisite install and seeing 80+ second load times which will result in our host killing our process and issuing a 502.

Our team is trying to come up with a workaround in the short term. We had some promising results by loading only one page info into the customizer, but we've not been able to make it dynamic. We understand this would not let us edit other pages from within a customizer session, but it would be an acceptable tradeoff for us now.

We've been working in and around the layers_get_builder_pages() method, but we're facing a pretty steep learning curve with Wordpress and Layers. Is there an easy way to restrict the loading of Layers builder content to a single page when entering a customizer session?

westonruter commented 8 years ago

See also this plugin proposal for adding page-specific sidebars that get loaded dynamically: https://github.com/xwp/wp-customize-content-widgets

The problem currently is that all sidebars and all widgets get loaded up front. This doesn't scale, and this is something the plugin would fix.

jessecurry commented 8 years ago

Is the wp-js-widgets plugin far enough along that the Layers widgets could be reimplemented as JS widgets?

jessecurry commented 7 years ago

Has there been any progress on this issue with recent updates or any newly discovered workarounds?

westonruter commented 7 years ago

The JS Widgets plugin is still somewhat in an alpha state. The rest of the core widgets need to be re-implemented to use the new framework, and the framework itself needs to be evaluated as it gets used for implementing widgets.

westonruter commented 7 years ago

FYI: JS Widgets v0.2.0 was released today. It includes a more refined API and JS-driven adaptations of all the core widgets (aside from Links), as well as a Post Collection bonus widget. Another standalone widget plugin called Next Recent Posts Widget takes the concept of JS widgets a step further and uses client-side JS templating for rendering the widget as well, implementing instant updates to changes. In this widget, selective refresh used to obtain rendered REST API data, while the raw value is used until the rendered data is returned. So this means that when entering -- into the widget's title will result in -- appearing in the rendered widget while waiting for the server to return with that wptexturize applies. I think it's ready now for development to be done on integrating JS Widgets into Shortcake as their own distinct Post Elements. I think it's ready for extending, at least for prototypes. I'm working on a proposal post for Make/Core.