恶心的 ios scroll问题!!Why the Scroll Event Change in iOS 8 is a Big Deal

原文地址:https://developer.telerik.com/featured/scroll-event-change-ios-8-big-deal/


If you’ve read any of the “What’s new in iOS 8 guides”, you may have noticed a change to how scroll events work. Although many may consider this a minor change, any developer that has tried to implement scrolling logic on the mobile web knows that this is actually fairly important. In this article I’ll explain what changed, what it means, and discuss one major caveat for Cordova developers.

A brief history lesson

When iOS Safari was first being developed, Apple’s engineers faced some difficult challenges displaying the existing web on a small screen. For better or worse, many of their internal engineering decisions became enshrined as “features” of the web — such as touch events, meta viewport tags, and so forth. One of these decisions was to pause all JavaScript execution whenever the user scrolled. To show this in action consider the following code that counts scroll events:

varcount=0;window.addEventListener("scroll",function(event){count++;});

In the two gifs below I display the event count in a fixed header and scroll a few times. Notice that in iOS 7 (left) the count does not increment until scrolling has completely stopped, whereas in iOS 8 (right) the count grows continuously.

Why exactly Apple pauses JavaScript execution during scrolls is unclear, but it’s likely for performance reasons, as the scroll event is often abused by web developers. In 2011, after a scroll event handler rendered Twitter unstable for many users, John Resig wrote an article about the scroll event problem, in which he included the following best practice:

It’s a very, very, bad idea to attach handlers to the window scroll event. Depending upon the browser the scroll event can fire a lot and putting code in the scroll callback will slow down any attempts to scroll the page (not a good idea). Any performance degradation in the scroll handler(s) as a result will only compound the performance of scrolling overall. Instead it’s much better to use some form of a timer to check every X milliseconds OR to attach a scroll event and only run your code after a delay (or even after a given number of executions – and then a delay).

So put yourselves in the shoes of an Apple engineer working on the original iPhone. A lot of sites are running performance-intensive code in scroll events and it’s making your browser seem choppy and slow. (And remember we’re talking about running on the original iPhone, not the hardware of today.) What do you do? Apparently you completely pause JavaScript execution during scroll, which is a sane decision given that environment.

Subsequent mobile browsers — notably IE Mobile and the Android browser — followed Apple’s example, possibly for similar reasons, or possibly for compatibility. Regardless, the lack of usable scroll events became a limitation of the entire mobile web for some time.

Why is this important?

As it turns out, there are many completely valid reasons you may want to perform actions during scrolling, for example parallax effects, or performance-friendly infinite scroll lists. And because of Apple’s decision to pause JavaScript during scrolling, these effects became impossible to do on the mobile web, at least without implementing scrolling with JavaScript, which a number of libraries actually do.

For example the popular iScroll library reimplements scrolling using CSS translations to make custom scroll events possible. Kendo UI Mobile includes a custom scroll widget and uses it to drive its list-based widgets. To be fair, these frameworks offer a lot more functionality than simple scroll events, and the custom JavaScript is usually done to get the best possible performance, but, the fact that you have to rebuild scrolling — a basic tenet of a web browser — to get usable scroll events on mobile is…insane.

And keep in mind that we’re not just talking about the scroll event. iOS < 8 pauses all JavaScript execution during scrolling. Therefore, any intervals you create with setInterval() are also paused. For example consider the following code that displays a new number every second:

varcount=0;setInterval(function(){count++;document.body.innerHTML+="<p>"+count+"</p>";},1000);

In the two gifs below I start scrolling after the count hits 3. Notice that in iOS 7 (left) the count stops during scrolling, whereas in iOS 8 (right) the count continues.

So, if you you use intervals in your apps for any reason, they are no longer arbitrarily paused in iOS 8 during scrolls.

Update (September 25th): Per a comment from Rick Byers my wording here is incorrect. iOS does not pause JavaScript execution—it pauses painting. So your app’s JavaScript will continue to run, but any changes to the DOM will not be painted until the scroll action completes.

How the web changed

Usually once a given behavior hits a major web browser we’re stuck with it until the end of time, but thankfully JavaScript execution during scrolling broke out of this mold. The Android team started firing continuous scroll events on the default browser shipped with Ice Cream Sandwich back in 2011. When Chrome started shipping on Android 4.0 it fired continuous scroll events as well. The next browser to change was IE Mobile, which followed suit on Windows Phone 8 back in 2012.

This left iOS as the only holdout, and with iOS 8 they have joined the rest of the mobile world, which finally gives us comprehensive coverage on the mobile web.

Not pausing JavaScript execution actually adds some compatibility for iOS that they didn’t have before. For example, the popular — and fun — scrollorama jQuery plugin started working correctly as of iOS 8. The gif below shows it in action.

One caveat for Cordova developers

Although Apple implemented this change in iOS Safari, as well as its new WKWebView control, it did not change the scroll behavior in its old UIWebView control. And because of a major bug in the replacement WKWebView control, the Cordova team cannot upgrade to WKWebView yet.

This means that at the moment Cordova apps running on iOS 8 continue to pause JavaScript execution, and will continue to until Cordova can upgrade. And this doesn’t just affect Cordova apps. Any iOS app that uses web views — including Facebook, Twitter, and Chrome for iOS — will get the old behavior until they upgrade their apps to WKWebView. So yes, that means you could get different behavior opening the same URL from different iOS apps depending on which API they use internally.

Update (September 25th): Commenter Ben Kennedy found that, for whatever crazy reason, the old scroll behavior also applies to home screen web apps. So to summarize, apps that run in Safari or in a WKWebView get the new scroll behavior, apps that run in a UIWebView or in a home screen web app do not.

Wrapping up

With iOS 8 it’s cool that you can actually execute code while the user scrolls, and that parallax effects are now possible without complex JavaScript hacks, but to me this is cool because the web actually changed. All mobile browsers used to pause JavaScript execution on scroll, but over time, as hardware advanced, they changed to allow JavaScript to run and fire scroll events as expected. This gives me hope that other features of the mobile web can change for the better as well.

Header image courtesy of William Hook

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,281评论 0 10
  • 写这一篇文章有点小意外,又是在情理之中,说是意外,是因为这是12月值月生雪晴战友发起的一个活动(所谓意外是未曾想到...
    Sencer阅读 687评论 0 4
  • 最近看的《明朝那些事》让我爱不释手,差不多接近尾声,感触颇多。 明朝开国大帝朱元璋一个小小的农民凭...
    MIU妙阅读 199评论 0 0
  • 凤九准备离开九重天,成玉听后决定办一场小宴,一来为了友情地久天长,二来为了送送凤九…… “哎!小殿下!这里!”成玉...
    愿岁月温柔回首阅读 3,482评论 4 23
  • 注定还是要折腾我一晚上,今夜无眠!
    水里的鱼儿阅读 117评论 0 0