Re: Out of order JS file execution in WebKit

Werner Thie <[email protected]> Mon, 12 Jul 2010 11:12:35 +0200
Newsgroups gmane.comp.python.quotient.dev
Organization THIEngineering AG
Message-ID <[email protected]>
This is a multi-part message in MIME format.
--------------030401010102020803000109
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Hi

Just to sum up the state of the affairs:

I modified the nevow/doc/howto/chattutorial/part00/listings/echothing 
such that on pressing the button an additional widget is dynamically 
injected into the form which is dependent on a base class which was up 
to the button event not touched. The code is unreliable as described on 
the Webkit browsers, the loading and eval'ing of the widgets code 
sometimes happens before the loading of the base class, although this 
problem happening might not be limited to the Webkit.

My first attack was to modify
Nevow.Athena.Widget._addChildWidgetFromComponents
as proposed by Tristan such that, given the list of JS modules to be 
loaded is in the correct dependency order, the loading will happen 
sequentially in exactly this order.

The patch for this particular 'serial type of loading' is attached to 
this eMail. The code is a surprisingly ugly hack but serves the purpose.

Anybody interested and willing to try this out and report back?

After having measured impact of serial JS loading to be negligible in my 
setups (a few K's of JS code) I'm content to live with that hack for the 
next few months until I see some more time to attack the problem with 
the other herein proposed scheme.

Thxs, Werner

On 15.04.2010 10:45, Tristan Seligmann wrote:
> On Thu, Apr 15, 2010 at 8:10 AM, Werner Thie<[email protected]>  wrote:
>> Tristan, can you give me a pointer for attacking this problem, I like
>
> Hmm, let's see. In order to serialise a widget for dynamic
> instantiation, LIveElement._structured() is called. This, in turn,
> flattens the element to get the markup; it also uses context.call to
> set up lists, including 'requiredModules', which the liveElement
> renderer mutates during the course of rendering. This allows it to
> collect a list of all modules required by the widget and any of its
> children. The list of dependencies is constructed by calling
> allDependencies() on the relevant module, and then filtering it with
> LivePage._shouldInclude(). _shouldInclude keeps a list of all modules
> it has ever been called with, and returns False if one of those
> modules is passed in, otherwise True (and adds it to the list); thus,
> each module will only be imported once.
>
> For static instantiation, this is exactly what we want, as modules
> will be loaded in the correct order, and only once; I'm not sure what
> the best way to fix this for dynamic instantiation is. One way to do
> it would be to force the client-side code to load modules serially;
> this would ensure that they're loaded in the correct order, but this
> may affect network performance adversely. I think a better solution
> would actually be something similar to what was already discussed in
> this thread; although, most of the pieces are already in place.
>
> Scripts are loaded in
> Nevow.Athena.Widget._addChildWidgetFromComponents, using
> Divmod.Runtime.theRuntime.loadScript(). The implementation differs
> between runtimes, but in all cases, it returns a Deferred that only
> fires once the module has actually been loaded. This is used to delay
> the actual instantiation of the widget until the dependent modules
> have been loaded. My suggestion would involve adding a loadScript()
> method on the page widget: the first time it's called, it would fire
> off the real loadScript() call; if called while the script is still
> being loaded, it would return another deferred that fires when the
> script has loaded; if called after the script has loaded, it would
> return a deferred that fires immediately. The server-side code would
> be changed to not filter the dependencies list through _shouldInclude
> in the dynamic instantiation case (by adding a flag parameter to the
> involved methods, I guess?), so that loadScript() would be called for
> all of the dependencies, not just the ones that have never been
> loaded. The page setup code would probably need to pass a list of
> statically loaded modules to the page widget, so that it knows that
> they're already loaded.
>
> Hope that helps; I wrote this based on a cursory reexamination of the
> code in question, along with vague recollections from the last time I
> looked at the code, so I may have some of the details wrong, but
> hopefully this is enough to point you in the right direction.

--------------030401010102020803000109
Content-Type: text/plain;
 name="__init__.js.diff"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
 filename="__init__.js.diff"

SW5kZXg6IF9faW5pdF9fLmpzDQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09DQotLS0gX19pbml0X18uanMJKHJl
dmlzaW9uIDE3OTkzKQ0KKysrIF9faW5pdF9fLmpzCSh3b3JraW5nIGNvcHkpDQpAQCAtNTU2
LDcgKzU1NiwxMCBAQA0KICAgICB9LAogCiAgICAgZnVuY3Rpb24gZmx1c2hNZXNzYWdlcyhz
ZWxmKSB7Ci0gICAgICAgIGlmICghc2VsZi5ydW5uaW5nIHx8IHNlbGYuX3BhdXNlZCkgewor
ICAgICAgZnVuY3Rpb24gZGVsYXllZEZsdXNoTWVzc2FnZXMoKSB7CisgICAgICAgIHNlbGYu
Zmx1c2hNZXNzYWdlcygpOworICAgICAgfQorICAgICAgaWYgKCFzZWxmLnJ1bm5pbmcgfHwg
c2VsZi5fcGF1c2VkKSB7CiAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgIH0KIApAQCAt
NTkxLDkgKzU5NCw5IEBADQogICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAg
ICAgICAgICB9CiAgICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoc2VsZi5mYWlsdXJl
Q291bnQgPCAzKSB7CisgICAgICAgICAgICBpZiAoc2VsZi5mYWlsdXJlQ291bnQgPCA3KSB7
CiAgICAgICAgICAgICAgICAgaWYgKCF0aGVSZXF1ZXN0LmFib3J0ZWQpIHsKLSAgICAgICAg
ICAgICAgICAgICAgc2VsZi5mbHVzaE1lc3NhZ2VzKCk7CisgICAgICAgICAgICAgICAgICBE
aXZtb2QuUnVudGltZS5EZWxheWVkQ2FsbChzZWxmLmZhaWx1cmVDb3VudCAqIDEwMDAsIGRl
bGF5ZWRGbHVzaE1lc3NhZ2VzKTsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICB9
IGVsc2UgewogICAgICAgICAgICAgICAgIHNlbGYuc3RvcCgpOwpAQCAtOTQ2LDcgKzk0OSw3
IEBADQogICAgICAgICAgICAgRGl2bW9kLlJ1bnRpbWUudGhlUnVudGltZS5sb2FkU3R5bGVz
aGVldChyZXF1aXJlZENTU01vZHVsZXNbaV0pOwogICAgICAgICB9CiAKLSAgICAgICAgaW1w
b3J0RGVmZXJyZWRzID0gW107CisgICAgICAgIHZhciBtb2R1bGVzID0gW107CiAgICAgICAg
IGZvciAobW9kdWxlSW5kZXggPSAwOyBtb2R1bGVJbmRleCA8IHJlcXVpcmVkTW9kdWxlcy5s
ZW5ndGg7ICsrbW9kdWxlSW5kZXgpIHsKICAgICAgICAgICAgIG1vZHVsZU5hbWUgPSByZXF1
aXJlZE1vZHVsZXNbbW9kdWxlSW5kZXhdWzBdOwogICAgICAgICAgICAgbW9kdWxlVVJMID0g
cmVxdWlyZWRNb2R1bGVzW21vZHVsZUluZGV4XVsxXTsKQEAgLTk2MiwxNSArOTY1LDI4IEBA
DQogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICBtb2R1bGVPYmogPSBtb2R1
bGVPYmpbcGFydE5hbWVdOwogICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpbXBvcnRE
ZWZlcnJlZHMucHVzaCgKLSAgICAgICAgICAgICAgICBEaXZtb2QuUnVudGltZS50aGVSdW50
aW1lLmxvYWRTY3JpcHQoCi0gICAgICAgICAgICAgICAgICAgIG1vZHVsZVVSTCkpOworICAg
ICAgICAgICAgbW9kdWxlcy5wdXNoKG1vZHVsZVVSTCk7CiAgICAgICAgIH0KLSAgICAgICAg
YWxsSW1wb3J0c0RvbmUgPSBEaXZtb2QuRGVmZXIuRGVmZXJyZWRMaXN0KAotICAgICAgICAg
ICAgaW1wb3J0RGVmZXJyZWRzLAotICAgICAgICAgICAgLyogZmlyZU9uT25lQ2FsbGJhY2s9
ICovZmFsc2UsCi0gICAgICAgICAgICAvKiBmaXJlT25PbmVFcnJiYWNrPSAqL3RydWUpOwor
ICAgICAgICBhbGxJbXBvcnRzRG9uZSA9IERpdm1vZC5EZWZlci5EZWZlcnJlZCgpOyAgICAg
IAorICAgICAgICBmdW5jdGlvbiBsb2FkTW9kdWxlc1NlcSgpIHsKKyAgICAgICAgICBpZiAo
bW9kdWxlcy5sZW5ndGggPiAwKSB7CisgICAgICAgICAgICBEaXZtb2QuZGVidWcoIi0tLSIs
ICdtb2R1bGVzOiAnICsgbW9kdWxlcyk7CisgICAgICAgICAgICB2YXIgZCA9IERpdm1vZC5S
dW50aW1lLnRoZVJ1bnRpbWUubG9hZFNjcmlwdChtb2R1bGVzWzBdKTsKKyAgICAgICAgICAg
IGQuYWRkQ2FsbGJhY2soZnVuY3Rpb24oKSB7CisgICAgICAgICAgICAgIGlmIChtb2R1bGVz
Lmxlbmd0aCA+IDApIHsKKyAgICAgICAgICAgICAgICBsb2FkTW9kdWxlc1NlcSgpOworICAg
ICAgICAgICAgICAgIG1vZHVsZXMuc2hpZnQoKTsgICAgICAgICAgLy9zaG9ydGVucyB0aGUg
bW9kdWxlcyBhcnJheQorICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIGVsc2Ugewor
ICAgICAgICAgICAgICAgIGFsbEltcG9ydHNEb25lLmNhbGxiYWNrKHRydWUpOworICAgICAg
ICAgICAgICB9ICAKKyAgICAgICAgICAgIH0pOworICAgICAgICAgIH0KKyAgICAgICAgICBl
bHNlIHsKKyAgICAgICAgICAgIGFsbEltcG9ydHNEb25lLmNhbGxiYWNrKHRydWUpOworICAg
ICAgICAgIH0gIAorICAgICAgICB9CisgICAgICAgIGxvYWRNb2R1bGVzU2VxKCk7CiAgICAg
ICAgIGFsbEltcG9ydHNEb25lLmFkZENhbGxiYWNrKAogICAgICAgICAgICAgZnVuY3Rpb24o
aWdub3JlZCkgewogICAgICAgICAgICAgICAgIHRvcE5vZGUgPSBEaXZtb2QuUnVudGltZS50
aGVSdW50aW1lLmZpcnN0Tm9kZUJ5QXR0cmlidXRlKApAQCAtMTAxOCw3ICsxMDM0LDYgQEAN
CiAKICAgICAgICAgICAgICAgICByZXR1cm4gdG9wV2lkZ2V0OwogICAgICAgICAgICAgfSk7
Ci0KICAgICAgICAgcmV0dXJuIGFsbEltcG9ydHNEb25lOwogICAgIH0sCiAK
--------------030401010102020803000109
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline