Safari unreasonably slow rendering SVG files - javascript

I have an application where I load different SVG files into an object and perform operations on them using JS. The code is all correct and works perfectly across all latest browsers, even IE11, with the single exception of Safari (including Safari on iOS and wkhtmltopdf).
When the application runs in Safari, performance on the SVG objects is abysmal. This includes initial page loading and changing the data attribute of the host <object>. Basic tasks like using setAttribute while looping over SVG elements can hang the application for minutes.
The application is entirely dependent on SVG interactivity so this is a major issue for me.
I'm pretty sure yet this is something related to the content of the SVG files. I've been playing around with simplifying the files to see if a particular type of SVG feature is to blame (patterns, styles, embedded images, <use> elements, etc) and while things do get faster as things like images are ripped out I haven't found any primary culprit yet and I can't really remove features without breaking the app anyway.
One odd thing I noticed is that changing from a "simple" SVG to a complex one is faster than the other way around. It seems like Safari has trouble cleaning up the complex object when it's not needed.
I've set up a demo page at the following link:
http://www.flooradvisor.com.au/shapes/backend/tests/webkit-svg-change-src.html
If anyone can help me understand why Safari hates my SVG files and what I can do about it that would be hugely appreciated.

Related

Slow javascript execution in Iframe only in IE

The Problem:
I've developed a web application. It is embedded in a site with the help of an iFrame.
If I run the application as a stand alone (IE9) on say: www.example.com/webapp it loads in about ten seconds flat (it's a rather large application). Chrome and FF are much faster.
If It's embedded in an iFrame however, IE completely loses it with javascript execution times up to 40-60 seconds until the app is done loading. Once the application is loaded however there are no issues and it runs flawlessly.
Recap: Stand alone: OK, in iFrame: Not OK.
In the web application a few xml's are loaded, specifically a very large one which is about 8mb. The xml's are parsed and content is created using KnockoutJS. However this is not very relevant as I've narrowed it down to the XML parsing which is done with jQuery.
Stand alone the parsing takes about 10 seconds in IE9. Embedded it's around 40-60. I've consoled out the status logs and timestamps and I can physically see the javascript is running incredibly slow embedded. Every trace-out takes 4-6 times as long which corresponds with the increased overall load time.
FireFox and Chrome are immune and show no slowdown or so little slowdown that it's unnoticeable.
I've tried iFrame and Object embedding. Same results.
The question
Do you know why simple javascript execution (XML Parsing when the xml IS loaded and in memory), would take 4-6 times longer when embedded in an iframe than in stand alone?
Bonus info
I'm not talking about page load here. Everything loads fine. Even the host page. This is not yet another page is hanging until iframe is ready problem. the problem is the execution inside the iframe being slow. I've tried embedding on same domain, foreign domain, internal, external. Same problem everywhere. As soon as I iframe the damn thing, load performance goes to hell. Once it's loaded, everything is fine and everything runs very well.
PS: I hope the bolding of what i find is keywords is OK. It's supposed to be a help, not be annoying. I personally have problems focusing on large amounts of text.
**
Performance Monitor while it's loading:
IE9**
http://imgur.com/iYdMuPe
I found that setting element size with jQuery .height(n) and .width(n) can be extremly slow, you may use .css("width",x) and .css("height",x) instead.
First, hit F-12 and confirm the document mode is the same in both instances. If not, change the document mode of the outer frame to match..
If they are already the same, try instead to load the iFrame script dynamically after the outer page is complete. Older versions of IE handle resource allocation oddly and could be part of the problem.
Granted, not the answer to your question but bringing 8 MB of XML to the client is quite inefficient. Can any of this be stripped out or entirely processed server side?
Lastly, IE is slow to move and add DOM elements (compared to Chrome). Your best bet is to add them all at once. So if you are updating the UI as you parse the XML (instead of all at once after parsing), that will slow you down considerably.
Similar to what #ern0 said, if you are manipulating height and width in your script and are experiencing slowness then changing from using jQuery's .height() and .width() methods to vanilla JS could realize a significant performance improvement.
Getters
Here is a performance test for reading the element's current height. It shows that the vanilla JS property offsetHeight is significantly faster than the .height(), .css("height") and .style.height techniques.
The difference is so significant that it is not even a competition.
Setters
Here is a performance test for setting the element's current height. It shows that the vanilla JS property .style.height is significantly faster* than the .height(), and .css("height") methods.
Again, the difference is so significant that it is not even a competition.
Summary
The .style.height property excels in both getting and setting by an incredible margin, as compared to the jQuery methods. The read-only offsetHeight property is significantly faster than the style.height property for getting, but (as it is read-only) it cannot be used for setting the height. As such, it may be easier to just change the code to use .style.height, if it still achieves the desired effect.
The height and width properties and methods should be pretty much the same. If you want to add performance benchmarks for them too, that is fine, but you should get the same outcome, with the width properties and methods finishing in the same place as their corresponding height counterparts.
Apparently IE had a serious problem with getting attributes of an xml node through jQuery in a deeply nested loop. Changing this to pure JS reduced load time to about 15 seconds. Still not great, but much, much better!

Frames generated in rendering and painting an HTML page

How do I get the timings and layouts of different frames generated while painting an HTML page which involves javascript manipulations and CSS3 animations by a webkit browser?
You can get the page layout by dumpRenderTree() provided by webkit, if that's what you wanted. Regarding the timing data, as far as I know you may need to build the webkit engine to enable it then you can get the timing data regarding rendering, network, Javascript, etc. - at least this is feasible for Android webkit.

Printable rotation in IE8

How do I print rotated content (divs) in IE8? The DXImageTranform filter options do not appear to be printable.
http://msdn.microsoft.com/en-us/library/ms533014(v=vs.85)
Just to put this into context. I'm writing a pure dom-based canvas library called simpleCanvas. I am desperately trying to offer rotation of text, rectangles and images in IE8 without using a VML fallback, because it's ugly and slow, and error prone. A VML fallback is on my todo list as I concede that it's the only way I know how to do this in IE8 without additional tools. I'm hoping that there is some trick that I'm missing that doesn't come with a third party or server side requirement. If you have found it, a bounty is coming your way.
This is a massive stretch but is the best idea I could come up with:
Explorer Canvas - https://code.google.com/p/explorercanvas/ - Implements the canvas in IE8 by abusing VML.
HTML2Canvas - http://html2canvas.hertzen.com/ - Can render your document onto a canvas, which can then be rotated.
Failing that, I suspect your only option is going to be to generate a rotated document server-side and give that to the client for printing.
Edit: One other last ditch would be to handle the printing via Silverlight, embedding the page in a browsercontrol inside silverlight (yuck), rotating that and printing the result via SL.
Really grasping at straws here though for anything client side in a legacy browser.
According to Printing webpage with rotated text in Internet Explorer 9 you need to use -ms-transform too. Be sure to read the EDIT too as there is something buggy.
Would https://developers.google.com/chrome/chrome-frame/ be acceptable? I'm guessing not if its a LOB application, but it'd give you the features you need without taking the user out of IE8 in the strictest sense. Just another avenue to explore.
https://code.google.com/p/jqueryrotate/ - This will rotate images, it uses VML to do it in IE8. The caveat is that any text you wanted to rotate would have to be as an image.
I've never used it and it would be some work but have you tried svgweb? Basically it uses SVG if the browser supports it and Flash if it doesn't. Because it's a flash object you can print it like an image once rendered.
Here's a few more demos of it: svgweb Demos

Make your site compatible with IE - Where to start?

So I'm nearly finished with the website I had to make for my school's prom. Now, I just checked it in Internet Explorer and, well, it's hopeless. Elements aren't where they're supposed to be, most of the JavaScript/jQuery doesn't work at all. I am clueless where to start to make my site compatible with Internet Explorer. Whats the best way to make your site compatible with IE?
The main cross browser step is DOCTYPE Declaration. It is an instruction to the web browser about what version of HTML the page is written in.
It's going to be murder to fix what's already broken... you really needed to start off on the right foot, as it is you may need to re-write large chunks of your site in order to get things working again.
Going back? Well the easiest thing is going to be to start a fresh layout (using the following pointers) and then move your site into the new framework. Depending on the scale of your site this is no small task. Your alternative is one-by-one code debugging, with maybe firebug light
Going forward, how do you build a site that works more evenly across the board?
1 Use a reset CSS boilerplate
I like the html5 one at http://html5reset.org/. These apply layers of CSS to get each browser looking the same to start with (your CSS then gives it the style you want). Note they DON'T address the variety of ways browsers calculate things - borders being part of the width or not (firefox/ie difference)
2 Use a JS library
Or write your own, but be aware of all the differences between the browsers don't just code for the one you're using. Build some JS tests for the library that you can run in any browser to make sure that the library performs as expected, then deal with any site oddities after that. There's too many JS libraries to make a recommend but Prototype.js and jQuery are a popular two.
well it's known that there are differences between browsers. The way browsers render CSS code is also different. You should check parts and see how or if it works as you want. :) There is no one-to-all solution. The experience will let you know what works and what not. But to start you could isolate what is not working in IE (javascript code) and then see what alternatives you have. As for the appearance, there is the option of having separate CSS files especially for IE. However, often there is a technique(a different way to implement the same appearance) that lets you create the appearance you want without multiple versions of code.

Chrome and SVG (Raphael), trouble with drawing "off-screen"

I'm working on a prototype system which will act as a proof of concept that an existing system can be made a lot more interactive.
It basically emulates our main software package but over the internet using JSONP requests to update a load of images and Raphael vectors to make it look like everything's running.
I'm having trouble on Chrome however with Raphael not drawing vectors "off-screen". What I mean by "off-screen" is that the main app runs through an iframe as it relies on cross-domain long poll comet through AJAX to get communicate back and forth. Below is an image demonstrating what I mean.
Here I've scrolled a long a little bit in the iframe to look at the bits "offscreen" and you can hopefully see that the grey arrows aren't rendered. I've used Chrome's developer tools to highlight over the SVN tag, showing that it's only given 450px by 810px to the SVG tag, which is the same size allocated for the iframe.
It's worth pointing out that it renders fine in Firefox. Any ideas?
I've had a similar problem and found a bug report for the WebKit project that seemed related:
https://bugs.webkit.org/show_bug.cgi?id=64823
According to the comments, it's a bug in the rendering engine and there's no workaround aside from losing the iframe or resorting to other means of scrolling the SVG viewport (like moving all the elements within the SVG element).
On the upside, version 16.0.912.21 has been released to the beta channel today and it seems that the bug has been fixed. I've also checked the latest chromium build (17.something) and the bug hasn't resurfaced. I'm guessing the fix should find its way into the stable channel in a couple of weeks.

Categories

Resources