I am building a sizable, mobile application that is currently built on top of jQuery Mobile and KnockoutJS. My first approach made heavy use of a Single Page Application design along with loading all dynamic content and data via Knockout and ajax calls. This has worked OK but maintenance and development has become very complicated as jQuery Mobile loads more and more into the DOM.
I wonder about moving to more traditional, individual HTML pages that are completely static while still loading data via Knockout and ajax. This will allow browsers to cache the biggest parts of the app: the HTML pages.
Question:
How can I best pass parameters around from page to page without creating unique URLs that inhibit client-side browser caching? I want browsers to aggressively cache pages.
I realize that I can implement all kinds of server side caching but that is not my goal here. /Display/3 and /Display/5 are the same page. Will the browser cache these as one?
I wonder about passing parameters after the hash mark? /Display#3 and /Display#5? How about passing parameters via JavaScript in the global namespace?
Hoping for a standard approach here.
Ok sorry for misunderstanding, but I think your approach goes the wrong way. You cannot use GET paramters that way, also JQueryMobile is a little bit confusing in url handling for AJAX.
Normally, if using AJAX to refresh content, you do not need to reload the page. So you need no caching, because the page is already there and only some content is reloaded via AJAX. But JQM's single page approach is not usable for dynamic created content that way. You can only dynamically create a page with all content in it, and JQM shows content by switching visibility. Then the # could be used to switch between the pages (the # does not force an reload, as used for on side navigation).
You can write your own loading function calling in buttons and links (instead of using URL GET paramters). By using JQuery's $.ajax method with dataType "html" (instead of json, default) you can do a content refresh in its success handler.
You could try html5 sessionStorage/localStorage. If html5 is an issue, than plain old cookies.
Just to clarify, if there are several HTML pages, each page must have its own URL.
Related
I don't know if this is a PHP or JavaScript code, but what do you call this technique about changing web content? For an instance, the MDC Web demo site. It has an empty content if you view the source, but completely contains all elements if you inspect the page.
Regarding PHP, I think it is done with a PHP code in MDC Web's case, but how exactly? Is this a common technique? I wanna know this method coz it's useful in some cases where there's actually no need to reload the page, but able to change the content and URL.
This is called Single Page Applications (a.k.a SPA).
A single-page application (SPA) is a web application or web site that interacts with the user by dynamically rewriting the current page rather than loading entire new pages from a server. This approach avoids interruption of the user experience between successive pages, making the application behave more like a desktop application more.
So I've been using the old fashioned way to switch between pages within my websites, I include my header on every page and use a/href's to go to another page.. I only use ajax requests within the pages themselves only. Not to switch my visitors to another page, as I said, I do that with native href's.
I looked at the history.pushState() to change the url's on the address bar every time I load a new page via jquery ajax. And it does it pretty well. The thing is when I refresh the page, it does keep the same url and loads that url/file again. But the file comes back nude, with no CSS and no header, since those are only included in my index.
I use php as my SS though.
Any good advice?
Using hrefs is perfectly fine, and standard. However, there are some performance gains to be had by avoiding full page loads via ajax.
If you do want to use pushState and ajax you have to configure your server so that all HTTP requests hit your index page/router. You can do this in nginx, apache, express js, or whatever you're using on the backend.
Then in your JS you'll want to sniff window.location to see what page the user is currently at and fire an ajax request immediately to load that page.
Alternatively, a faster but more difficult approach is to not set your server to point all requests to your index, and actually serve the full HTML for the page they request (HTML, CSS, headers and footers) so that the page doesn't come back "nude". This will make the initial page load faster. After that, you can resume using ajax requests as they navigate around the site.
How you do this depends on your technology stack. If you're using webpack like me, then at least in dev-mode you can set historyApiFallback: true to have all requests "fallback" to your index, and then I'm using React Router to load the appropriate page. But again, you might be using something different.
I've been learning about angularjs and have been very confused about how angular manages to change pages without refreshing and yet have a completely different view.
Are they actually changing the page URL or just hiding all the elements of on page and showing the other?
This video by CodeSchool explains it quite well.
AngularJS is just a tool that allows you to build single-page web applications with relative ease. What you are looking for is actually the definition of Single-Page Application:
Single-Page Applications (SPAs) are Web apps that load a single HTML page and dynamically update that page as the user interacts with the app. SPAs use AJAX and HTML5 to create fluid and responsive Web apps, without constant page reloads. However, this means much of the work happens on the client side, in JavaScript.
Also, from http://www.johnpapa.net/:
A SPA is fully (or close) loaded on the initial page load, it’s key
resources are preloaded, and progressively downloads features as
required.
And, more specific to your particular question:
When a user clicks on a menu item, the SPA sees that url and
translates it to a View that should be displayed. If the view has not
been seen before, the application may make an HTTP request to retrieve
the HTML template for the view. Then it will compose the view, fill in
the template, and display the view in the appropriate location within
the shell. If the view has already been viewed once, the browser may
have cached it and the router will be smart enough not to make the
request. This is one way a SPA can reduce round-tripping to and from a
server, and thus improve performance.
Keep in mind that this behavior is attained with the use of JavaScript, and does NOT require any specific library or framework (such as AngularJS), although you will probably want to learn how to use one to facilitate the process.
I also recommend you check these resources:
http://johnpapa.net/building-single-page-apps-with-knockout-jquery-and-web-api-ndash-the-story-begins/
http://www.johnpapa.net/pageinspa/
If your url's are mapped with the $routeProvider, you can reload a controller invoking $route.reload().
Essentially, I want to create a personal website that functions like this one:
https://sublime.wbond.net/packages/Jade
Whereby it's contained within one HTML page and clicking on a nav item will only load the required information.
Looking at the javascript code I believe the developer is using Backbone.js and Handlebars.js. I think they used PHP for the backend.
There is a key functionality that I'm after that is within this site. Essentially, when you are at the aforementioned directory, and then you change to https://sublime.wbond.net/docs, there will be an AJAX request for only the HTML that's needed and then it is appended to the current page.
Having written a simple backbone app by following a tutorial, it seems it's done differently. Hosting the app using node, it will load all of the content. When you go to another directory, it still loads all the content and then backbone will append the right piece based on the URL. I can see this being useful for certain kinds of apps, but I don't want that functionality. I looked into it more and I thought about using the fetch() functionality in backbone, but I'm not too sure he's using that either.
It appears like he's doing something like Rendr by Airbnb. I can't really use that because there the documentation is not sufficient right now.
It looks like when you call a page it just gives you the HTML all ready without the need to compile it locally. Is there something I'm missing here in terms of utilizing backbone or is this just some tool he's made to handle this?
If you are not afraid spending hours in front of videos, those excellent screencasts could get you started : the guy explains how to build a Single-Page app using Backbone and Marionette, from scratch.
This web site is not using Backbone, and the solution he uses is a mixte of full html page load and JSon call, look at this links :
https://sublime.wbond.net/browse.json
https://sublime.wbond.net/search.json
https://sublime.wbond.net/docs.html
https://sublime.wbond.net/news.html
https://sublime.wbond.net/stats.json
The simplest way to have the same behavior as wbond.net will be to change the way you render the page on the backend. You need to check if request is XHR and render only content, without layout. On the frontend you need to bind click event to each links which will send AJAX request on binded URL and put whole response in the page content area (jQuery's $.get() method).
This is a best practice type of question. I am developing a complete AJAX application. The user navigates to the main page of the application and everything from there on out is loaded via AJAX into the content section of the main page. Is it better to take all the javascript files I have and merge them into one file that is loaded on the main page or to split them up into just what is needed for each page that is loaded?
Putting it all in one file obviously has the benefit that only one HTTP request is made to load the javascript needed for the site and any request for a page there after will only need to fetch the HTML. But, this requires that every event that is wired up (using jQuery) be attached to the document using the live or on function. So everything will look like:
$(document).on('click', '#SomeButton', function () { });
Doing it this way will cause there to be many hundreds and possibly over a thousand events being tied to a single element, the document.
Putting them in separate files requires multiple HTTP requests to be made to load the various pages of the site but limits the number of events that are attached to the document.
Any thoughts on what is best here?
I would vote for separate js files for each page for bigger projects specially if your project is using any js library like jQuery and its plugins like grid plugin etc. In case you have a big single javascript file your first page will load slowly obviously giving your user a bad first impression. What we do is that we create separate js files for each page specially when there are ajax calls to load data for the pages. Plus there are separate files for each pluggable component like custome drop down or date counter etc. This way its easy to manage the code and customize it later.
Before deploying the app we can merge related files and create single file for a single page. For example if a page called editProfile.php uses a data picker, a jquery validation plugin and custom js to load user data, we can combine them in a single file so that only file will be loaded for a single page.
So I would vote for separate files for each page and applying optimizations before deploying.
Honnestly i'm not really an expert in this domain but this is my piece of advice on this subject on a production environment.
I would use CDNs for libraries (like jquery). They offer maximum cacheability, and there is a very big chance it is already cached in your client's browsers from visiting other websites. This saves some requests already.
Group and minify your common javascript code, like plugins, utilities, things used throughout your site. It will be requested once for all and will then be available.
Have a separate, minified, script file for each "page" you load dynamically that you will load along with your content.
Loading script for content pages:
Using the .load() method from jquery to load fragments of pages will unfortunately remove any <script> tag present in the fragment. As noted in the jquery load() method, this is to avoid "Permission denied" in IE.
What you can do is to have a <script id="contentScript"></script> tag in your base page and load the script along with the content by replacing the src.
I don't know if it is a good practice but it makes sense to me :-)