In the interest of learning how to use Angular, I thought I'd port a half-finished project of mine over from vanilla JavaScript.
The original is here: http://john.bitsurge.net/bikeracks/
The new version is here: http://john.bitsurge.net/bikeracks-angular
angular-leaflet-directive: http://tombatossals.github.io/angular-leaflet-directive/
The first thing I noticed was that the angularized version was significantly more CPU heavy than the original. To see this, zoom way out and then zoom in again quickly. This is problem still manifests, even after removing all $watchs from the markers. ng-stats claims there are only 18 $watchs left, which is certainly acceptable.
The output from batarang suggests to me like things are actually pretty fast, but that contradicts that actual user experience, which is noticeably different between the two. Maybe these batarang times are per-call but there are just hundreds of calls being made?
Batarang Output
The second thing I noticed, while trying to debug the first, is that the angular version doesn't appear to be using any mobile-friendly styling! The buttons are hopelessly tiny and I can't read the attribution at all.
Any idea what's going on here?
Angular looks like the desktop version
The vanilla app uses mobile-friendly sizes
I still have no good answer for the performance issues but the map rendering problems were due to a missing <meta> tag in the <head>.
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
..
</head>
solves this one! \o/
Related
I'm having an issue with placeholder text not appearing in IE 11 when utilizing AngularJS. It shows up on every other browser and I haven't modified any CSS to change the appearance of it. I have even disabled all stylesheets and still can't get them to appear. See image below.
If I visit other sites that utilize placeholders within input fields - I have no issues. I'm a bit stumped in terms of resolving the issue. Any ideas?
$(document).ready(function(){
// IE workaround to show placeholder
$(element).placeholder();
})
So it seems I found my issue and also have a solution to follow up. Prior to this I was having compatibility issues with Angular running in specific version of IE and had force compatibility to IE 9 inserting this in the head of my HTML:
<meta http-equiv="X-UA-Compatible" content="IE=9">
I then proceeded to utilize this angular directive https://github.com/cvn/angular-shims-placeholder. It didn't work right off the bat but after scratching my head some more, I realized it may be a caching issue and upon clearing it out, I now have placeholders within my inputs in IE!
What jinja2 can achieve, the same can be achieved with Angular.js. My question is- are there any advantages of replacing jinja2 with angular.js completely ?
I think most problems came from the same obvious difference: Jinja2 is server-side, Angular is client-side, this makes they really different.
SEO. Google don't understand Angular magics. It is just a heavy Javascript code and Google can't understand it fine. Sure, you have some workarounds to show your important text to Google, but to solve it you'll have to render some things server-side, going back to Jinja2 or some hack to render things to improve your SEO. (it is not important if you don't care about Google searches)
Performance Server-side rendering is way faster than Javascript rendering. I'm talking about your average user, maybe with an outdated Internet Explorer and a crappy internet connection. With Angular, you have to wait at least some Javascript assets to be loaded before the page is usable. Users notice this and we know a slow site will hit your conversions. Check this Twitter article about "time for first tweet": https://blog.twitter.com/2012/improving-performance-on-twittercom
Compatibility. Yes, they claim the framework supports all common browsers, but have full documentation about hacks to make it work for IE7. Depends of your audience.
Maturity. Jinja2 is really stable, has a pretty API and is deployed with almost all Flask websites. Angular is still evolving and sometimes things just change a lot.
Inexperience. You can't just replace Angular with Jinja2. When you try it, you will understand they are different and you must not work the same way with both. You will make a lot of mistakes before you make things right, just like with any new awesome tool you use.
Of course you can claim against all my arguments based on your specific needs, this is just some things you must understand before you go to Angular.
That said, I'm using Angular in several projects, mostly for single page apps. This is an awesome use case for Angular. In all these projects, I still use Jinja2 to some rendering, so this is not a complete replacement.
UPDATE:
Some updates almost two years after my initial response.
Google is better understanding dynamic rendering, but I still don't trust it.
I don't think the client-side rendering is a thing. Only realtime data is rendered client side, but the base HTML is generated server side.
Angular dropped IE7/IE8 support. It is definitelly a good thing for the web, but unfortunately I still must support these browsers in some cases.
Angular 2 is on the way, changing everything you know about current versions. I don't remember any major Jinja2 change.
Why is replacement your objective? Use the power of both Jinja and other server side frameworks together with the power of client side frameworks.
The benefits of using both:
less and easy code
better performance
more easy to maintain
and much more. You have a choice.
Choosing for one or the other will make your work frustrating and complex.
I'm wondering if anyone has found a solution to this problem. Is there a way to get the best of both worlds:
build a page-based site, with permanent links, accessibility, SEO, and graceful fallback / progressive enhancement (basically all the best practices of web development)
and, for those with javascript, a responsive front-end experience with ajax loading of content, no page refreshes while navigating the underlying site pages, minimal redundant downloading of scripts/content/css/etc. (all the benefits of a client-side framework like AngularJs or Ember.js)
I see a few major sites are able to manage this (gmail, stackoverflow), and I see that Jeff's new site builds a bare-bones version of the site in a noscript tag.
Is the solution to the hybrid page-based/single-page app to build two versions of the site, send both, and let the client decide which it can show? (is this what gmail does?)
Or is the problem that AngularJS et al. are simply not designed to allow for graceful degradation?
It hurts my DRY brains to think that #1 is the answer.
(The reason I am focusing on AngularJs is that I like its support for html templating, declarative style, and its attempts to fix js scoping. Ember and other frameworks are excellent too; maybe one of them would be a better fit for a hybrid site?)
This questions is a bit of a nuanced one because the answer is "it depends". For example you mentioned Gmail, there isn't any reasons whatsoever that an application like Gmail would need to be indexed for SEO, though depending on what you want or need to support you may want to ensure you can support not having Javascript.
However even the "no-javascript" argument is getting tired and weak these days, at least for the class of "web applications". If I want to use a Windows application I need Windows, if I want to use a javascript powered web application it isn't unreasonable to assume that I'm going to need a browser that isn't crippled to use it.
However back to your question I can only speak to AngularJS because I'm the most familiar with it. For the most part it does allow you to support a progressive enhancement approach, though don't expect to use things like URL routing if this is what you want to support. What you can do is use AngularJS controllers, bindings and directives similar to how you might use jQuery as a way of enhancing the interactions and behaviours of the page.
Just keep in mind this approach will seriously limit what you can do with Angular (or Ember for that matter) and it may start to be debatable what you are getting from this approach that you couldn't easily do with jQuery alone.
The alternative these days is to do what sites like Twitter are doing. That is basically serve fully rendered HTML from the server for any view on the initial load and then use Javascript for subsequent loading and enhanced UI behaviour. This is very effective (though perhaps quite challenging to implement) if you really need to support browsing with and without Javascript and has the added benefit of improve the rendering/load times for the first request. Again "it depends" because it depends a lot on how your site actually works if it is possible to use this. You have to design for it, and it isn't going to be trivial or easy.
Update:
For what it's worth we are taking the Year of Moo approach and rendering the pages that need SEO using PhantomJS and sticking the cached initial state of them somewhere to serve them up. We have a rake task we run on deployments to update this. Again this is just the initial state but it helps get around the issue for now.
Things are always changing though and I'm sure I will have changed my mind on this approach in a year or so.
Have you read Google's Making AJAX Applications Crawlable. You can have JavaScript single page app and crawlable content.
If you stick with angular, there is interesting article: Turns out it is possible to have your AngularJS application indexed
i have a fixed width site, and the client has requested that when it is viewed on a mobile, it should show the whole site by default (ie zoomed out).
In my head i have the following:
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
Which is the code that came with the wordpress template im currently using.
Ive looked around various answers on here, and tried various different combinations, however, whichever i use, the site always loads on a mobile with the screen zoomed right in to the top corner (have tested a couple on phones, and a couple with responsinator).
I know im probably being really daft here and missing something really obvious, but if anyone could help itd be hugely appreciated!
If anyone would like to take a look at the site directly, its EdoMidas.com
try this:
Replace 1140 with the width of your website.
let's assume I have a so called 2.0 app, compatible from IE6 upwards. The app uses quite complex CSS and is driven by heaps of JS. It works, very well it does.
Now let's assume there is a client who own a strangely coded site, archaic in ways, and forces IE7 emulation through this wonder of a tag:
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
Now, he desires to use my app, which is injected in his code using a simple external script call. It works, but not so under the IE7 emulation - obscure bugs from Hell start appearing, not even overflow hidden works properly. By itself the app does work in IE7, but as it turns out, the IE7 emulation is not the same as IE7 and has it's own set of fancy issues.
Turns out the client is unable to strip the emulation meta tag, so I'm left with I don't really know. Does anyone know of ANY WAY I could overpower the rendering mode set in the page header or would there be some other suggestions?
My utmost thanks for anything usable.
Perhaps you could make a wrapper for your app. An iframe that contains an empty page to make the script call. The content of the iframe should not be affected as the meta won't be present in the empty page.