Disabling page.js generation for partial templates (e.g. Angular)

26 views
Skip to first unread message

j...@joescii.com

unread,
Mar 19, 2018, 11:46:58 AM3/19/18
to Lift
While working for one of my clients, we discovered that Lift 3.x is placing a page.js file on partial templates loaded into the page. We discovered the problem because occasionally we found our app in a state where every angular template load fails to find its corresponding page.js. For the most part, everything we've observed is harmless but it's less than ideal. We're fetching unneeded assets, and I have my concerns that the code we place in page.js never expects other page.js files to get run in the same page load.

I added the following transform in out Boot.scala to prevent our partial HTML templates from having the page.js file:
// Lift 3.x slaps a <script> tag referencing a page.js on all HTML responses, including our angular templates
// This is a work around to avoid having the client pull an unneeded js file and avoid possible 404's.
LiftRules.responseTransformers.append( res => {
import net.liftweb.util.Helpers._

(S.request.map(_.uri), res) match {
case (Full(uri), html: XhtmlResponse) if uri.startsWith("/weave/templates/") =>
val stripped = ("script" #> "").apply(html.out).headOption.getOrElse(html.out)
html.copy(out = stripped)
case _ =>
res
}
})

This workaround isn't ideal for several reasons. 

Firstly, it assumes that there are ZERO valid script tags in the directory. This was safe in our case fortunately because the directory ONLY contains partial HTML and no script tags of our own. Just beware of this if you want to apply this code to your own project. 

Secondly, Lift is doing all of the work and bookkeeping to add this script file just for us to do more work and throw it away.

I feel like Lift shouldn't assume that an HTML uri needs page.js slapped in there, although that's a good default behavior. I'd like to be able to control this behavior with LiftRules. Any objections or concerns about doing so? And what would be the best way to expose this feature? My initial thought is to create a setting with type Req => Boolean that answers the question "Should this request's HTML response have a page.js added?" and by default always answers "true" to achieve our current behavior.

Looking forward to the feedback!

Thanks,
Joe


Antonio Salazar Cardozo

unread,
Mar 19, 2018, 2:25:34 PM3/19/18
to Lift
The page JS should only appear in cases where JS is appended or events are extracted,
I believe? This was by design, otherwise event extraction doesn't work (the JS to bind
events doesn't fire).

Is there any content in page.js?
Thanks,
Antonio

j...@joescii.com

unread,
Mar 21, 2018, 1:51:10 PM3/21/18
to Lift
Indeed there is content in page.js every time. It has the lift settings and so forth. Below is an example:

var lift_settings = {};
window.lift.extend(lift_settings,window.liftJQuery);
window.lift.extend(lift_settings,{"liftPath": "/lift", "ajaxRetryCount": 3, "ajaxPostTimeout": 15000, "gcPollingInterval": 75000, "gcFailureRetryTimeout": 15000, "cometGetTimeout": 140000, "cometFailureRetryTimeout": 10000, "cometServer": null, "logError": function(msg) {lift.defaultLogError(msg);}, "ajaxOnFailure": function() {alert("The server cannot be contacted at this time");}, "ajaxOnStart": function() {jQuery('#'+"ajax-loader").show();}, "ajaxOnEnd": function() {jQuery('#'+"ajax-loader").hide();}});
window.lift.init(lift_settings);

When I first was investigating I was more concerned because I know that we put GC code in there on full page loads. But it seems these extra page.js files just have the settings fortunately. At this point I suspect no harm is being done to functionality, just unnecessary work.

Joe

Antonio Salazar Cardozo

unread,
Mar 22, 2018, 9:53:54 PM3/22/18
to Lift
Ah. So the thing to do here might be to tweak the `LiftRules.javaScriptSettings` to return
`Empty` on requests that start with `/weave/templates`. I think that will make the JS blank
for the “page” and therefore eliminate the page.js.

Need to get it into my brain that JS settings are emitted even when no other JS is…
Thanks,
Antonio
Reply all
Reply to author
Forward
0 new messages