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