Wilson Page wrote a really great article for Smashing Magazine digging into a real world website and all the cool modern tools and techniques he and his team used to build it.
For layout, they initially chose flexbox, but…
As the app began to grow, we found performance was getting worse and worse.
We spent a good few hours in Chrome Developers Tools’ timeline and found the culprit: Shock, horror! — it was our new best friend, flexbox. The timeline showed that some layouts were taking close to 100 milliseconds; reworking our layouts without flexbox reduced this to 10 milliseconds!
There are some before/after screenshots of the dev tools timeline in the article. Worrysome, no?
I was talking to Tim Kadlec about it. Tim said he reached out to the team to see if they had created a reduced test case or had any more data to share. Unfortunately they did not.
Maybe we can find that data. I built a little random flexbox layout generator thingy.
See the Pen Generate a Crapload of Flexbox by Chris Coyier (@chriscoyier) on CodePen
Sliding that range slider around regenerates the random flexbox layout. The further to the right, the more. So far, I haven’t been able to find anything terribly taxing. However, my little demo there isn’t exactly “real world”. Perhaps images inside there are problematic. Perhaps using the flexbox properties to change source order are what is taxing. Perhaps old flexbox is the culprit. Perhaps there is nothing to be worried about at all.
If you have any ideas on how to replicate some bad performance around flexbox, feel free to fork my generator thingy and add/change what is needed to make it happen.
The best way I know of to actually measure the performance is Chrome Dev Tools > Timeline. Then hit the “Record” button, slide the slider around, and stop. Then look around the timeline for long paint times. Like this:
The purple there is layout, which is fast in this case (so far).
I’ll Update This Post
If we can gather some solid data, I’ll update this post with those closest thing to an answer as we can to the title of this blog post.
UPDATE: And here we go!
I have just experienced the same thing while building an app.
The view using flexbox, besides the overall layout, was a calendar with a month view. Having it on screen would slow down render quite a bit.
Switching to a table for the calendar view, sped up the whole view tenfold.
Interesting! Do you have comparison test cases made up for that? That’s exactly the kind of thing that would fit the bill here.
Once I’m back from vacation I can try to recreate it :-)
Tables have always been more performant than freely styled markup though — recreating tabular layouts (as so many standardista hipsters were ever so eager to do) using a system of floats would have a massive impact on render speed.
@Barney .. that’s very hard to say without numbers. I’d be interested in data on the difference.
Jeppe have you tried this on Opera my browser starts to hang?
I have tried to recreate my problem, but I don’t see the big performance problem.
I did use angular earlier, and didn’t this time.
http://codepen.io/bobslaede/full/pixcn
Check it out.
@Ajman
I haven’t tried in Opera
Why am I thinking that it may not be “flexbox’s” fault but browser implementation instead…
I think it’s highly likely that “old” flexbox is a bigger culprit than new, hoping for some data on that.
I can confirm the performance problems we experienced were with the old
display: -webkit-box;
syntax. We also made made huge layout perf gains on Blackberry Playbook by removing unnecessary flexboxes from The Economist web app. I cannot speak for the performance of the new syntax on mobile as it is currently not supported on any of a target devices.Excellent good to know.
Do you have some test cases put together? My goal here is to have a demo we can point people to and say, look, here’s the problem. Real demo / real data kinda thing.
I wanted to play around with this one some more… It’s a little tough in the demo above to compare the layout costs against paint, innerHTML (parsing HTML into DOM is costly!), and the underscore templating..
So I did a head-to-head comparison of old v new syntax, as I know the FT team used the old flexbox without dropping in the future-forward syntax.
Old v New Flexbox Benchmark
New flexbox: layout costs of _~18.2ms_
Old flexbox: layout costs of _~43.5ms_**
So old is 2.3x slower than new.
Summary
When using flexbox, always author for the new stuff the IE10 tweener syntax as well as the new updated flexbox that’s in Chrome 21+, Safari 6.1+, Firefox 22+, Opera (& Opera Mobile) 12.1+, IE 11+, and Blackberry 10+.
(I’m a little curious about the layout costs of this demo are with
float
s ordisplay:table
, but.. the numbers would be very specific to this particular style of layout.)What’s more important is optimizing what matters. Always use the timeline to identify your bottlenecks before spending time optimizing one sort of operation. FT did indeed encounter a layout bottleneck in their code, but I’ve been working with Wilson on that and we’ll actually be improving the Chrome DevTools as a result!
Err’body wins.
This is awesome Paul! Thanks for clearing this up :)
We do now have future syntax in place, but any perf gains wont take effect on mobile Safari (our primary platform) until iOS7 gets rolled out. I also believe it will land behind a ‘-webkit-‘ prefix, unlike Chrome (currently Canary) where you can use it in all its unprefixed glory :)
For funsies, Chris and I just tried out display:table-cell and it hit 30ms, right between the other two. Pretty neat.
I should point out that these numbers are specific to Webkit/Blink. Due to the time of implementation, flexbox is pretty much identical across Safari & Chrome & Android.
Who cares if it’s slow? What are you gonna do? Use floats and weird faux columns again? Eh no. I’ll take 18 or 45 ms.
Wellll. 45ms ain’t much but on mobile x10 that’s 450ms and you’re looking at a half second for something that is normally close to nothing, and doesn’t factor in all the other traditional culprits for speed. That’s on a rather extreme layout, but still, something to be aware of.
As far as I’m concerned, I’d rather strain myself with old layout methods than slowing the whole page to half a second for mobile users.
Performance is quite all that matters on small devices with crappy connection. No matter if it’s easier or hard to code.
I’m kind of with Hugo on this one. Depending on the size of a project, that performance issue can make Flexbox for full layout a no-sell for me. I’ve considered using Flexbox within an existing grid framework for components; falling back where it wouldn’t work as well. I’ll keep doing my own experiments to see how maintainable that sort of approach would be.
One thing about the whole mobile is 10x slower thing… how many websites use the same layout on mobile as on desktop? I’m sure it’s easy enough to strip out most (if not all) flexbox stuff for mobile.
CrocoDillon
@CrocoDillon you’re right, Flexbox is not so useful for small phone size screens, but on larger tablet size mobile devices it is.
The mobile flexbox layouts are simple and the boxes are usually less than 10. Even if there is a slowdown, it is negligible. Our mobile framework is built around flexbox and this doesn’t seem to slow it down.
Thank you guys! I had just mastered flexbox and started using it in my projects when I read the article by Wilson Page and really wished someone would dig deeper into that claim. You read my mind. Chris and Paul, BIG fan!
I had similar issues. We had an implementation of the old spec and the latest version of Firefox would end up timing out on scripts (I think DOM insertion). I updated to include the new spec and it worked but was very slow.
For me, it turned out my problem was heavy nesting. It was in a CMS with a bit of div-itis so I was having to apply flex: 1 to a lot of nested elements. I overrode the stock templates to reduce to markup and it’s now running very snappy. I don’t have any numbers available at the moment though.
Is the flexbox model already used in production? I thought using flexbox in real-world Websites is still far away?
@kaspar, we are lucky enough to only have to support iOS, Android, Windows 8 (IE10) and Firefox. All of which at least support the
display: box;
spec. If you are supporting IE 7, 8 or 9 you will have to gracefully degrade, or find an alternative. I believe there are also JavaScript polyfills that can fill the Flexbox gaps too.no. many clients still want an optimization for ie8 or ie9. sure, this is painfull.
using flexbox has general influence on a layout. it is not like a not supported shadow.
Maybe I am off-topic but here there is a website with flexbox on production ocomcareers.com
Cannot say how much slower it is though, I can only say that its not that bad either on mobile
Since I haven’t seen it documented anywhere else, I took the time to gather all of the flexbox properties together and link to their reference documentation. Anything related to each of the different implementations over time, from Apple, Microsoft, Mozilla, or the W3C web sites all listed in the order you’d want to use (so newer implementations of flexbox in Chrome supersede the older) all in one place: Flexbox / Flexible Box Layout CSS Reference.
I have seen this aricle on smashing magazine when I had to optimize site for ie8. grrr.
Lets hope the browser vendors get optimizing this now that they’ll start getting lots of real world feedback and examples.
I think I am getting different results here! .. Has anyone tried this on the Opera version ?
In my experience & testing flexbox runs into particular trouble in Firefox – I think it’d be wise to be testing for this as well as chrome – we’ve had even just very simple layouts load 20-30 times slower in FF (much to our horror)
However I do think most of our tests were run on the old syntax, which looks to be much slower
While I was working on https://play.google.com/store/apps/details?id=com.triapodi.apprec I incread the performance for at least 6x times just on removing
flexbox
(Webkit outdated flexbox syntax) andborder-radius
.Did you happen to have some tests/data for that? That’s perfect and the exact kind of thing I’d like to gather in this article. I worry that people will pick up stuff like “Not using flexbox is six times faster!” without context or data on what that means and what exactly was tested. That’s particularly interesting because it’s mobile where the old syntax is most pervasive and almost certainly slower, so if we could gather real numbers that would be amazing. (I’m not even sure how to get real performance profiling numbers on mobile)
I think this just highlights the fact that in a real world situation we may just need to restrain ourselves on rolling out some of the newer technologies even where the user base has a supportive browser base… The main thing this does highlight though is that testing what ever we produce as developers is key.
We’ve been building up a site using a SASS version of jQuery Mobile 1.3.2 and Knockout.js. As the grid on jQuery Mobile is limited, and we needed a lot of flexibility with columns to be able to show the content on several size screens, I tried to introduce flexbox based grid into the solution. I ended up using flexgrid, as it had a fallback to the old flexbox, and it already had SASS components ready.
Before inserting flexbox into it, we already had some problems loading up a several hundred item long list in a view – I wished the flexbox to be the answer to get the speed and responsiveness to help the framework to finish the task quicker and smoother.
The actual time of getting the application running and data downloaded on desktop/laptop computer was sort of ok, and expected. But, when we used Windows 8 tablets (with Atom processors) and IE10 (which are going to be used to use the app), the times were not good at all.
Before flexbox we retrieved a list of ~450 items in ~1 minute 10 seconds from the server. With flexbox the time was prolonged to ~1 minute 40 seconds. When I investigated the symptoms with Chrome timeline, it was showing the parsing of the data, rendering and retrieving it to take the majority of the time.
I decided to ditch the flexbox and find a way to get to a faster results with jQuery Mobile grids – I just didn’t have time to test it further.
I learned from this that flexbox is not a way to build up a big list of data – yet. It may be good for smaller, static sites, or pages, but not data-heavy pages.
After changing back to jQuery Mobile grid system, I got the download time squeezed on IE10 to 40 seconds, and Chrome 20 seconds when I also dropped the jQuery Mobile list view JavaScripts. However, Chrome does not seem to be able to render the list as well as IE, and is generating ghosting…
My mobile UI framework’s layout manager is completely based on the flexbox model(both old and new syntax). I have not seen any real degradation in performance in any mobile device I have tested. Of course, speed is relative in terms of processing power on these devices, but the tests have not indicated anything to be alarmed at. Note that on any one screen/page, we are laying-out/rendering ~ 500 elements in 20 – 80ms. I think that other known “slow” CSS properties (box-shadow, border-radius, gradients …) might be the culprits in some of the performance issues mentioned.
Anyway just wanted to add my $0.02.
Just wanted to mention that we observed performance degrade exponentially with the number of nested flexboxes. I’m not sure if this is something that has been factored into any performance tests so far.
Great point Wilson. In my UI framework, all containers are inherently flexboxes, but their children, not necessarily flexboxes/flex-items. That being said, in sample apps that I have written, the max level nesting of flexboxes has been 4 (per element), so I don’t know if that is a good representation with respect to your tests or with what you have seen.
Will need to run my own tests with respect to “x” number of nested flexboxes to see when performance really begin to degrade noticeably.
BTW, off topic, love your FastDom…:)
Thanks Cesidio! Hoping it can play a small part in speeding up the mobile web :)
flexbox does have a performance problem, but it’s not flexbox itself but the implementation
firstly, the new flexbox may be faster than the old one, but surely mozilla’s old flexbox implementation was faster than the webkit’s new one
proof of that is we were able to resize XUL guis with any lag whatsoever; instead, resizing now guis with similar contents on chrome causes 2-3s full-page renderings
but the worst part is the optimization
unless you’re going to modify a fixed size rectangle, every dom modification causes a full page render, which again, freezes the whole browser window for at least a couple of seconds
i have nothing to say about mozilla’s new implementation because i found a bug that makes the browser crash and i didn’t have time yet to check what’s causing it
if someone is interested i will set up a demo that shows the issues
(note: every test i made uses no gradients, no shadows, no border radius, opacity or other settings that may cause performance issues)
For example,
these two produce basically the same result, but in practice modifying the #test1 DOM subtree a full document re-render, whereas #test2 re-renders only the element itself and possibly part of its subtree
(note: i didn’t actually test this very code alone, just saying that this happens in my real-word gui)
hope to find some free time to set up a test page during holidays
sorry, my mind is still using
-moz-box-orient
:Pflex-direction:vertical
=>flex-direction:column
Wes, a test page and a ticket at crbug.com would be most excellent. We want to make sure the implementation is fast, so your test case will be super helpful to help us optimize. Thanks so much!
Holler at me if you need any help with that.
Thanks for the feedback! In my experience just providing a big dump of code on bug trackers doesn’t help to get bugs fixed :P
Should I try to isolate the problem? I believe there are many problems involved, surely not all related to flexbox, and probably each of them should have its own bug report.
Yes please! That’d be perfect. crbug.com is the place to report for Chrome. coding.smashingmagazine.com/2011/09/07/help-the-community-report-browser-bugs/ has all the details.
submitted the first report! 331352
hope it is detailed and “isolated” enough :P
thank you
anyway guys, i think i have made bad advertising to flexbox so i want to say also this
give it a try and give browsers some time
flexbox is, no question, brilliant
I’ve been developing a web-app using flexboxes and everything went fine for quite a long time. But after a while i recognised, that my web-app was getting really really slow in FF, while Chrome and IE were able to handle it without any problems. I thought the problem might be in connection with flexboxes, so I googled and found this article and tested the example above. But having a lot of flexboxes next to each other didn’t seem to hurt any browser i tested.
Then I slightly changed the example to recursivly add flexboxes into each other:
JSFiddle
And theres the problem: Chrome doesn’t have any problems with 40 nested flexboxes or more. But Firefox already freezes for a while if you let him draw 10 nested boxes ..
Anyone got a nice solution for this problem? :/
Same here…
It’s impossible to work with nested flexbox in firefox:
http://codepen.io/anon/pen/dhzJE (limited to 20 items, or you will need to kill the firefox process)