lift.js could cause cache issues

88 views
Skip to first unread message

Joe Barnes

unread,
Oct 28, 2015, 2:29:02 PM10/28/15
to Lift
While digging around in our javascript code, I noticed that we are serving /classpath/lift.js.  I'm concerned that this will not give us desirable caching behavior when there are changes to lift.js.  It needs either the lift version or a checksum added to the name.  

I plan to open a ticket to address this unless anyone objects to this being a problem.

Joe

Tim Nelson

unread,
Oct 29, 2015, 4:32:27 AM10/29/15
to Lift
I was thinking we should publish it to bower, so it can be included in your JS bundle as a WebJar.

Tim

Antonio Salazar Cardozo

unread,
Oct 30, 2015, 3:38:17 PM10/30/15
to Lift
I seem to recall lift.js gets some explicit no-cache headers (which is arguably
worse in many ways), fwiw. Could also attach an ETag to it instead of a querystring.
Thanks,
Antonio

Joe Barnes

unread,
Oct 31, 2015, 11:39:57 AM10/31/15
to Lift
I've not put work into using ETags up to this point, but from my understanding this would still leave Lift applications open to clients caching lift.js from an older version of Lift when the team upgrades.  Eventually the ETag will work out so that a fresh version is fetched, but I don't feel this is in anyway preferable to having the name of the js file include the version like lift-3.0-M6.js.  This is precisely how I make lift-ng work.  It's completely automated, so a PR could solve this for good.

As for the bower suggestion, that's a pretty cool idea.  However, what if we just published as a classic webjar?  I would guess that would fit more smoothly into our publishing pipeline, rather than introducing JS tooling.  What do y'all think?

Joe

Tim Nelson

unread,
Oct 31, 2015, 4:39:17 PM10/31/15
to Lift
My main thing is just to be able to use it as a webjar dependency. It doesn't matter to me how it gets there, I just thought bower was the easier way.

I know bower only allows one artifact per repo and I believe we have a couple of them, so classic sounds like the way to go.

Joe Barnes

unread,
Nov 1, 2015, 1:09:47 PM11/1/15
to lif...@googlegroups.com
That's quite a good point Tim.  When working through the details of angular.js, I learned what you mentioned here.  The classic webjar for angularjs has all of the optional modules.  The bower and npm webjars have each one as separate artifact entirely.

--
--
Lift, the simply functional web framework: http://liftweb.net
Code: http://github.com/lift
Discussion: http://groups.google.com/group/liftweb
Stuck? Help us help you: https://www.assembla.com/wiki/show/liftweb/Posting_example_code

---
You received this message because you are subscribed to a topic in the Google Groups "Lift" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/liftweb/VY10pnY0MCs/unsubscribe.
To unsubscribe from this group and all its topics, send an email to liftweb+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Joe Barnes

unread,
Jan 24, 2016, 4:29:44 PM1/24/16
to Lift
So back on the original topic of browsers caching lift.js... After verifying that my browser is caching old versions of lift.js as I make changes to it, I have opened and assigned this issue to myself.

The approach I typically use for this problem is to embed either a version or a checksum into the filename.  I tend to favor the version approach since it makes tracing the origin of the artifact easy.  However, a checksum has the advantage of benefiting the Lift contributors as they experiment with changes to the source.

I will tackle this using the version approach just like lift-ng has, unless anyone would like to discuss a more preferable approach.

Joe
To unsubscribe from this group and all its topics, send an email to liftweb+unsubscribe@googlegroups.com.

Joe Barnes

unread,
Jan 24, 2016, 4:38:12 PM1/24/16
to Lift
BTW, I confirmed this while running the dev mode, if that is in anyway a factor (I believe it isn't).

Also, I just had the thought that we could do a hybrid approach for contributors.  Use the version, but if the version contains "SNAPSHOT" include a checksum.  

Joe

Tim Nelson

unread,
Jan 25, 2016, 8:06:11 AM1/25/16
to Lift
What about packaging it as a webjar instead of modifying ResourceServer?

Personally, I'd like to see ResourceServer and all of those js and css artifacts in the repo go away and we only publish lift.js as a webjar.

I did write a version of ResourceServer that handles webjars, but then found out that any Servlet 3 container can serve webjars out of the box, but I haven't gotten around to testing that.

Another thing is, since I use embedded Jetty and sbt-assembly, it doesn't work because the jars must be in the WEB-INF directory. So, I still need a solution for that.

Since we're now using sbt-web for lift-webkit, it should be fairly easy to create the webjar. The only thing we'd need to do is move it to the location that sbt-web expects it.

Tim
To unsubscribe from this group and all its topics, send an email to liftweb+u...@googlegroups.com.

Joe Barnes

unread,
Jan 25, 2016, 9:52:15 AM1/25/16
to lif...@googlegroups.com
I recall you mentioned this because you wanted to be able to include lift.js in your own bundle of js.  I hadn't thought about it being the official way to do it.  I kinda like the idea.  Do you think we should straight publish a webjar, or publish via NPM and/or bower?  Publishing there will still give us a free webjar, and would be available for folks who use are using those js tools.

I'm keen on Lift doing the webjar serving, as I have mentioned before.  I'm right there with you regarding the Servlet 3 point you made.  I actually suspect that approach isn't ideal because of this whole caching thing I've brought up.  I don't know that the Servlet 3 container approach handles that (I would think it does, but folks get this wrong surprisingly often).  Like I mentioned to you the other day, I have this worked out in lift-ng such that the version is used as part of the artifact path so the right thing happens.  It should be no problem to port to Lift.  

There are other things we can take advantage of if we serve it ourselves.  In lift-ng, we serve the non-minified artifacts in dev mode.  This makes debugging errors much easier.  We could also combine all of the requested webjar artifacts into one since I'm guessing it will be a while before http2 makes that no longer necessary for optimizing. 

How do other folks feel about this route?  I have no problems handling the necessary code changes.  But I know zero about publishing JS artifacts to NPM and/or bower.

Joe

Tim Nelson

unread,
Jan 25, 2016, 12:02:21 PM1/25/16
to Lift
I think publishing to Bower would be best so people using Bower would have access to it. That does require Node, but we are already using Node for our JavaScript tests and I'm hopeful that at some point we'll be able to take advantage of sbt-web plugins and/or Nashorn so we won't need Node.

WebJars have the version number in the path, so caching should not be a problem in a Servlet 3 container, or anywhere else. They do provide a nifty [webjars-locator](https://github.com/webjars/webjars-locator) library that handles finding the current version so you don't need to include it in your HTML. I use that in the snippet I wrote.

In dev mode, I almost always have ChromeTools open, which turns off caching by default, so I'm not concerned about that, but we could change it so that we don't send the caching headers in dev mode if that helps others.

I just pushed my branch so you can see where I'm at if you want. I've only worked on the serving part and it's not quite done.


This is what else needs to be done:

* Make sure it doesn't conflict with serving directly from a Servlet 3 container
* Add serving non-minified artifacts in dev mode
* Don't send caching headers in dev mode ??

As far as publishing to Bower goes, I can work on that. I'll try to work on that in the next few days.

Lastly, I think concatenating resources is best left to the build tool, but I wouldn't be opposed to it. One problem I can think of is you'd have to make Lift aware of your dependencies. The way I have implemented serving webjars only requires you to add the dependency to sbt. You then use the snippet to serve it, like this:

    <link rel="stylesheet" data-lift="WebJars.css?src=bootstrap.min.css" />

Tim

Antonio Salazar Cardozo

unread,
Jan 25, 2016, 9:49:28 PM1/25/16
to Lift
I don't necessarily mind the idea of adding a bower thing of lift.js (although I'm
not thrilled by the idea of adding build complexity on a project that isn't particularly
rich in committer time); I do, however, strongly dislike the idea of making this the only
way that lift.js can be served. Right now all you need to develop a Lift app locally is Lift,
and I think that's a very strong plus.

The WebJars snippet magic looks pretty sweet, and if it made it into 3.1 I think the
idea of moving lift.js out of toserve would make me considerably less squeamish :)
Thanks,
Antonio

Antonio Salazar Cardozo

unread,
Jan 25, 2016, 9:50:29 PM1/25/16
to Lift
Though also of note, I think it would be even cooler if the WebJar snippet
didn't require a parameter, but rather read the href from the link directly:

<link rel="stylesheet" src="bootstrap.min.css" data-lift="WebJars.css">

Thanks,
Antonio

On Monday, January 25, 2016 at 12:02:21 PM UTC-5, Tim Nelson wrote:

Joe Barnes

unread,
Jan 25, 2016, 10:37:23 PM1/25/16
to lif...@googlegroups.com
Antonio,

With Tim's suggestion, the lift js webjar would just be another dependency.  It wouldn't change what is needed to develop a Lift app locally, unless there is something I have misunderstood about your point.

Joe

Tim Nelson

unread,
Jan 26, 2016, 7:03:14 AM1/26/16
to Lift
I didn't know you could "read the href from the link directly", but I like it. I'll update the snippet.

The reason I thought it would be best to publish to Bower was because if someone is using Bower it would be available to them. But, I'm having second thoughts about that as they are insistent on keeping their one artifact per repo rule: https://github.com/bower/bower/issues/24

Bower does allow using a URL or a GitHib repo directly for a dependency, so they could possibly use that.

I'm now thinking it would be nice to just include all of the JS in the main webkit JAR. Whatever we do, I agree we don't want to lose the simplicity we already have.

Tim

Antonio Salazar Cardozo

unread,
Jan 26, 2016, 1:43:30 PM1/26/16
to Lift
Indeed, seems like that could get annoying for us. I'm basically down for
whatever provided that you can pull in the Lift packages and be good to go…
And assuming we can get publishing to wherever else we need to publish
automated alongside what we've already automated.

Re: reading the href, I think S.attr will do the trick, as I believe its context
is the element that invoked the snippet.
Thanks,
Antonio
Reply all
Reply to author
Forward
0 new messages