Why was script tag execution removed in 0.51?

64 views
Skip to first unread message

Carter Bryden

unread,
Apr 16, 2018, 11:49:45 PM4/16/18
to unpoly
I'm sure there's a reason, but it seems like a major step backwards with no explanation given as to why.

Is there any way to get javascript from a fragment without one massive bundle for the whole app? Or do I have to include the js for every page up front, to be called by a compiler?

Henning Koch

unread,
Apr 25, 2018, 4:13:18 AM4/25/18
to unpoly
Am Dienstag, 17. April 2018 05:49:45 UTC+2 schrieb Carter Bryden:
I'm sure there's a reason, but it seems like a major step backwards with no explanation given as to why.
 
The TLDR is that parsing HTML on the client is hard.

In earlier versions we used a combination of jQuery's built-in HTML parser and regular expressions to build DOM elements from HTML returned by the server. Unfortunately that solution had many issues, which eventually could not be worked around anymore. Also we want to eventually get rid of the jQuery dependency.

Unpoly now uses the standard DOMParser interface to do the job. It's built into all browsers and much faster. One drawback is that the specs says that DOMParser must disable any <script> tag it encounters.

Is there any way to get javascript from a fragment without one massive bundle for the whole app? Or do I have to include the js for every page up front, to be called by a compiler?

I strongly recommend to call all your JavaScript from compilers. By strongly associating your JavaScript to the elements it works on, you can prevent memory leaks as fragments get swapped in and out of the DOM repeatedly.

When your JavaScript bundle is so massive that you cannot load it all up front, I would recommend to load large libraries from the compilers that need it. Compilers are also a good place to track whether the library has been loaded before. Including the same <script> tag more than once would probably lead to memory leaks or duplicate event handlers being registered by your lib.

In our work we mostly load all JavaScript up front, since our bundles are small enough. We recently had a case where we had a very large geo map library that we only wanted to load when it is used. The code we used for that looked something like this:

var hugeLibraryLoaded;


up
.compiler('.map', function($map) {
  hugeLibraryLoaded
= hugeLibraryLoaded || $.getScript('/huge-lib.js')
  hugeLibraryLoaded
.then(function() {
   
HugeLibrary.init($map)
 
})
})


 
Note how the library will only get loaded once even after compiling multiple <div class="map"> elements.

Best regards
Henning
Reply all
Reply to author
Forward
0 new messages