@JoshuaSWarren #phpworld
Magento 2 Performance:
Every Second Counts
Slide 3
Slide 3 text
@JoshuaSWarren #phpworld
About Me
• PHP-Based Ecommerce Developer Since 1999
• Magento Developer Since 2008; Magento 2 Dev Since 2014
• Magento Master
• Founder of Creatuity, Magento Enterprise Solution Partner
Slide 4
Slide 4 text
@JoshuaSWarren #phpworld
Performance Matters
Slide 5
Slide 5 text
@JoshuaSWarren #phpworld
47% of consumers expect a
page to load in 2 seconds
Slide 6
Slide 6 text
@JoshuaSWarren #phpworld
40% abandon a website that takes
more than 3 seconds to load
Slide 7
Slide 7 text
@JoshuaSWarren #phpworld
Each 1 second delay causes at
least a 7% drop in conversions
Slide 8
Slide 8 text
@JoshuaSWarren #phpworld
If a site sells $1,000 per day, a 1
second delay could cost $25,000/year
Slide 9
Slide 9 text
@JoshuaSWarren #phpworld
If a site sells $100,000 a day, a 1 second
delay can cost $2.5 million/year
Slide 10
Slide 10 text
@JoshuaSWarren #phpworld
Improving the load time for mobile
users by 1 second can increase
conversion rates 27%
Slide 11
Slide 11 text
@JoshuaSWarren #phpworld
Load time is money
Slide 12
Slide 12 text
@JoshuaSWarren #phpworld
If a bug caused 40% of visitors
to leave, should you fix it?
Slide 13
Slide 13 text
@JoshuaSWarren #phpworld
Poor performance is a bug.
Slide 14
Slide 14 text
@JoshuaSWarren #phpworld
And it’s a bug for developers
to solve.
Slide 15
Slide 15 text
@JoshuaSWarren #phpworld
Magento 2 Performance
Out of the Box
Slide 16
Slide 16 text
No content
Slide 17
Slide 17 text
No content
Slide 18
Slide 18 text
No content
Slide 19
Slide 19 text
No content
Slide 20
Slide 20 text
@JoshuaSWarren #phpworld
Given the budget, Magento 2 can scale
to any level and remain very, very fast
Slide 21
Slide 21 text
@JoshuaSWarren #phpworld
Complex customizations, if not handled
properly, can slow any site down
significantly
Slide 22
Slide 22 text
@JoshuaSWarren #phpworld
Infrastructure Matters
Slide 23
Slide 23 text
@JoshuaSWarren #phpworld
All the performance optimizations in the
world can’t compensate for bad hardware
Slide 24
Slide 24 text
No content
Slide 25
Slide 25 text
@JoshuaSWarren #phpworld
Please don’t host your ecommerce
site on $5/month discount hosting
Slide 26
Slide 26 text
@JoshuaSWarren #phpworld
Ensure Your Environment is Well Configured
• Utilize Redis for cache & session storage
• If appropriate, split your web server and database onto
separate servers
• Run PHP 7
Slide 27
Slide 27 text
@JoshuaSWarren #phpworld
Now that your
infrastructure is optimized…
Slide 28
Slide 28 text
@JoshuaSWarren #phpworld
Performance is a State of
Mind
Slide 29
Slide 29 text
@JoshuaSWarren #phpworld
There are thousands of ways
to implement a feature
Slide 30
Slide 30 text
@JoshuaSWarren #phpworld
Take the time to find the
right way
Slide 31
Slide 31 text
@JoshuaSWarren #phpworld
The Right Way
• Provides the desired functionality
• Minimizes technical debt and maintenance costs
• Does not reduce or slow site performance
Slide 32
Slide 32 text
@JoshuaSWarren #phpworld
Ivan’s Rules
• Ivan Chepurnyi, Magento performance expert
• https://ivanchepurnyi.github.io
• Ivan has four rules that changed my (dev) life
Slide 33
Slide 33 text
@JoshuaSWarren #phpworld
Ivan’s Rules
• Minimize amount of I/O operations to bare minimum
• Make I/O operations as lightweight as possible
• Spend time on requirement analysis
• Analyze the possible data impact
Slide 34
Slide 34 text
@JoshuaSWarren #phpworld
In other words…
Slide 35
Slide 35 text
@JoshuaSWarren #phpworld
Performance problems tend to stem
from too much I/O or I/O that’s too slow
Slide 36
Slide 36 text
@JoshuaSWarren #phpworld
In Magento 2, generally I/O =
MySQL database operations
Slide 37
Slide 37 text
@JoshuaSWarren #phpworld
Efficient MySQL Usage
• Avoid full table scans, avoid temporary tables and avoid the
join buffer
• Multiple simple queries tend to be faster overall than one
large, complex query
• Think about the underlying database usage triggered by the
code you write
Slide 38
Slide 38 text
@JoshuaSWarren #phpworld
Don’t Be Afraid
• Don’t be afraid to create new tables when needed
• Creating a new table to contain the data you need can be
faster than triggering complex queries and JOINs
• Don’t be afraid to try something new - the core code doesn’t
always use the fastest approach
Slide 39
Slide 39 text
@JoshuaSWarren #phpworld
Don’t Be Afraid
• Don’t fear MySQL. The more you learn about MySQL, query
optimization and how MySQL executes queries, the better
you will become at performance optimization
Slide 40
Slide 40 text
@JoshuaSWarren #phpworld
But what if you didn’t write the code
on a site that’s running slowly?
@JoshuaSWarren #phpworld
Code Profiler
• No, not the late 90’s TV show
• A tool to measure the performance of your PHP code,
including the time it takes to run and the resources it
consumes
• There are a many options for profiling your code
Slide 47
Slide 47 text
@JoshuaSWarren #phpworld
Profiling Options
• xdebug
• xhprof
• blackfire.io
• There are many options, but…
Slide 48
Slide 48 text
@JoshuaSWarren #phpworld
Rifleman’s Creed
This is my rifle. There are many like it, but this one is mine.
Without me, my rifle is useless. Without my rifle, I am useless.
Slide 49
Slide 49 text
@JoshuaSWarren #phpworld
Hunting For Slow Code…
Slide 50
Slide 50 text
@JoshuaSWarren #phpworld
Profiler’s Creed
This is my profiler. There are many like it, but this one is mine.
Without me, my profiler is useless. Without my profiler, I am
useless.
Slide 51
Slide 51 text
@JoshuaSWarren #phpworld
Blackfire.io
• I’ve chosen Blackfire.io as my profiler of choice
• I recommend it, but these techniques will work with any
profiler, some just make it easier than others
• Blackfire provides substantially more than what I can show
today, so today we’ll just focus on performance profiling
Slide 52
Slide 52 text
@JoshuaSWarren #phpworld
What can Blackfire Do?
• How about point you to a way to make a page 99% faster?
• Before:
• After:
Slide 53
Slide 53 text
@JoshuaSWarren #phpworld
Let’s review the profiles in
detail…
Slide 54
Slide 54 text
@JoshuaSWarren #phpworld
Reviewing A Profile
• Total load time is 4 minutes 57 seconds
• One call makes up 4 minutes 54 seconds - PDOStatement:execute
select main_table.*, ... from sales_flat_order_grid as main_table left
join sales_order_custom on sales_order_custom.order_id =
main_table.entity_id left join orderarchive as orderarchive_tbl on
orderarchive_tbl.order_id = main_table.entity_id where
(orderarchive_tbl.order_group_id is null or
orderarchive_tbl.order_group_id = ?) order by created_at desc limit ?
Slide 55
Slide 55 text
@JoshuaSWarren #phpworld
Reviewing A Profile
• I/O - database I/O is our bottleneck
• We’re breaking Ivan’s rules - lots of I/O, and it’s not
lightweight
• In this case, we discovered a simple solution - not only were
there multiple LEFT JOINs, they were being performed with
no indexes!
Slide 56
Slide 56 text
@JoshuaSWarren #phpworld
Let’s review the ‘after’ profile
now…
Slide 57
Slide 57 text
@JoshuaSWarren #phpworld
Reviewing A Profile
• Reduced the time needed for this SQL query from 4
minutes 54 seconds to 550 milliseconds.
Slide 58
Slide 58 text
@JoshuaSWarren #phpworld
Adventures in Magento 2
profiling on conference wifi…
Slide 59
Slide 59 text
@JoshuaSWarren #phpworld
Writing Fast Magento 2 Code
Slide 60
Slide 60 text
@JoshuaSWarren #phpworld
Build a Culture & Process of Performance
• Each new commit, pull request or build should trigger a
profiling run of all key pages
• Any significant decreases in performance should trigger a
failed build alert
Slide 61
Slide 61 text
@JoshuaSWarren #phpworld
Build a Culture & Process of Performance
• Spend time talking about performance when designing
solutions
• Share your experience and the trends you notice with your
teammates and other Magento developers
Slide 62
Slide 62 text
@JoshuaSWarren #phpworld
Writing Fast Magento 2 Code
• Avoid the database as much as possible
• When database access is required, use simple, well-indexed
queries
• If you see a need to access the filesystem…
Slide 63
Slide 63 text
No content
Slide 64
Slide 64 text
@JoshuaSWarren #phpworld
When Slow I/O Can’t Be Avoided
• Move it to a background or periodic process
• Utilize as much caching as possible
• Design it in such a way that it impacts as few sessions as
possible
• Major difference between slowing down every page view on
a site versus slowing down every cart completion
Slide 65
Slide 65 text
@JoshuaSWarren #phpworld
Test and profile multiple
potential implementations.
Slide 66
Slide 66 text
@JoshuaSWarren #phpworld
Advanced M2 Optimization
• The following tips are thanks to Max Pronko - https://
www.maxpronko.com/ - @max_pronko
• Based on Max’s real world experience as CTO of a merchant
that uses Magento 2
Slide 67
Slide 67 text
@JoshuaSWarren #phpworld
Advanced M2 Optimization
• Disable unused core modules - for instance, if you don’t
offer downloadable products, disable
Magento_Downloadable
• Disable reports and features you don’t use
• Remove any blocks you aren’t using from your theme
Slide 68
Slide 68 text
@JoshuaSWarren #phpworld
Advanced M2 Optimization
• If your site only offers one language, disable inline
translation
• Move as many of your scripts as possible to load async
Slide 69
Slide 69 text
@JoshuaSWarren #phpworld
Homework
Slide 70
Slide 70 text
@JoshuaSWarren #phpworld
php[world] sessions
• DCPHP User Group Meeting: PHP Performance Profiling
Using Blackfire
• Tonight, 7PM, Ash Grove B
• Magento 2 Development Best Practices
• Friday, 10AM, Ash Grove A
Slide 71
Slide 71 text
@JoshuaSWarren #phpworld
Future Events
• Meet Magento World - Online Conference in December -
http://meet-magento.com/conference/meet-magento-world/
• Magento 2 Performance Training - January 18th-20th in
Orlando with Ivan Chepurnyi - http://bit.ly/2eAo8cz
• Magento Imagine 2017 - April 3rd-5th in Las Vegas -
imagine.magento.com
Slide 72
Slide 72 text
@JoshuaSWarren #phpworld
Remember that performance
is a state of mind
Slide 73
Slide 73 text
@JoshuaSWarren #phpworld
Poor performance is a bug
Slide 74
Slide 74 text
@JoshuaSWarren #phpworld
Go try a profiler on a Magento site,
identify one performance problem and
solve it
Slide 75
Slide 75 text
@JoshuaSWarren #phpworld
Tweet at me @JoshuaSWarren with what the
problem was and how you solved it.
I bet it’s I/O related…