New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading files and possible problem with headers #95

Closed
niksy opened this Issue Feb 20, 2012 · 28 comments

Comments

Projects
None yet
@niksy

niksy commented Feb 20, 2012

I'm using yepnope through Modernizr and I have some problems with loading assets on Android (2.3) device.

Everytime when I load page through address bar or normal refresh button in browser, files load as they should with set conditions (yep/nope, callbacks and complete).

But when I load page through normal link on page (clicking on it), nothing connected to Modernizr/yepnope loads and functions which rely on those assets fail to activate - but everything works fine when I load it through address bar and refresh button as I already mentioned.

But then I've tried to force load those files with versioning (e.g. misc.js?v=54) and everything works as it should, but then I have situation where those files load everytime for every page load, without caching, which is not something anyone would want to see :)

Is this something related to headers? Currently my .htaccess file has these headers:

Options +FollowSymLinks

AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript text/javascript

<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/html "access plus 1 seconds"
ExpiresByType image/gif "access plus 20 years"
ExpiresByType image/jpeg "access plus 20 years"
ExpiresByType image/png "access plus 20 years"
ExpiresByType text/css "access plus 20 years"
ExpiresByType text/javascript "access plus 20 years"
ExpiresByType application/javascript "access plus 20 years"
ExpiresByType application/x-javascript "access plus 20 years"
</IfModule>
@niksy

This comment has been minimized.

niksy commented Feb 21, 2012

Just checked on iOS 5 and it works as it should regardless of refreshing, loading through address bar or clicking on a link.

Here is a test case:
http://jsbin.com/ynload/
http://jsbin.com/ynload1/
http://jsbin.com/ynload2/

Android stock browser (haven't checked others) is the one with problems, all other work as expected.

@SlexAxton

This comment has been minimized.

Owner

SlexAxton commented Apr 23, 2012

@ralphholzmann - I missed this issue when it came through. Do we have a successful loading mechanism for older mobile webkit browsers?

@ralphholzmann

This comment has been minimized.

Collaborator

ralphholzmann commented Apr 24, 2012

We do. Images work everywhere webkit. This is a weird edge case. I'm installing the 2.3 emulator now to give this a shot.

@lpancescu

This comment has been minimized.

lpancescu commented Apr 25, 2012

@ralphholzmann - I see the same symptoms not only with Android 2.3, but also with Mobile Safari on iOS 4.2.1 and with Epiphany and Chromium on Debian Squeeze (both use older versions of WebKit). I'm using Modernizr.load to conditionally load jQuery, a hyphenation plugin for jQuery and a language pattern, if the browser supports soft hyphens but not CSS hyphens (like iOS 4.2.1 or Android's browser). It only works if I clear the cache before loading a page, on all browsers above.

I see a difference when loading the page in Chromium's Timeline, with and without purged cache: when the javascript files are already in cache, there's a "Send request" for each, they are loaded in 0ms, but there is no "Evaluate script" stage after that for any of them, as it happens with an empty cache. The Modernizr.load callbacks are also not executed (I set a breakpoint in my callback, which only gets hit when the cache is empty). If I try $('p') in Chromium's Web Console, it returns an array of objects with purged cache, and null if jQuery was already in the cache - I guess Timeline tells the truth...

EDIT: Tested on iPod Touch 2G running iOS 4.2.1, VirtualBox VM running Android-x86 2.3RC1 and Debian Squeeze amd64 on my EeePC. I also tested with iPhone 4 running iOS 5.1, but that works properly.

@niksy

This comment has been minimized.

niksy commented Apr 25, 2012

@ralphholzmann have you tested this on real device or just in simulator? Mine test cases were done on real device (HTC Desire), if that helps somehow…

@ralphholzmann

This comment has been minimized.

Collaborator

ralphholzmann commented Apr 25, 2012

I tested on a simulator and confirm the issue. It sounds like in certain cases the tag we preload scripts with isn't firing its onload callback. We may need to look at an alternative loading method for mobile and older webkits. We used to have a code fork for older webkits, but we removed it to save space and didn't see any compatibility issues. I guess its time to revisit that assumption.

@niksy

This comment has been minimized.

niksy commented Apr 27, 2012

Yes, definitely, there is a pretty big number of Android devices with those OS versions than newer ones and it makes conditional loading of resources on larger mobile browser landscape pretty inconvenient if we can't use this technique.

@mikeycgto

This comment has been minimized.

Contributor

mikeycgto commented May 14, 2012

+1 to this.

We've been seeing the behavior initially describe in this ticket on older Android devices (and on a Kindle Fire) for sometime now. Glad I'm not alone in this.. ;D

Where can I find the older webkit code mentioned above?

@mikeycgto

This comment has been minimized.

Contributor

mikeycgto commented Jun 26, 2012

Look a little into this issue and many tests fail on both my Android phone and Kindle Fire (which is good). Haven't tried to run the test page on an emulator though, has anyone tried that?

I'm interested in fixing this bug (cause its a big block for mobile support on our app) however I am unsure of where to start. If someone could point me in the right direction and describe the polling technique in general and I could try and implement it and get this bug squashed once and for all!

@SlexAxton

This comment has been minimized.

Owner

SlexAxton commented Jun 27, 2012

If you look at some of the branching we do with the browser inferences at the top of the file, we decide what type of element we want to use to preload with. There's a good chance that the method we used in the 1.0.x series of yepnope releases actually works on these browsers, since it was a little bigger and more specific. That may be a good place to start. See if yepnope 1.0.x works on those devices.

@lpancescu

This comment has been minimized.

lpancescu commented Jun 29, 2012

I did some tests with two other loaders (as replacement for yepnope.js). $script.js loads the scripts reliably and executes them almost always in the correct order - about 1 time out of 10, some jQuery plugin ends up running before jQuery itself with the older WebKit in Android and Debian.

LAB.js always works reliably in my tests - every single time, with all tested browsers. Its only disadvantage is that it needs to be loaded separately, it cannot be embedded in HTML like $script.js or in Modernizr itself. Perhaps LAB.js can serve as a starting point for fixing this in yepnope.js?

@cmelion

This comment has been minimized.

cmelion commented Aug 21, 2012

+1 for this issue on Version - 1.5.4pre
It looks like most of the Android devices we test with are working, the notable exception is a Samsung 10" tablet with Android 3.2.

@cmelion

This comment has been minimized.

cmelion commented Aug 24, 2012

yepnope 1.0 works on older android, 1.5.4pre does not.

The behavior is quite strange, when multiple dependencies are specified, some but not all load.
I verified this by writing console.log messages in each of the dependent js files.
I also checked in Charles Proxy, the requests were processed with 200s.

Rolling back to 1.0 for now.

@cmelion

This comment has been minimized.

cmelion commented Aug 25, 2012

F.Y.I. Swapping the 1.5.x browser sniffs for 1.0.2 browser sniffs works on all platforms we tested (IOS, Android, IE8+, Firefox and desktop webkit)

@mikeycgto

This comment has been minimized.

Contributor

mikeycgto commented Oct 3, 2012

Been meaning to reply to this ticket. We added back in the test for isOldWebkit and added some logic to manually trigger the onload callback when the file is already cached.

Basically, whenever the file is cached and is loaded via an image tag on 'old webkit', the image callback will fail to trigger and the file will never load properly.

We've been using this change on our app for a while now and haven't had heard any issues with "false starts" (breakbase.com). It's a client-heavy app and when it would fail to load users would get stuck at our load screen.

Here's a link to the changes on my fork. Let me know what you guys think and I can send a pull req (I also need to pull down and merge from upstream :x)
mikeycgto@bcdc296

@seventy6

This comment has been minimized.

seventy6 commented Oct 6, 2012

mikeycgto did your solution work? We have the same issue with Android 2 getting the callback 50% of loads. Might have to ditch using YepNope on a current project - which will be a shame!

@cmelion

This comment has been minimized.

cmelion commented Oct 11, 2012

I pulled the patched version from the repository I am still getting
failures. I'm having better success inserting the browser sniffs from 1.x
versions.

On Sat, Oct 6, 2012 at 5:25 AM, Nick Forsberg notifications@github.comwrote:

mikeycgto did your solution work? We have the same issue with Android 2
getting the callback 50% of loads. Might have to ditch using YepNope on a
current project - which will be a shame!


Reply to this email directly or view it on GitHubhttps://github.com//issues/95#issuecomment-9196690.

@mikeycgto

This comment has been minimized.

Contributor

mikeycgto commented Oct 14, 2012

I'm now noticing that our app will fail to load sometimes during a refresh (scripts are cached). Going to mess around a bit more with isOldWebkit handling and see if I can get something going that works all the time ("clean" hits as well as refreshing).

@cmelion

This comment has been minimized.

cmelion commented Oct 14, 2012

Michael,
Can you test with appcache as well? With empty (first time), up to date
and after a cach update. We also se different behavior when loading from a
link or bookmark and reload/refresh.

-Charlie

On Sunday, October 14, 2012, Michael Coyne wrote:

I'm now noticing that our app will fail to load sometimes during a refresh
(scripts are cached). Going to mess around a bit more with isOldWebkithandling and see if I can get something going that works all the time
("clean" hits as well as refreshing).


Reply to this email directly or view it on GitHubhttps://github.com//issues/95#issuecomment-9421132.

@jfroom

This comment has been minimized.

jfroom commented Nov 21, 2012

+1 for this issue on Version - 1.5.4pre with Android emulators.

In case it helps, remote browser based Android emulators over here: http://www.manymo.com/

@nring

This comment has been minimized.

nring commented Nov 28, 2012

Using 1.5.4pre as a base, I used the injectCss function from 1.0.2 combined with the following browser sniffs:

isGecko               = ( "MozAppearance" in docElement.style ),
isGeckoLTE18          = isGecko && !! doc.createRange().compareNode,
insBeforeObj          = isGeckoLTE18 ? docElement : firstScript.parentNode,
isOpera               = window.opera && toString.call( window.opera ) == '[object Opera]',
isIE                  = !! doc.attachEvent && !isOpera,
isWebkit              = ( 'webkitAppearance' in docElement.style ),
isNewerWebkit         = isWebkit && 'async' in doc.createElement('script'),
strJsElem             = isGecko ? 'object' : ( isOpera || isNewerWebkit ) ? 'img' : 'script',
strCssElem            = isWebkit ? 'img' : strJsElem,

It's working for me so far in IE8+, Android 2.3+, iOS6, and modern browsers.

@niksy

This comment has been minimized.

niksy commented Dec 1, 2012

@nring do you have a fork of yepnope which we could use for now?

@cmelion

This comment has been minimized.

cmelion commented Jan 3, 2013

@SlexAxton @ralphholzmann Any chance we can get an official fix for this issue? We would prefer to use the latest release but the Android loading issues prevent this.

@DesignByOnyx

This comment has been minimized.

Contributor

DesignByOnyx commented Feb 20, 2013

I have fixed the issue with some inspiration from @mikeycgto's isOlderWebkit idea. The change is minimal and does not affect newer webkit browsers. I have submitted a pull request to get this change into the official yepnope library, however the impatient can find the fix here:

https://github.com/DesignByOnyx/yepnope.js/blob/master/yepnope.js

NOTE: I did not minify the code. That part is up to you!

SlexAxton added a commit that referenced this issue Feb 20, 2013

Merge pull request #155 from DesignByOnyx/master
Fixed issue #95 with older webkit browsers and cached assets not loading properly
@niccottrell

This comment has been minimized.

niccottrell commented Feb 25, 2013

Thanks for everyone for finding and patching this. Please excuse my ignorance, but can anyone point me to instructions on how to replace the yepnode packaged with Modernizr with this patched version?

@DesignByOnyx

This comment has been minimized.

Contributor

DesignByOnyx commented Feb 25, 2013

  1. At the top of your Modernizr file there should be a long URL to the modernizr download page. Paste the url in your browser.
  2. Uncheck the option for Modernizr.load (yepnope) and generate your new Modernizr code without yepnope.
  3. Download the yepnope.js file and paste it into your Modernizr.js file. I recommend you minimize it first.
  4. Add the following code to your Modernizr file at the very bottom:
Modernizr.load = yepnope;

Note: I haven't tested it, but it should work. If you are having issues with Modernizr.load() not working, try changing your code to call yepnope instead:

// Old code
Modernizr.load([{
  load: 'http:/­/ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js',
  complete: function () { }
}]);

// New Code
yepnope([{
  load: 'http:/­/ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js',
  complete: function () { }
}]);
@niccottrell

This comment has been minimized.

niccottrell commented Feb 25, 2013

@DesignByOnyx Thanks for the instructions! We ended up needing to add the final line as:

Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0));};

since otherwise the this["yepnode"] value was never populated.

@humanaut

This comment has been minimized.

humanaut commented Mar 2, 2013

I just wanted to confirm that the immediate above made it work for me too.

I also wanted to request confirmation of this fix working or not working completely for iOS 3? Clicking on a link in a page and going to another page still results in assets not being loaded from conditional tests, unless the page is refreshed.

If polyfills such as respond, matchmedia etc are hardcoded into HTML file, this problem does not happen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment