My question is just conceptual.
When you use the ui-router (docs) in your application, then you have a system built of multiple views. Right?
I was thinking about that, because looking at the network log of Chrome, every change to another view, the client-side makes a request to server to get the HTML files.
Well, the definition of SPA might vary, but basically it has nothing to do with making requests to a backend. It is a matter if the browser needs to do a full page reload to make that request.
Traditionally
Fill out a form, submit it and the browser is redirected to a new url. A full page request
SPA
The application makes an AJAX request in the background. On its response it changes the URL manually and then changes the state of the application. There is no full page request, just JavaScript running in the background
But you are right about suspecting something wrong when there are lots of HTTP requests for templates. You do not want your application to do all these requests to the server. To avoid that you actually have to precompile your templates using a tool like grunt or gulp. Example: grunt-angular-templates. This will insert the templates in your JavaScript code and Angular just grabs them from there, instead of making a backend request. During development though it is no problem.
With modern frameworks you need a tool to "compile" your project for production. You want to concatenate all JavaScript files into one file, bring in precompiled templates and uglify the code. This is not something frameworks give you, you have to set it up yourself using tools like grunt or gulp.
Hope this was of help :-)
Related
I'm an android developer and about two years and recently I've been thinking about building web applications. So I started researching about spring boot and everything is great. Then, I came across this thing called template engines (thymeleaf) which by definition separate your code from presentation.
What is confusing me is how can a backend server have html? should the presentation be handled by html, css and javascript in the front end? I even saw tutorials where they actually type in html code in their controller as return values.
My understanding is that the backend server exposes APIs for the frontend to use by using AJAX and the frontend will manipulate this data and present the information on the screen, why would a backend provide html code?
THank you
the frontend will manipulate this data
What front end? You mean the JavaScript code in the HTML page? Where did that come from? Oh yeah, the server.
It is the server that serves the HTML pages to the client, as well as any .js and .css files.
The server could provide static pages, and anything dynamic is handled by JavaScript. Or, the server could dynamically build the HTML page, using ... you guessed it ... a template engine.
You generally don't want JavaScript to build the page initially, just to use JavaScript for handling any dynamic behavior. Some pages don't even need any dynamic behavior.
Unless of course you're thinking about single-page applications (SPA), where there is only one root HTML page, and everything else is built client-side with JavaScript and AJAX calls, but most web applications are not SPAs.
Thymeleaf replaces JSP by providing HTML pages using a template engine. The controller requests the HTML file and Spring Boot provides that template after building it using the Model provided.
Thymeleaf is great because it allows you to rebuild templates on the fly. Lets say for example you're showing a users points to them on the front end, but maybe the points increase or decrease.
What you can do is build the template in the background using a Model. The Model reference is magically provided to the template provided which parses it.
#RequestMapping(...)
public String request(Model model) {
model.put("points", 5);
return "my-template.html"
}
Then use the Thymeleaf language to provide your object to the HTML file to be processed in the engine during runtime.
<html..>
<head>...</head>
<body>
<h1 th:text="${points}"></h1>
</html>
Spring Boots Template engine will build this in the background and present it to the user, but it will show the actual points to the end user! Hope this helps a tiny bit.
I know this question has been answered pretty effectively so far, but I want to add my two cents in as I work with Thymeleaf often.
The easiest way to think about a template engine is that it allows some dynamic development of html based on information passed to it by the controller method. This allows you to put logic in that normally wouldn't exist, or say display a certain section if a user is perhaps logged into admin.
If web pages were houses, html is the frame, css is the walls, Javascript is the lights and electricity, and a template engine would pretty much just be the architect designing the plans on the fly before the frame was built based on desires of the buyer of the house (user inputs).
OK, newer Apps and websites may just load/boot/open once and then pull or push data via AJAX requests, this is good, it saves traffic and it is fast.
But it has not always been like this and some Frameworks still don't build everything on small requests. Spring in Java or Symfony in PHP are MVC Frameworks and use template engines to build pages. This may sound a little outdated but there is still a lot of websites using this.
And if you build a web app for a customer with slow PCs or other devices and the page contents are performance heavy you might want to do as much work as possible on the server so that the user does not have to wait for long. And also you can cache the rendered pages. There is even server side rendering of react pages to e.g. make the initial page load faster...
With Java and Spring I did just use JSP I don't know thymeleaf. Just use what you like and maybe what is most supported/documented.
And building websites like this does not mean you cannot use AJAX, but if you use templates you need to think about what makes sense.
What is confusing me is how can a backend server have html?
The "back end" must have HTML, because that's what's delivered to, and rendered by, the client.
It may just be that the back end "server" is just a CDN delivering, say, an HTML/JS SPA, but there's still something delivering content to the browser.
That said: server-side rendering is still a thing, and has had a resurgence lately--a React app may have its initial rendering done on the server so again the client gets a page rendered with both HTML and associated data, and then starts acting like a normal SPA.
My understanding is that the backend server exposes APIs for the frontend to use by using AJAX and the frontend will manipulate this data and present the information on the screen, why would a backend provide html code?
Because something needs to run the JS to access those APIs.
Some history:
Browsers used to suck. JS used to be a neat add-on, sites were relatively static, and essentially all rendering was done on the server. The back end would get data from wherever it got data from and generate complete HTML pages, and there was little happening on the client side other than some form fields, maybe some validation, and that was about the extent of it.
I have a news section created with ReactJs, each news post acts as an individual page.
Unfortunately Google is not indexing these pages because of REactJs. I tried to use the babel-polyfill webpack, but it's still not working. Also, I'm making my Ajax call BEFORE rendering the DOM.
Any other ideas for another workaround on this?
the google crawler won't wait for async requests to resolve, and because your pages are rendered on the users' client, they will appear to be empty pages.
You have two options. Either modify your app to render on the server, this is often called a universal app, or an isomorphic app. There are many tutorials for creating these. The other option is to pre-render static html from your code so that the crawler can see what should be there. There are numerous libraries you can use for this.
The first option is more extensible and probably preferable, but a bit more complex. So make the choice about whats more appropriate for you
It is not indexing them because they are bundled so tat they could be rendered inside your client's browser. What you ought to do is server side rendering.
You can find more about it here: https://medium.freecodecamp.org/server-side-rendering-your-react-app-in-three-simple-steps-7a82b95db82e
I'm running an angularjs app, and can't figure out why my page is loading slowly. The css and js files all load quickly, but there is a long delay between that and when the html loads, where the app just seems to stay suspended doing nothing
headertemplate.jtml, footertemplate.html, and notelist.html are the partials being loaded to make up the view
Angular uses ajax to retrieve templates. You should be able to look at the network tab in developer tools to see the ajax request for each template. That might give you a clue as to what the hold up is.
I'm not sure why it's taking so long to receive them, but one way you can speed that up would be to pre-cache the templates with a tool like HTML2JS. This way, your templates are just another JS file that you include along with your program code and templates are loaded as soon as your program code is loaded. It will increase your initial download size, but will greatly improve the speed of fetching templates.
You can cache all templates in $templateCache which will make angular app never make xhr request for partial htmls.
https://docs.angularjs.org/api/ng/service/$templateCache
There are various gulp and grunt modules to automate that process.
https://www.npmjs.com/package/gulp-angular-templatecache
https://github.com/ericclemmons/grunt-angular-templates
By the way are you making any server calls in angular.forEach, for some reason they don't show up in network tab (idk why?? o.O)
Or may be you are using resolve in ui-router's state config which is taking time to activate the state and calling html partial..
Per default, Angular fetches the HTML templates from the server when the user navigates to a route. With that in mind, imagine this scenario:
User loads the Angular app. The main view has a subpage called "Order".
While the user is studying the main view a new version of the app is rolled out in production. The new version has a complete rewrite of the Order page with new Javscript and HTML.
The user navigates to the Order page. The Javascript is already loaded by the browser in step 1, so the user is on the old version until app is reloaded. But the new template gets fetched from the server on navigation. So now the Javascript and template are our of sync!
Is my assumption that the Javascript/HTML is out of sync, correct?
If so, are there any best practices related to this issue?
I guess one solution is the make Angular fetch all the templates on app initialization. But this could be a performance penalty if the app has hundreds of HTML views.
I've never wondered about that issue myself. One possible idea would be to reuse the pattern known as assets versioning, where upon new release, you rename all your assets.
For instance, instead of login.html you'd use login-xyz.html as a name of a template. xyz could be a random value, or a checksum of the file. Checksum might be a slightly better option because if the new release is small (i.e. you fixed just some small bug in one file), if user loads any page but the fixed one, he/she will not be bothered with a reload - all other files will have the same checksums, they'll work with no interruptions.
This way, when an outdated Anguar app tries to fetch a template, it'd get a HTTP 404 error. As an addition to that, you could write a simple $http interceptor, which would detect a 404 response, and reload page automatically (or offer user an option of doing so).
There are modules which are capable of renaming assets, such as gulp-rev - but I never heard of using that for Angular templates. You might implement something like that on your own, though.
Of course you might want to keep both the new and old versions of files to allow users to work without interrupting them with a refresh. Depends on what your requirements are. I assume you're trying to avoid that, though.
Sample 404 interceptor (CoffeScript, as I have it handy now):
m.factory 'notFoundInterceptor', ($q) ->
return {
responseError: (response) ->
if response?.status == 404
# Reload, or warn user
return $q.defer()
# Not a 404, so handle it elsewhere
$q.reject response
}
m.config ($httpProvider) ->
$httpProvider.interceptors.push 'notFoundInterceptor'
Thanks for good answers.
It turned out that this problem solved itself for us. Every time we roll out a new release all the users sessions gets deleted and users will be sent to the login page. This will trigger a page load and fresh JavaScript/HTML gets loaded.
I've read about this issue long time ago, and one option is to do versioning on changed pages and application.js file.
For example on your version 1 of your application you can on your html file use something like:
<script src="js/angular_app_v1.js"></script>
Inside your routes also version the templateURL
templateUrl: 'templates/view_product_v1.html'
So when you roll out a new version you won't be overwriting templates and users already working will have the old version until they reload the browser but won't have version inconsistences.
Versioning of the assets using the file names would become unmaintainable for even a medium sided app.
Although it is a heavy weight approach for web assets you could look into content negotiation. This is where the call for a resource, generally a REST api returns the version of the resource, Content-Type: application/vnd.contentful.delivery.v1+json.. On the client you can check that the version matches what it expects. So if the client only knows how to load v1.1 and the resource responses with v1.2 the UI would know it cannot process that and should reload the page.
Another possibility is to load all templates up front in the UI. There are build processes in Grunt you can run such as https://github.com/ericclemmons/grunt-angular-templates that will combine all of your templates into a single file for delivery and then load them into $templateCache so no requests ever get to the server.
If you have some sort of server-side language you can build a filter in (.NET, Rails, Java or whatever), and pass along a version number with your template requests. If the version requested by the client is older than what's deployed, you'd send an error to the client. Your client would watch for that error ($http interceptor) and force a page-refresh to pull down the newer javascript code. (Maybe show an alert to the user first so they know what's going on).
You can preload all your templates into a $templateCache and serve them as one templates.js file. There is a gulp task for this https://www.npmjs.com/package/gulp-angular-templatecache. Then your application will load all templates in a single request together with application scripts on start up, thus they will be in sync. Read http://www.johnpapa.net/angular-and-gulp/ for more info.
It always makes sense to have a version number and use it when syncing resources. It's not only a good practice for the use case you described, but also for other situation, such as rolling back to a specific version or having two versions live and usable (for example in order to let some users preview the next version)
Starting a new Ember app and was prepared to follow token authentication type structure for authentication in the restricted API routes but was then told we need to not show any of the javascript (or as absolute little as possible) before authentication. This has me a little puzzled given single page javascript apps.
I'm using the, very helpful, ember-app-kit which has great tools that compile everything down to a minified and obfuscated single javascript file, which I thought was good enough for security, but apparently its not.
Having the entire app loaded once, and even in a single compiled/minified js file, what is best practice for "hiding" some of the javascript and only loading after authentication?
I had one thought of my own and have found another potential:
A ) coming from rails, I thought I could just build a very thin rails app that handles authentication in a server side view that doesnt load any of the app js. Then on successful authentication, transition the user to a view that loads all of the JS for the app and go from there.
B ) I found some talk of new functionality in ember-data that allows you to async load javascript files in the models. This seems like it could work but also seems very complex and I'm not sure if It'll totally work cause they want to hide not only models but things like app routes (basically everything but login)
I have done option A in rails: authenticate the user on the server and then forward them to a page containing the actual client Ember application. It will be far simpler than trying to dynamically load the app on the client side. Simple is usually best.