Bug Tracker

Opened 7 years ago

Closed 7 years ago

#13051 closed bug (wontfix)

Double script loading when present in an HTML page called in AJAX (IE < 10)

Reported by: vvo Owned by: vvo
Priority: low Milestone: None
Component: ajax Version: 1.8.3
Keywords: Cc:
Blocked by: Blocking:

Description

jQuery version: 1.8.3 browsers: IE < 10

I have set up a test page: http://jsbin.com/itovoz/1

It is a simple page including jQuery 1.8.3 that makes an AJAX call to another jsbin.com page. In this AJAX called page I included a <script> tag, this <script> will be loaded twice by all IE < 10.

What's expected: jquery.cookie.min.js is downloaded and executed once

What's happening: jquery.cookie.min.js is downloaded twice

I noticed I could not ALWAYS reproduce it, I have set up tests page in webpagetest to confirm the behavior, you'll see it's loaded twice:

IE7: http://www.webpagetest.org/result/121213_S7_5b2f160556db35d8b71345f84706eb37/1/details/

IE8: http://www.webpagetest.org/result/121213_GF_3df9e063700cc48adcbdf2e602aedfa6/1/details/

IE9: http://www.webpagetest.org/result/121213_7B_fba12e3b23d9ef5be765693a048a813c/1/details/

Could not reproduce on IE10.

As I said, sometimes everything is fine which is strange, example on IE8: http://www.webpagetest.org/result/121213_4Z_36b3072c31b505e77694f8b0a379d656/1/details/

This is a BIG performance regression and is affecting a lot of websites.

Very hard to notice but as a webperformance consultant I have seen it many times lately on multiple clients.

jQuery 1.4.4 is not affected. test page: http://jsbin.com/idasoh/1 test result: http://www.webpagetest.org/result/121213_FV_400864dd640776b3624b48a940b4978d/1/details/ (ran multiple times)

jQuery 1.6.2 is affected test page: http://jsbin.com/ivicav/1 test result: http://www.webpagetest.org/result/121213_NS_87f1194933b718ddbc4901c156638178/1/details/

Change History (9)

comment:1 Changed 7 years ago by vvo

Also, I could not find the documentation part that talk about the weird (but needed I guess) ?51651321 added to every <script> inserted in AJAX.

comment:2 Changed 7 years ago by dmethvin

Owner: set to vvo
Status: newpending

Sorry, I can't repro on your jsbin test case with IE9. http://i.imgur.com/EhJOv.png

Can you try with the current code and see if the problem is still there for you? http://code.jquery.com/jquery-git.js

In general, it's not a good idea to design pages that load scripts this way. Use $.getScript() or use a script loader rather than injecting HTML that happens to have script tags.

Last edited 7 years ago by dmethvin (previous) (diff)

comment:3 Changed 7 years ago by vvo

Status: pendingnew

Thanks for answering so fast.

First, using latest jquery as you provided does not solves it: http://www.webpagetest.org/result/121213_4J_60683a5c9b7256e109b54801a1b9390a/1/details/.

Second,

All I can say is that you should try harder (sorry really). As I said and prove (see WPT links for IE8 working well sometimes), this is not happening everytime so this must be based on a timer or something.

Here's another catch using HTTPWatch on IE9, http://i.imgur.com/e4IHa.png And using IE9 developper tools http://i.imm.io/OZpq.png

Yes its not a good idea but this is a regression since it should work as the docs says:

"html": Returns HTML as plain text; included script tags are evaluated when inserted in the DOM.

from http://api.jquery.com/jQuery.ajax/

Using jQuery.load this way is perfectly fine, I mean I never stumbled accross a "jQuery best practice" saying that we should not do that.

The docs of jQuery.ajax even says that if there's a <script> in it it will work fine since it will be evaluating it so why not doing it? (I'm trying to find justification why some people are doing it)

Yes this is a bad practice but a lot of people are doing this in production.

Last edited 7 years ago by vvo (previous) (diff)

comment:4 Changed 7 years ago by dmethvin

Status: newopen

All I can say is that you should try harder (sorry really).

I can see that it occurred from the webpagetest traces. I can mark this open but since I can't repro it the ticket will probably not get any action. If you can repro it consistently you could trace through jQuery and see where the problem is occurring.

comment:5 Changed 7 years ago by dmethvin

Component: unfiledajax
Priority: undecidedlow

comment:6 in reply to:  4 Changed 7 years ago by vvo

Replying to dmethvin:

All I can say is that you should try harder (sorry really).

I can see that it occurred from the webpagetest traces. I can mark this open but since I can't repro it the ticket will probably not get any action. If you can repro it consistently you could trace through jQuery and see where the problem is occurring.

I'll try to do that yes. It seems very strange that you could NEVER reproduce it even after many reloads (and cache busting) ?

comment:7 Changed 7 years ago by dmethvin

@vvo, still waiting on further analysis from you. I tried doing some debugging but the test case is using the compressed jquery and when I tried switching it to the uncompressed version on the jQuery CDN I was getting errors from jsbin.

As far as *why* it's requested twice, you can see the reason in the webpagetest.org traces:

http://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.2/jquery.cookie.min.js
http://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.2/jquery.cookie.min.js?_=1355420580018

Since the two requested URLs have different query strings the browser doesn't use the previously requested version.

comment:8 Changed 7 years ago by vvo

Hello, so I did a lot of digging.

First you'll find a jquery fork with an simple example to reproduce the bug here: https://github.com/vvo/jquery/tree/double_script_bug.

Here I copy paste my commit log: What I have found:

The double script bug is easily reproductible.

  • Clear your browser cache
  • Use any network observer
  • cd jquery, launch http-server . -p 80 (npm install http-server)
  • browse with IE9 and network observer to http://ip:80
  • see double script loading. One for script.js, other for script.js?timestamp

The javascript is not executed two times, only once.

But still it is loaded twice!

I used "blind man debugging" (putting returns and reloading the page untill no more script/only one script loads)

I tracked down the first javascript load (script.js) to be done by: https://github.com/vvo/jquery/blob/double_script_bug/src/manipulation.js#L284: fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );

This function will create a new dom fragment element using the ajax request response text. If you return; just before this call, of course your page will fail but you'll see that there's no more script loaded.

Then if you return just after, you'll see that there's the script.js loaded.

The second load of scirpt.js?timestamp is done by the append function: https://github.com/vvo/jquery/blob/double_script_bug/src/manipulation.js#L111 this.appendChild( elem );

So, creating a fragment with a <script src> in it will download the script once, then appending will download the script again (with a timestamp added, the timestamp is not a problem, this is the standard jQuery procedure of loading <scripts> in ajax calls)

What we should do I guess is replace() just before creating the fragment to pre-add the timestamp to the script.

As I just discovered jQuery core, I need some advice here.

http://dl.dropbox.com/u/3508235/7IE9%20test%20%5BRunning%5D%20-%20Oracle%20VM%20VirtualBox_006.png

Last edited 7 years ago by vvo (previous) (diff)

comment:9 Changed 7 years ago by markelog

Resolution: wontfix
Status: openclosed

In IE, script loading starts right after script element became a DOM-node, execution however, happens only after it's attached to the document – http://jsfiddle.net/YR5ar/, that's what happens in jQuery.buildFragment, fixing that, would require manipulation of the argument string, which seems as overkill for that case.

Note: See TracTickets for help on using tickets.