magento / magento2

Prior to making any Submission(s), you must sign an Adobe Contributor License Agreement, available here at: https://opensource.adobe.com/cla.html. All Submissions you make to Adobe Inc. and its affiliates, assigns and subsidiaries (collectively “Adobe”) are subject to the terms of the Adobe Contributor License Agreement.
http://www.magento.com
Open Software License 3.0
11.48k stars 9.29k forks source link

Checkout page very large and quite slow. #4868

Closed pynej closed 7 years ago

pynej commented 8 years ago

Using a single store on 2.6 in production mode. No combined JS/css, with setup:di:compile, varnish, and SSL for checkout.

Normal pages work quickly through varnish as expected in 2s/100ms uncached/cached and around 12k each. Customer pages like past orders come in without varnish as expected in 1.5-2.5s at around 40k. Going to the checkout with a single item in my cart take 4.5s and weights in at 800k and seams to go up in size and response time.

Note that these times are for the roundtrip for the html file, not any resources or images.

ishakhsuvarov commented 8 years ago

@pynej Thank you for reporting this issue. We already have an internal backlog item MAGETWO-40101 to improve checkout loading time and make the page cacheable. We will update this ticket when it's implemented.

daniel-ifrim commented 8 years ago

@pynej @ishakhsuvarov Checkout page has in it JSON data for all payment methods and shipping methods that are disabled in admin. This is why the page html source is this large. Magento_Ui should filter out at least disabled payment methods and shipping methods. And all regions from database are redundant in those JSON objects.

SchumacherFM commented 8 years ago

We ran into the same issue that all payment methods will be loaded regardless if deactivated.

screen shot 2016-08-03 at 09 21 49

screen shot 2016-08-03 at 09 40 52

Would be nice if you guys can fix it ASAP ...

pynej commented 8 years ago

On 2.1 We were able to enable the Merge Css, Merge JS, and Bundle Js options and with all three on the issues seam to goo away.

SchumacherFM commented 8 years ago

The bug is still not fixed and enable bundling and merging hides only the problem.

Customers are already complaining about the bloated checkout page.

pynej commented 7 years ago

Yes. I would say this is a critical issue and makes us look very bad to our customers. The site, products, and custom loggin pages are all quite fast @.5ms for cached requests and 1s for uncached requests. But anyone getting to the checkout page is in for a nice 10s delay and gets very irritated. We have even disabled some unused of the shipping modules per advice I found but that had a very minimal impact on the performance.

To clarify the checkout page is 50 times larger then any other page on the site and its loading 5 times as much javascript code. Or with bundling turned off its loading 50-90 separate scripts per page load.

Also the way that the varnish/caching works the /checkout and its resources don't benefit at all form these systems. This means that the checkout page spends 1.85s processing in PHP with all the setup:di:compile complications, all caches enabled, and opcach set up. It then has to spend a further 1.5s downloading the large file. Then it gets to loading wither 90+ scripts or the 3.5MB bundles file either way taking another 6s.

pynej commented 7 years ago

These example numbers are with the following disabled: List of disabled modules: Magento_Dhl Magento_Fedex Magento_Authorizenet Magento_Paypal Magento_Braintree

We did load a custom module for CC processing: MD_Cybersource

pynej commented 7 years ago

The script block stertign with this is 440KB of JSON data.

<script type="text/x-magento-init">
        {
            "#checkout": {

Most of the data here looks like it is Locality info. Region/State info that is filled in the dropdown when country is changes. At the very leas this should be changed to be loaded when the country is actually changed as 99% of this data isn't going to be used on a individual page. An api that returns the regions for the selected country will significantly reduce this page size.

pynej commented 7 years ago

Reducing the 'Allow Countries' in settings to only US doesn't entirely remove the entries form the page HTML but it does reduce the checkout page form 476KB to 371KB.

loekderooij commented 7 years ago

This is a real serious issue, especially when you have many payment methods. One of our customers uses 2 payment providers which makes the total of payment methods 50+. Excluding countries and region reduces the request size, but even then the code looping these methods gets real slow. Total loading time took up to 30 seconds.

Since our customer only uses a total of 7 payment methods, I 'fixed' this by writing a plugin for 'Magento\Checkout\Block\Checkout\LayoutProcessor' in which I strip all payment methods that are not active for the current storeview. Now the page takes only 2 seconds to load instead of 30. This is however not a real solution to the problem.

pynej commented 7 years ago

Related to https://github.com/magento/magento2/issues/6997 though there may be more issues like the payment methods not covered in that ticket.

KalaiarasanSeetharaman commented 7 years ago

We are using magento 2.0.6 . It is present in live . Checkout page is very slow . Why it is very slow when compared to magento 1 . Magento 2 is slow. How to optimize for checkout page . I have enabled cache system also , other optimization in backend also i did . But still slow for magento 2 checkout page it take arround 2 min more

thlassche commented 7 years ago

@SchumacherFM @ishakhsuvarov @pynej I fixed this by adding a layout processor plugin. It checks whether the default payment methods of Magento are enabled or not, and if they are disabled it removes them from the JS layout. Dramatically reducing the page load of the checkout page

di.xml:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Checkout\Block\Checkout\LayoutProcessor">
        <plugin name="checkoutLayoutProcessor" type="\<vendor>\<moduleName>\Plugin\CheckoutLayoutProcessor" />
    </type>
</config>

CheckoutLayoutProcessor.php:

<?php
namespace <vendor>\<moduleName>\Plugin;

use Magento\Checkout\Block\Checkout\LayoutProcessor;
use Magento\Framework\App\Config\ScopeConfigInterface;
class CheckoutLayoutProcessor {

    protected $scopeConfig;
    public function __construct(ScopeConfigInterface $scopeConfig) {
        $this->scopeConfig = $scopeConfig;
    }

    public function beforeProcess(LayoutProcessor $layoutProcessor, $jsLayout)
    {
        // Do not render jsLayout of disabled payment methods (fixes Magento core bug)
        if ($this->scopeConfig->getValue('payment/free/active') == 0)
            unset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['renders']['children']['free-payments']);
        if ($this->scopeConfig->getValue('payment/banktransfer/active') == 0)
            unset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['renders']['children']['offline-payments']['methods']['banktransfer']);
        if ($this->scopeConfig->getValue('payment/cashondelivery/active') == 0)
            unset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['renders']['children']['offline-payments']['methods']['cashondelivery']);
        if ($this->scopeConfig->getValue('payment/purchaseorder/active') == 0)
            unset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['renders']['children']['offline-payments']['methods']['purchaseorder']);
        if ($this->scopeConfig->getValue('payment/checkmo/active') == 0)
            unset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['renders']['children']['offline-payments']['methods']['checkmo']);
        return [$jsLayout];
    }
}
Khaleel commented 7 years ago

This is still not resolved.

Magento 2 Checkout JS:

This code is JSON fired inside the HTML rather than an API call - that code is around 957kb call it 1mb

When you JSON Lint fire the code it returns 2.1mb of JSON

Your developers need a kick up the ass in Ukraine.

SerhiyShkolyarenko commented 7 years ago

We are closing the issue because MAGETWO-60351fix is delivered to develop branch. Thank you!

thlassche commented 7 years ago

@SerhiyShkolyarenko Is that true? Bug is still present in 2.1.3

@Khaleel @SchumacherFM @ishakhsuvarov @pynej I developed an extension to solve the issue. Please let me know when you need it.

andidhouse commented 7 years ago

Is this really fixed in 2.1.3? We use 2.1.3 in production mode and the checkout it very very slow... taking about 3-4 seconds on mobile devices to load.

Khaleel commented 7 years ago

We have the following:

Entire website loads on a CDN via a dns rule. So whole site is on Akamai. All the site is cache via varnish - I realise checkout some files are skipped We made a cache prewarmer for knockoutjs loading We removed loads of modules on the checkout and countries and addresses we dont ship too

Still incredibly slow. Our Technical Director has suggested we create a subdomain seperate custom checkout and just tie into the Magento API .. some front end reactjs/angular app checkout system that ties into Magento API..

RequireJS, KnockoutJS are pretty outdated compared to newer engines

andidhouse commented 7 years ago

we have kind of the same experience here. The checkout built is very complex and slow. We do not see any improvement here to magento v1 - so very disappointing. We not put any effort any more into custom solutions. If the magento team fixes the major issues soon - good! If not there are plenty other great nearly bugfree systems out there. Just wondering that the magento team does not put any effort into checking the checkout performance 👎

BlackIkeEagle commented 7 years ago

@SerhiyShkolyarenko could you refer to the merge commit in your comment please?

hostep commented 7 years ago

In case anyone is interested in making the checkout faster in Magento 2.1.x, we have gotten it almost twice as fast as it was before, using:

1) The commit MAGETWO-59685, you need to fiddle a bit with the diff from this commit to apply it cleanly on a stock Magento installation, but it is not that hard. (If you use Magento 2.1.2 you'll also need the class Magento\Directory\Model\AllowedCountries which was introduced in Magento 2.1.3 and on which MAGETWO-59685 relies to work properly, if you use Magento 2.1.3 and up, you already have this class). This first part strips away all countries and regions which you don't use in your shop resulting in a much more leaner json data structure.

2) The second part is where you'll need to strip away unused payment methods, which also results in an even smaller json data structure. I first tried backporting MAGETWO-60351 to Magento 2.1.x, but failed to do this, since it is built upon a whole bunch of other commits which aren't released yet. So we took the approach which @LuckyLoek and @thlassche mentioned above and built a custom Plugin for Magento\Checkout\Block\Checkout\LayoutProcessor::process method, which strips out all unused payment methods from the $jsLayout array. In the following structures you can strip away unused payment methods:

All of this results in the json data structure being significantly smaller then before and getting parsed much quicker in your browser, which makes the checkout as a whole much quicker to load.

Watch out: all the above was only tested properly on Magento 2.1.2, it should in theory work for 2.1.3 but this wasn't tested properly. And 2.1.4 wasn't tested at all.

Hope Magento is able to backport both MAGETWO-59685 and MAGETWO-60351 to Magento 2.1.x and is not keeping these fixes exclusively for Magento 2.2 and up.

Hope this helps someone :)

Khaleel commented 7 years ago

Thanks for the insight @hostep a shame since were still on 2.0.4

che2on commented 7 years ago

Please make the checkout load faster by default!

che2on commented 7 years ago

With all due respect, I also feel magento team is not serious about magento2. The checkout process takes around 30 to 40s with current setup. It is very important part of a business. If we are not able to fix the loading issue, it is unusable for businesses and can be only used for testing or hobby projects

che2on commented 7 years ago

I withdraw my previous comment. I was running magento in php bin/magento deploy:mode:set developer mode instead of doing it on production mode.

Now the one page check out page is loading within 4 to 5 seconds.

@all please make sure you are in production mode by doing

php bin/mageno deploy:mode:set production

andidhouse commented 7 years ago

4-5 seconds is not acceptable at all for a "state of the art" ecommerce system at all. We put our system now on a dedicated xeon cpu server with 64 gb ram and ssds - will report if this changes anything if not...hmmm

Khaleel commented 7 years ago

I have said time and time and time again.

The failure of M2 was RequireJS and Knockout JS and LESS and poor Front End Architecture submitted by Alan Kent and his team in Ukraine. Call me racist or say what you want but the European developers are "Back End" minded and have no clue of Front End Development and have bloated and over engineered the development method, deployment method and outsourcing and cheapening the outsource of Magento from LA has caused this.

The Back End too has mixed in a lot of poor vendor and bloated architecture - really, so many composer and xml and helpers needed just for simple module re-writes? The architecture and new DB is way to complex..

pynej commented 7 years ago

"4-5 seconds is not acceptable at all for a "state of the art" ecommerce system at all. We put our system now on a dedicated xeon cpu server with 64 gb ram and ssds - will report if this changes anything if not...hmmm"

Yah, and for a simple web application like this the "Solution" to performance issues shunt be "throw more cpu and ram at it". I'm easily able to get a wordpress site responding in less that 1 second on a single core server with 2gb or ram for references.

hostep commented 7 years ago

@pynej: the slowdown on the checkout is caused by javascript, which runs in the browser, so upgrading your hardware won't help in this case. It might help for other cases but not for the slow checkout page I'm afraid.

che2on commented 7 years ago

Yes. 4 to 5 seconds is bad. and it goes upto 10 to 20 seconds on old devices / mobile phones. In fact, the loading gif image is very very irritating. Team magento should get rid of loading bar, instead should load the one page check out in under 1 second. Please do this change, I assure everyone would love magento2. Checkout is a very important step and magento2 should fix this issue on priority and keep up their reputation.

@all Can someone please share a plugin like @thlassche suggested, i tried the checkoutLayoutProcessor plugin and i couldn't deploy as i made some syntax mistake while adding it under/app/code/etc .

@hostep By any chance is it possible for you to share a plugin some code so that can be applied to make checkout load under 1-2 seconds?

@magento-admin Where exactly is the the timeline, will 2.1.5 magento include the checkout fix?

hostep commented 7 years ago

@che2on, I'm not promising this will reduce it to 1-2 seconds, but it should certainly help a little bit. Below is some sample code from our solution (it's almost the same as @thlassche's solution, so he earns the credits :)). This isn't a full module, just the important bits (and yes it is very ugly, the clean solution would be to get a list of all active payment methods and throw out the ones which aren't in that list, currently we did it by hardcoding the payment methods which should be removed):

namespace Vendor\FasterCheckout\Plugin\Checkout\Block;

use \Magento\Checkout\Block\Checkout\LayoutProcessor as CheckoutLayoutProcessor;

class LayoutProcessor { public function afterProcess(CheckoutLayoutProcessor $subject, array $jsLayout) { $jsLayout = $this->removeUnusedPaymentMethods($jsLayout);

    return $jsLayout;
}

// tnx to https://github.com/magento/magento2/issues/4868#issuecomment-259244034
private function removeUnusedPaymentMethods($jsLayout)
{
    if (isset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['renders']['children']))
    {
        $paymentRenders = $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['renders']['children'];

        /* !!! these are just examples, only remove the ones you don't use !!! */
        unset($paymentRenders['offline-payments']);
        unset($paymentRenders['authorizenet']);
        unset($paymentRenders['vault']);
        unset($paymentRenders['paypal-payments']);
        unset($paymentRenders['braintree']);

        $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['renders']['children'] = $paymentRenders;
    }

    if (isset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['payments-list']['children']))
    {
        $paymentListChildren = $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['payments-list']['children'];

        /* !!! these are just examples, only remove the ones you don't use !!! */
        unset($paymentListChildren['checkmo-form']);
        unset($paymentListChildren['banktransfer-form']);
        unset($paymentListChildren['cashondelivery-form']);
        unset($paymentListChildren['purchaseorder-form']);
        unset($paymentListChildren['authorizenet_directpost-form']);
        unset($paymentListChildren['payflowpro-form']);
        unset($paymentListChildren['payflow_link-form']);
        unset($paymentListChildren['payflow_advanced-form']);
        unset($paymentListChildren['hosted_pro-form']);
        unset($paymentListChildren['paypal_billing_agreement-form']);
        unset($paymentListChildren['braintree-form']);

        $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['payments-list']['children']  = $paymentListChildren;
    }

    return $jsLayout;
}

}

Khaleel commented 7 years ago

The JSON address, the JavaScript, the HTML, the fact that checkout pages do not have any cache layer, the lack of default CDN support, minification and the use of all the checkout modules and XML files.. checkout should have been simple and clean.. it was over engineered.

che2on commented 7 years ago

@hostep Tried your FasterCheckout module and it is now taking 80 seconds to load. :(

che2on commented 7 years ago

Here is a good news! I am learning more and more about magento as i am discovering bugs and speed issues.

The Checkout page speed is under 3 seconds now, used @thlassche's solution.

The very very important step is to System > Advanced > Developer and minify javascript and css .

Also use varnish and redis for caching.

If someone wants the entire module please have a look at this generator https://mage2gen.com/ and use the code suggested above.

So far it is going good. Will be back here for the next speed fight.

plentyhappy commented 7 years ago

Desktop works fine but Android checkout takes 10 seconds and iphone not much better (tried this on multiple phones from different people). Changing to production mode really does not help - have not tried the @thlassche's solution yet.

Anyone from team Magento have update on when checkout will get quicker? Will it be part of the next release or a few months from now?

twistedatrocity commented 7 years ago

@plentyhappy I would not count on it any time soon. There are major bug fixes committed to the develop branch as far back as a year ago that have still not made it into a release. I really don't know what this company is thinking anymore.

plentyhappy commented 7 years ago

Here's an idea for Magento team:

http://feedback.shipstation.com/forums/330429-product-feedback-fresh-ideas/filters/top

users are allowed I believe 3 votes...you can use all your votes on 1 feature requested or split them up and hope that other users share your concern. Magento could use this for bug fix requests and/or feature requests.

hostep commented 7 years ago

@twistedatrocity: the community can now submit PR's to backport certain fixes from the develop branch to the 2.1-develop branch, and if they get accepted, they will be released in one of the upcoming 2.1.x releases: https://community.magento.com/t5/Magento-DevBlog/Pull-Requests-for-2-1-x-Patch-Releases/ba-p/65630

I'm thinking about submitting a PR to backport MAGETWO-59685 in one of the next days. This one should already improve the speed of the checkout somewhat, certainly if you aren't selling to a lot of different countries. I already tried backporting the other fix (MAGETWO-60351) for this slowdown issue a couple of months ago, but failed to do so. This one is probably going to have a bigger effect then only MAGETWO-59685, but it should already be a small step forwards.

@plentyhappy: there is already a way to upvote issues: https://community.magento.com/t5/Magento-DevBlog/GitHub-Issue-Priority/ba-p/60088, although it isn't very clear about how to vote for issues to get backported. But now the community can get involved in this by submitting PR's (see above).

Just fyi :)

plentyhappy commented 7 years ago

Thanks for the information hostep! Fingers crossed for backport :-)

magento-team commented 7 years ago

Internal ticket to track issue progress: MAGETWO-67724

magento-team commented 7 years ago

Internal ticket to track issue progress: MAGETWO-67725

thlassche commented 7 years ago

I now have an extension which contains my fixes + additional fixes to load only active countries. The JSON now only contains relevant data for me.

delyriand commented 7 years ago

Hi @thlassche ! Can we get your module somewhere? I have same problem with checkout ... It is very slow on tablet and mobile.

thlassche commented 7 years ago

@delyriand Yes, just drop me an e-mail

tomlever commented 7 years ago

Hi @thlassche , is it possible to get your module?

hostep commented 7 years ago

@tomlever: you can just upgrade to Magento 2.1.8, it should contain the fixes discussed in this issue.

thlassche commented 7 years ago

@tomlever Sure, just drop me an e-mail

Khaleel commented 7 years ago

I am on 2.1.6 and face same issues. The module can be found here: https://marketplace.magento.com/thlassche-performancetweaks.html @tomlever

sbwcws commented 6 years ago

Did that extension help any one to speed up the checkout process