I'm trying to play with Google Maps API.
My HTML code looks like:
<div id="map-1"></div>
I use some JS to init map on the page, nearly similar to this one:
var mapInstance = new google.maps.Map(document.getElementById('map-1'));
It works well.
The issue is, I need to add and remove a maps on a same page multiple times (when user clicks on corresponding links).
I haven't found anything about how to remove a map from the page - with all the html changes and events it brings on initialization https://developers.google.com/maps/documentation/javascript/reference
There're some methods like clearInstanceListeners, which are likely related mostly to the points and overlays, not to the map itself (I suppose it should remove a zoomin/out, doubleclick and other events).
I've tried something like google.maps.event.clearInstanceListeners(mapInstance);. It doesn't work - my map doesn't loose any events.
The reason why I'm asking for this is the memory leaks. I suppose that if I create nearly 50 maps on my page without successfully destroying them, my page will use too much memory (because events are still in memory if only an HTML is removed) and as a result, overall performance of the page will dramatically slow down.
Do you have any ideas about how this issue can be solved?
I've also seen a topic Google Maps JavaScript API V3 - Unload / Deconstructor / Delete / Remove
They recommend to use jQuery.remove().
I don't think it's a right case for me, because:
1) I simply don't use jQuery in my project
2) remove method removes events only from jQuery's cache (events which were binded by jQuery)
3) as a result of the 2), html is removed, but memory isn't cleared (hello memory leak).
I encountered the same issue recently. First, Have you try it? It doesn't end in a memory leak every time... It should be really quick to test on your computer.
Anyway, in my case, I solved the memory leak issue updating only the data (I used a heatmap overlay) and keeping all the way long the same google map. I'm not sure it's exactly what you're expecting but hope it helps..
Related
So I have a very specific problem that presented itself recently (right before our planned launch day tomorrow) and I am not completely sure how to solve it. I have built our website of an HTML-template with my modest front-end skills and we are very pleased with it. However, I can't seem to solve this.
The problem:
I have a filter system that allows a user to filter articles that are presented on a page. A user can even fill in this filter on the home page, direct to the page with the articles and have the filter applied. However, if then the filter is broadened (less strict) and new articles present itself, the pictures do not show up. Found out this is the case because the flexslider behind it has to be initialized again which happens on a window load (e.g. when the window is resized). The function that controls the initialization of the flexslider is in an external js file and I am not sure whether I can call on it from my own custom.js file, so I am thinking of just calling a resize/reload window function to active it.
The question:
Can I run a resize window function (or something that activates the flexslider) without hindering user experience (more specifically, without ACTUALLY resizing/reloading the window)? I will run this on a change in the filter.
I know this is a very specific question but hopefully somebody can help me out.
Take care!
p.s. it would be ideal if I could run the actual function that loads the flexslider but this is located in an external js file.
EDIT:
Briefly some additional info. If I go straight to the article page, it has no filter active and thus shows all articles, if I then start flipping through the filter, all is good. It is however only if I arrive from the homepage with a set filter that the problems arise. You then arrive on the article page which shows only the articles that are within the boundaries, and when the filter is taken away it has problems loading the images of the new articles showing up. As if it had not loaded these because they were not open on window load the first time.
You can trigger a resize event by creating a new event and passing it into the dispatchEvent command on window. There's a nice guide here. You'll want the type of event to be resize, since that's what it's listening for.
window.dispatchEvent(new Event('resize'))
This will work for events that were added via jQuery as well as events added via addEventListener.
I managed to solve it after all by delaying the function that drops the filter values into my inputs so it loads in all images initially before applying the filter. It happens at such speed it's hardly noticeable.
Also, I did try to initiate a window resize function, it did work without actually resizing anything, but unfortunately the images did not load in properly (overlap and such).
Anyway, it has been solved. Thanks for all the input!
We have a complex web mapping app using arcgis JavaScript api. The following code is used to inform the ui that the map layers are loaded:
on(map,"update-end",function(){
//emit event to ui module
});
map.addLayers(layers);
The application frequently adds and removes map layers. However occasionally something is going wrong and although layers get added the update-end event doesn't get fired, despite the layers completing load. After this happens the event wont fire again unless the app reloads.
Does anyone have an idea under what conditions this may occur? How can we prevent the problem?
I usually put my map.on("update-end", endUpdateMap); sentence after any map.addlayer() in the same javascript where you are defining your layers. It works fine for me.
map.on("update-end", endUpdateMap);
function endUpdateMap(error) {
esri.hide(loading);
map.enableMapNavigation();
map.disableDoubleClickZoom();
map.showZoomSlider();
}
I had this issue, I think there is actually a bug in the JSAPI. If you remove a layer whilst it is updating then it actually breaks the "update-start" and "update-end" events, they stop firing completely. I will try and put a test case together at some point but I found with a slow drawing layer, like an image service, the issue was very prevalent.
Anyway, I had to think of a way around it and this is what I came up with:
this.layer.setVisibility(false); // set invisible first to ensure spinner stop
this.map.removeLayer(this.layer);
First, some background. I'm fairly certain this is not because of zombie views. I use requireJS and I have only one instance of main views at any given time.
Also, this behavior is random, I haven't been able to reproduce it even once, but several of my users have pointed it out and shown me a video where every click on the app seems to trigger the handler twice. The clicks happen very very fast. It can't be mechanical failure of the mouse because the problem has been reported on multiple machines. The reports are from people with fast Internet connections, for what it's worth.
Is it possible that two instances of the app are running at the same time? Are there any steps I can take to isolate a problem of this kind in backbone?
Apologies for the wall of text, please let me know if I can put up any extra information or relevant pieces of source.
Edit : I've managed to recreate this in Opera. After stepping through part of the code that fires twice (I was inspecting code that opens a modal), I was able to look at the view that triggers the event. Both views have the same CID, so this cannot be attributed to Zombie views right?
In my experience, this is almost always related to zombie views, or other DOM leaks. My best friend in this case if the Web Inspector Profiles -> Take Heap Snapshot and look for detached DOM tree (type "detached" in the search field).
It can occur in tricky cases, even if you think you're only instanciating views once.
Beyond that, you'll have to show us some code ;)
The problem here was that I was running a third party library that reports JS errors. Due to a n error on their part, event bindings on page were affected and this caused the confusion inside the application.
Moral of the story - Whenever you hit an error you feel is impossible, remove your third party dependencies one by one and confirm the problem is your fault to begin with.
I am currently using CKEditor to be able to edit and to view documents in my SQL database. If I change the content of the document in the sql database it should automatically update the CKEditor instance with the new text. My only problem is that it flashes when ever it updates (ie: it goes blank and then updates to the new text). Does anyone know of a way to make it a smother transition. I'm also using JQuery so I'm not sure if there is anything that could be used there to make a smooth transition to the new text.
CKEDITOR.instances.content.setData("data");
CKEDITOR.instance.content.setData("new data");
The change from data to new data will have a quick bit of lag.
There's no way to avoid some slight flickering when setting data in framed (based on wysiwygarea plugin) editor instance. This is because the entire contents of the iframe containing your work must be re-created. This is nothing like a piece of cake and I hardly think we can bypass this thing.
I'd recommend you to play with element.setHtml( html ) on editable though:
CKEDITOR.instances.editor1.editable().setHtml( '<p>FooBar</p>' );
This is not a valid method for setting editor contents in any way because it bypasses internal filtering, processing and stuff. Yet it may work formay you if you're careful.
P.S. You'll probably also want to cache editor1.editable() object to speed-up things.
There are quite some core developers of CKEditor active on stack
overflow.
Yep. We are ;)
It seems that the screen flickers because the page is reloading an iframe within the editor. By using the divarea plugin for CKEditor I can get rid of the flickering. The only problem now is that the CKEditor.readOnly property no longer works...
I implemented infinite scroll like so:
new_page_value = 1;
$(window).scroll(function() {
if($(window).scrollTop() >= $(document).height() - $(window).height() - 200) {
new_page_value = parseInt(new_page_value) + 1;
get_page(new_page_value);
}
});
When the user almost reaches the bottom of the page (200px left) the function get_page() is called. This contains an ajax call that gets all the contents of the new page and appends it to the <body> of the document.
Now I just realized if my site gets big and instead of having 10 small pages I have a gazillion giant pages then the user's browser might crash if they are persistent enough to keep infinite scrolling for long time.
Would this be a possible solution to this problem:
I will keep appending the new pages to the document <body> until the 10th page, after that I will be replacing the <body> content entirely instead of appending. So using html() rather than append().
I just don't know if this will actually work to prevent crashes. Will .html() clear the "memory" of prior html that was brought in via ajax?
I really think this is a common issue for many sites with AJAX list content. So let's take an example at some of the most popular ( think of scale = experience ) websites and their solutions :
Google Images
If you check out images.google.com and you search for whatever, for e.g. "guiness", you will see a page full of results (actually the images are ajax loaded, not the html-code, so the page is with fixed height) and when you scroll at the bottom there is a button "Show more results". This might be solution one of your problem, but is it really necessary to place a button at the bottom after, for e.g. the 10-th page? I really think it is generally a good solution for page usability and memory leaks, but it is really not a necessary option as we can see in :
Facebook
Facebook Newsfeed is another story. There is a button "Show more posts", but I really don't know when exactly it is displayed rather than loading the next page of posts. It happened to me once to load 10-15 pages of posts, only by scrolling. And you know Facebook posts include videos, photos, AJAX comments and a lot of more Javascript fancy stuff, which take a lot of memory. I think they've managed to do this after a lot of research, how much of the users scroll to the bottom.
Youtube
Youtube has "Load more videos" at every page, so the solution is basically similar to Google, except that Google renders the whole html of the page and on scrolling just loads the images.
Twitter
Twitter supports infinite scrolling. Yep, they do it may be because tweet is 140 characters and they don't need to worry about memory so much. After all who is willing to read more than 1000 pages of tweets at one page load. So they don't have a button for "load more" and they don't need one.
So there are two solutions :
Use infinite scrolling ( you should consider how much content you load and how rich it is )
Use button : "Load More"
Most of all, you should not delete already loaded content of a list.
Nowadays everything is Javascript and Javascript has garbage collection, so it is very hard to unload the DOM ( if it has Javascript, not plain text ) and manage to remove the Garbage from Javascript. Which means that you won't free the whole allocated memory of the unloaded content from the browser.
Also think about of your requests, why would you need to load again something, that you have already loaded at first place. It costs another server request, meaning another database request and so on.
I have worked with this before and here are some of my thoughts:
a) If you are appending data to the memory page(s) at a time then it is not an issue, some browsers might not respond well but most of the lastest browsers will render without any problem so long as there is enough memory on the target machine, you could probably see how the ram usage increases as you append pages. Use chrome for this as each page is a separate process and it has an inbuilt task manager
b) regarding usage of html(), it indeed removes the markup but it does so at a heavy cost as it tries to take care of special conditions and has an overhead and accesses all the controls nested within the container that you are replacing (not sure about the last pat), but it has a cost. A simpler way to clear the DOM would be to use the innerHTML property and set it to empty, jquery does this but it is at a later point in the html() api. open up the api and look at the method.
using innerHTML
$("<selector>")[0].innerHTML=""
Also deletion of pages sounds weird to me as a user, what if I want to go back to the initial comments and please dont think about making it an infinite scroller too.. I have tried and given up after the number of bugs raised but we had a genuine use case for it and I had to stick a button up there, but this wasnt when the user scrolled away from the first page, this is when the user landed on a 3rd page but now needs to see the results above it.
Hope that answers your question and btw infinte scrolling is your friend use it, dont over engineer a case which will probably only be tested by your QA team. Its better to spend your effort somewhere else.
Yes it will, if i may suggest an idea after let's say 5 pages just delete the first page and append the new one instead of deleted all of the previous pages. good luck :)