One of the biggest complaints about Operator is that it affects performance when loading pages and switching tabs. I've been spending the past few weeks analyzing these problems and I think I have them mostly solved. Note that page load vs. tab switching are actually two different problems; tab switching has to do with how fast I process the microformat data, whereas page load has to do with listening to DOM events. So here's what I learned:
- My method for removing duplicate microformats was unnecessarily expensive. I was sorting in every case, and also duplicating and chopping up arrays. I went back to the way I originally wrote it and it works much better.
The adr microformat is a real pain because it doesn't have the concept of default text to display in the UI like other microformats. This meant that any page that has a lot of adr microformats was very expensive because of all the work I do computing what the address could be. To solve this in the future, adr will not be on the toolbar by default.
Incidentally, the only reason I added adr in the first place was because I wanted to handle the edge case of multiple addresses in one hCard. I have since added support for actions to function on multiple items in a microformat, so the next release will move mapping back to hCard where it belongs with a submenu if there are multiple addresses.
- Some pages have lots of hidden microformats they show and hide based on interaction with the page. This can cause some performance issues. I think that by default, microformats should not be visible in Operator if they don't show up on the page. So a page can have a thousand hidden microformats and it won't affect performance. There will be an option to show all microformats.
- You have to be very careful not to add event listeners too early or you will get WAY too many messages. I was adding my DOM event listeners too soon so I was getting all DOM events during page load. Bad idea. Listeners should be added on each individual pageshow event, not DOMContentLoaded, and you should not try to be smart and add listeners recursively. Just add them to each target for each pageshow event.
- While we're on the subject of DOMContentLoaded vs. pageshow, if you have an extension that updates the UI based on page content, you have to manage the interaction between these messages very carefully. The problem is that there are cases where you get just pageshow, just DOMContentLoaded, or both. Here's the scoop: DOMContentLoaded happens on the first load of a page as long as it is not from back/forward cache. pageshow happens with the load of any page including from the back/forward cache and it happens after DOMContentLoaded. The case where DOMContentLoaded happens without pageshow is the display of error messages like when you put in a bad URL. So the trick is to disable your UI on DOMContentLoaded and do interesting stuff on pageshow.
- My testing shows that a pageshow event for a page containing frames doesn't happen until all the child frames have received their pageshow. Because of that, I can wait to process the microformats on the page until I have received the pageshow event for the main content document since I am going to recurse into the child frames anyway. If I am wrong, someone please correct me.
Well that's what I've learned so far. There should be an Operator release soon that addresses all these issues.