ouyang789987 / swfobject

Automatically exported from code.google.com/p/swfobject
0 stars 0 forks source link

Issue: Initialization is 353ms slower than it can be. Feature: Allow a way to delay initialization. #532

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Issue: 
The initialization of swfobject takes (353ms) longer than it can due to 
"callDomLoadFunctions" and "testPlayerVersion" which both manipulate the DOM. 

Take a look at the Before and After screenshots attached. These are taken with 
"SpeedTracer" on Chrome v10.0.642.2 on a 2.53GHz 4GB MacBook Pro (OSX v10.6.6). 
The screenshots display the profile of the following page:

----
<!doctype html>
<html>
<body>
    <div id="cnt"></div>
    <script type="text/javascript" src="swfobject.js"></script>
</body>
</html> 
----

In the "Before" image you can see the "Sluggishness (events)" spike, and 331ms 
attributed to DOM (DOMContentLoaded). [The average of 50 runs comes to 353ms.] 
This is a heavy price to pay for initialization. Especially since (a) swfobject 
isn't used on the test page, (b) swfobject is loaded after the dom is ready (at 
the end of the document [following best practices]). The After screenshot is 
taken after the patch below is applied. As you can see, there is no 
"Sluggishness" spike, and the 331ms initialization is gone.

Feature:
In essence, I'm proposing the "isInitDelayed" parameter to be added. When set 
to true, it skips the dom-loaded check, and lazily calls the main() 
initialization function when one of the public-api methods are called. This 
moves the cost of initialization (331ms) to the first call.

This will be very useful for folks that follow the best practices, and execute 
all JS right before the closing body tag. It will also be useful in cases when 
you don't know in advance whether you're going to need swfobject.js on a page 
or not. 

Diff:

----
28c28,29
<               isDomLoaded = false,

---
>               isInitDelayed = true,
>               isDomLoaded = isInitDelayed,
622c623
<       return {

---
>       var publicAPI = {
776a778,794
> 
>       if (isInitDelayed) {
>               var isInitialized = false;
>               for (var fn in publicAPI) {
>                       (function(oldFn) {
>                               publicAPI[fn] = function() {
>                                       if (!isInitialized) { 
>                                               main();
>                                               isInitialized = true;
>                                       }
>                                       oldFn.apply(this, arguments);
>                               };
>                       }(publicAPI[fn]));
>               }
>       }
> 
>   return publicAPI;
----

Original issue reported on code.google.com by GeorgeC...@gmail.com on 21 Jan 2011 at 10:56

Attachments:

GoogleCodeExporter commented 9 years ago
Running the basic test suite page (for actual Flash insertion) : 
http://www.bobbyvandersluis.com/swfobject/testsuite_2_2/test_dynamic.html

I am not seeing the same results as you. I get a 58ms DOMContentLoaded call. 
This is using a 2.4Ghz PC (Chrome 10.0.642 speedTracer)

As SWFObject 2.x is designed to be placed in the <head>, rather inline so that 
it can execute its calls at the correct time, can you please test with one of 
the test suite pages like the above and see what affect that has on your 
results?

Original comment by aran.rhee@gmail.com on 22 Jan 2011 at 2:35

Attachments:

GoogleCodeExporter commented 9 years ago
Page: http://www.bobbyvandersluis.com/swfobject/testsuite_2_2/test_dynamic.html
Results: 1088ms, 615ms, 625ms, 597ms, 615ms
(I've attached an archive of the screenshots.)

I understand that it was designed to be placed on the head. The feature is for 
people who've decided to follow the best practices 
(http://developer.yahoo.com/performance/rules.html#js_bottom). I believe they 
shouldn't have to be taxed for the dom-ready check (whether that is 300ms or 
50ms), since it's not needed for them.

Original comment by GeorgeC...@gmail.com on 22 Jan 2011 at 4:36

Attachments:

GoogleCodeExporter commented 9 years ago
Ran another set of tests on a different, more powerful machine (Quad core 
2.66Ghz, 4GB, Ubuntu 10.10, Chrome 10.0.642.2 dev). The results are a bit 
better:

test_dynamic.html (from bobbyvandersluis.com)
[in ms]
1. 120
2. 130
3. 126
4. 130
5. 127

[screenshots attached in the archive]

empty_page (from the HTML above) [swfobject isn't called, just included]
[in ms]
1. 111
2. 106
3. 111
4. 108
5. 106

So, once again, by including swfobject on the page, I'll get hit with a 
"Sluggishness (events)" spike, and on this (more powerful hardware) will add 
~100ms to the page load-time.

Original comment by GeorgeC...@gmail.com on 25 Jan 2011 at 9:44

Attachments:

GoogleCodeExporter commented 9 years ago
If you are planning to take the diff above, here's the revised, working version:

//---------------
  if (isInitDelayed) {
    var that = this,
        isInitialized = false;
    for (var fn in publicApi) {
      (function(oldFn) {
        if (typeof oldFn === "function") {
          publicApi[fn] = function() {
            if (!isInitialized) { 
              main();
              isInitialized = true;
            }
            return oldFn.apply(that, arguments);
          };
        }
      }(publicApi[fn]));
    }
  }
//---------------

Original comment by GeorgeC...@gmail.com on 31 Jan 2011 at 7:21

GoogleCodeExporter commented 9 years ago
This is certainly something worth considering, but I'm not sure if it will make 
the cut for the next update, as we're trying to focus on squashing bugs, not 
adding new features.

Thanks for the detailed information and code

Original comment by platelu...@gmail.com on 16 May 2011 at 5:05

GoogleCodeExporter commented 9 years ago
Placing on hold as our next release focuses on bug fixes.

Original comment by platelu...@gmail.com on 18 May 2011 at 8:25

GoogleCodeExporter commented 9 years ago
I technically have a separate problem, but that can be solved the same way that 
this problem can be solved: by simply exposing the "callDomLoadFunctions" 
method by including it on the global "swfobject" variable.

My problem is encountered when using RequireJS to include the swfobject 
library. If any JSONP calls are made and left hanging (for say 20 seconds), 
then the "onDomLoad" function (from "swfobject.js") prevents the execution of 
"callDomLoadFunctions" until those pending JSONP calls return a response or 
timeout.

My application relies on jQuery to first detect the dom ready event before 
executing code that involves swfobject. Because of this, I (just like 
GeorgeC...@gmail.com) need the ability to forego the swfobject library's delay 
in executing its functionality that waits for the dom ready event.

I've added the one line of code necessary to fix this in the attached file.

Additionally, I understand the desire to only introduce bug fixes in the next 
version, but this fix cannot potentially introduce new bugs, thus the stability 
for the next version is not in jeopardy if you so choose to include this.

Original comment by sakat...@gmail.com on 20 Oct 2014 at 7:09

Attachments: