A user account is required in order to edit this wiki, but we've had to disable public user registrations due to spam.
To request an account, ask an autoconfirmed user on Chat (such as one of these permanent autoconfirmed members).
Talk:Dynamic Script Execution Order: Difference between revisions
(→Text/cache solution: new section) |
|||
Line 73: | Line 73: | ||
== Text/cache solution == | == Text/cache solution == | ||
It seems to me that having a real text/cache script type, or a similar element that fires a load/error event and provides a .text property gets you where you need to be. You could setAttribute("type", "text/JavaScript") or use the text to create a new script element. Or a new style element, or whatever. That puts you in control of when script or CSS is interpreted. With async as the default, you don't need a new ordered attribute as that's easily managed in script. |
Revision as of 20:38, 4 November 2010
Please discuss the proposal here. All informal feedback is welcomed, and when it's appropriate, please add content to the main page.
What about CommonJS / RequireJS?
I'm not sure we need to complicate the HTML or browser engines in order to satisfy the advanced use cases. To me it seems that the JavaScript langauge itself could abstract the requirements and let the browser vendors implement whatever solution they see fit. Specifically, if JavaScript provided the define() and require() calls proposed in the CommonJS "specifications" (and implemented by RequireJS, dojo (trunk), and others *Yabble?), then browsers could just load and evaluate scripts as fast as possible without regard to script execution order.
This would solve all of the problems except for the current inability to use loaders like LABjs in FF4 or webkit. To solve that problem, we should consider keeping the existing functionality or triggering the deprecated functionality when needed.
--Unscriptable 01:29, 2 November 2010 (UTC)
Response
This is a valid point except that it assumes that all code that needs to be loaded is "modular"... in fact, most code on the internet that needs to be loaded is NOT modular, and instead requires particular ordering when being loaded... for instance, "jquery" and "jquery-ui" -- jQuery must be run before jQuery-UI is loaded and run.
The spirit of this proposal is to add the facility to native browser (rendering engine, specifically) behavior, such that any and all existing content is able to be loaded (even with dependencies and order) without modification.
Dependent code should be modular
I completely agree, 99% of JavaScript in use today is NOT modular, but that's arguably because there was no built-in support to make it modular (IMHO, YMMV, RTFM, BBQ, ROFL). But that doesn't mean there aren't dependencies that span script files / script nodes. I don't know how many sites would be broken (or if there is any way to determine how many sites would be broken) if/when the latest browsers started loading and evaluating script-injected scripts out of order. It's not just LABjs-based sites. I'll bet many dojo and YUI sites will break, too (although I don't know this for a fact because I don't know exactly how their dynamic script loaders work).
In any case, breaking existing sites is a BAD IDEA. :) There should be some way to allow LABjs and other dynamic script loaders to continue to work.
The part I don't agree with in the proposals is that it should be the job of HTML and/or the browser engine to manage dependencies. Specifically, I am talking about the scriptGroup element and the "waitFor" attribute. The "async" attribute may be the right level: it appropriates only general heuristics to the browser: load these scripts whenever you like, but load these other scripts in this order.
Detailed dependency management belongs in the modules, though. This is how it's done in most environments / languages: import statements, include statements, etc. It's no different in JavaScript, if a developer wants to take advantage of some code in another module, she/he should import it into their current module. This should be the model moving forward. It's not hard, it's not un-web-like, and it's already being done.
Existing code can be made to work modularly, too:
1. Identify modules and wrap them with a define() method. 2. Identify dependencies using either the Asynchronous Module Definition format or the CommonJS synchronous format
async format:
define(['dependency1', 'dependency2'], function (dependency1, dependency2) {
/* this is the factory function, return the module inside here */
return { /* some object, but could also be a constructor or a function */ };
});
sync format:
define(function (require, exports, module) {
/* this is the factory function, require dependencies and return the module inside here */
var dependency1 = require('dependency1');
var dependency2 = require('dependency2');
return { /* some object, but could also be a constructor or a function */ };
});
In the async case, the browser may employ whatever method it sees fit (e.g. parallel) to download the dependencies since the code inside the factory function won't execute until all of the dependencies are loaded and evaluated. In the sync case, the browser has no choice but to download and evaluate the dependency before continuing code execution. It's conceivable that the browser could find and asynchronously pre-fetch the inline require()'ed dependencies in the sync case. (RequireJS doesn't quite do this. Instead I believe it finds the inline require() calls and converts the module to an async module.)
So, in short: don't break LABjs (or any other script loaders), but don't extend the spec to manage dependency management from HTML.
--Unscriptable 01:29, 2 November 2010 (UTC)
Response #2
The cat's already out of the bag... we've got a dozen+ years worth, hundreds of millions of javascript files out there, which are NOT modular, and will not be modified to be modular.
If we're talking about either trying to change all the JS on the web to be modular, or trying to extend the HTML markup spec to include a better facility for accomodating the existing script content, I think the former is idealistic and "correct" but the latter is realistic and "right".
A modular loading system will only work for modular code, but a general loading mechanism in HTML (like the <script> tag) can load both modular and non-modular code, which is why that more general mechanism is what's in HTML right now and not some more specialized loading API that only loads a small percentage of JavaScript code out there.
The <script> tag has worked fine forever, and there's been no real big push to do away with it in favor of having all loading handled by JavaScript -- in fact, that would be impossible because if you had no way to load JS onto the page with a <script> tag, then no JavaScript could run on a page to load more code. So I don't agree that we should stop adding functionality to the HTML loading mechanism and only focus on JavaScript.
If we agree that the <script> tag itself is not only required but normative, then I'm not sure why decorating the <script> tag with additional behavior to help it be more powerful is a bad pattern. We've addded "defer" and "async" already. I'm not sure I understand why adding a wrapper tag called "scriptGroup" would be that much different than attributes on the <script> tag?
I also don't think that "scriptGroup" constitutes "dependency management". "scriptGroup" is a semantic way for a web author to express that they want to group a set of scripts together ONLY so far as execution order behavior is concerned. It implies nothing more to it (that "dependency management" would imply) than that.
For instance, consider this: if JavaScript had been built with non-global context and statement level context and sandboxing and such things, we'd have a much more secure JavaScript right now. But just because JavaScript may someday be taught some new tricks in terms of security, that doesn't mean that "now" HTML shouldn't try to help solve the problem. If for instance the <frag> tag can be used to create a sandboxed environment for third-party JavaScript code to run in, this is a much easier way to address the security problem than to suggest we have to wait for ES-Harmony to add extra syntax to the language to accomplish the same thing.
Getify 02:13, 2 November 2010 (UTC)
Text/cache solution
It seems to me that having a real text/cache script type, or a similar element that fires a load/error event and provides a .text property gets you where you need to be. You could setAttribute("type", "text/JavaScript") or use the text to create a new script element. Or a new style element, or whatever. That puts you in control of when script or CSS is interpreted. With async as the default, you don't need a new ordered attribute as that's easily managed in script.