Scrolling lags on iOS when touch starts on an a-element
When mapbox CSS file is loaded on the page, it induces a noticeable delay on the start of scrolling on iPad/iPhone when the touch starts on an <a> element and DOM is quite large.
We recently shipped a new release of our website with Mapbox map added and had to quickly revert back to an old version after finding out scrolling was hindered when started on non-mapbox elements. We then debugged the code, removed entire Mapbox JS and still the problem was there. Only after removing the CSS link was the scrolling performance back to normal – including the JS without CSS did no harm.
After furious investigation and frustration, we managed to pin it down to one CSS3 selector in Mapbox CSS file which apparently is dead slow and has a super bad performance. It somehow causes Safari to spend a nice amount of time (in our debugging we found it to be from 300ms to 600ms) in recalculating styles before the scrolling starts.
Our fix was this:
diff --git a/vendor/assets/stylesheets/mapbox.css b/vendor/assets/stylesheets/mapbox.css
index 16a79f7..57f5773 100644
--- a/vendor/assets/stylesheets/mapbox.css
+++ b/vendor/assets/stylesheets/mapbox.css
@@ -225,9 +225,6 @@
border-bottom:none;
border-radius:0 0 3px 3px;
}
- .leaflet-bar a:only-of-type {
- border-radius:3px;
- }
.leaflet-bar .leaflet-disabled {
cursor:default;
This issue could probably be reproduced by creating a semi-large DOM with big <a> elements. In our web-app, the DOM has 40 elements with this mark-up, filling 3/4 of the width of the page.
<a href="/tilat/ravintola-sunnin-kokouskabinetit" class="m-previewbox">
<div class="m-previewbox-contents">
<div class="m-previewbox-image" style="background-image: url('/photos/000/000/467/51384ba901ff76b4949ec097f4ce180ac8c798a6.jpg?1379928241')"></div>
<div class="m-previewbox-info">
<h2>
Ravintola Sunnin kokouskabinetit
</h2>
<span class="hide-for-small">
<i class="icon-map-marker" title="Osoite tilalle Ravintola Sunnin kokouskabinetit"></i>
Aleksanterinkatu 26,2 krs, 00170 Helsinki
</span>
<span class="show-for-small">
<i class="icon-map-marker"></i>
Helsinki
</span>
<p class="hide-for-small">
Kokouskabinetti keskellä Helsinkiä, Senaatintorin laidalla.
</p>
<div class="m-venue-info">
<div class="m-venue-info-additional">
<div class="m-custom-rating">
<i class="icon-star"></i><i class="icon-star"></i><i class="icon-star"></i><i class="icon-star-half-empty"></i><i class="icon-star-empty"></i>
</div>
<div class="m-rating-total">
<i class="icon-comment-alt"></i>
16
</div>
</div>
<div class="m-venue-info-additional is-last">
<i class="icon-male" title="Kapasiteetti"></i>
<strong>30</strong>
</div>
<div class="m-venue-info-additional show-for-small">
</div>
</div>
</div>
<div class="m-previewbox-right">
<i class="icon-chevron-right m-previewbox-right-arrow show-for-small"></i>
<div class="hide-for-small">
<div class="button small success">Katso tila →</div>
<div class="m-venue-info-price-primary">
<h3>Päivävuokra</h3>
<h4>-</h4>
</div>
<div class="m-venue-info-price-secondary">
<h3>Tuntivuokra</h3>
<h4>-</h4>
</div>
</div>
</div>
</div>
</a>
In our case, the map is positioned above these elements.
Wow, thanks for the report. Who knew one selector would cause such a difference.
Thanks for the report! this style is only required when a control element is in a hover state as a background-color is applied. I wonder if this would make a difference:
.leaflet-bar a:hover:only-of-type {
border-radius:3px;
}
@VesQ could you confirm?
Mobile devices don't have a hover state usually so it should fix it.
I'll test this tomorrow on a proper device. It does seem reasonable to expect the proposed change to help, but knowing what the issue was in the first place, I would not be hasty to close this issue... who knows what Safari wants or doesn't want to do.
Sorry for this taking so long. We actually changed our design quite rapidly in the end and I didn't manage to get the time to try this fix.
I still don't see why the fix would work. As knowing what CSS selectors are performant, just adding another qualifier to the a-element hardly does anything good to the performance. Mainly just makes it even more worse.