Open Bug 465087 Opened 16 years ago Updated 2 years ago

Stop allowing SVGs to (accidentally) create insanely large pattern surfaces that cause performance issues

Categories

(Core :: SVG, defect)

1.9.0 Branch
defect

Tracking

()

People

(Reporter: byteart.studios, Unassigned)

References

Details

(Keywords: perf, Whiteboard: [external-report])

Attachments

(2 files)

User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; pt-BR; rv:1.9.0.3) Gecko/2008092510 Ubuntu/8.04 (hardy) Firefox/3.0.3 Build Identifier: Mozilla/5.0 (X11; U; Linux x86_64; pt-BR; rv:1.9.0.3) Gecko/2008092510 Ubuntu/8.04 (hardy) Firefox/3.0.3 Objects on svg documents using patterns will cause the browser to hog terribly. Often does a noticeable performance hit on the whole system as well. Reproducible: Always Steps to Reproduce: 1.type the following content on a plain text editor (such as notepad, gedit, kwrite): <?xml version="1.0" standalone="no"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg-flat"> <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="xMidYMin slice" version="1.1" > <style> *{ margin: 0; } stop.begin { stop-color:yellow; } stop.end { stop-color:green; } body.invalid stop.end { stop-color:red; } #err { display:none; } body.invalid #err { display:inline; } </style> <defs> <linearGradient id="gradient"> <stop class="begin" offset="0%"/> <stop class="end" offset="100%"/> </linearGradient> <pattern id="pattern" height="100" width="100" > <rect x="0" y="0" width="100" height="100" style="fill:url(#gradient)" /> </pattern> </defs> <rect x="0" y="0" width="100%" height="100%" style="fill:url(#pattern)" /> <g id="blocks"/> <script type="application/x-javascript">//<![CDATA[[ function crash(){ var svgNS = "http://www.w3.org/2000/svg"; var grp = document.getElementById("blocks"); var x,y,rect; for (x = 0; x < 10;x++) for (y = 0;y < 10; y++){ rect = document.createElementNS(svgNS,"rect"); rect.setAttributeNS(null,'width',3.75); rect.setAttributeNS(null,'height',3.75); rect.setAttributeNS(null,'x',96 - (x * 4) ); rect.setAttributeNS(null,'y',(y * 4) + 0.25 ); rect.setAttributeNS(null,'style',"fill:url(#pattern);"); grp.appendChild(rect); } } //crash(); //]]></script> </svg> 2. Save as a file with the .svg extension and open it with firefox. Actual Results: It will hog the browser a bit, despite there only one pattern-filled rectangle. If you uncomment the line that says "//crash();" (create more 100 rectangles) it will hog the browser for a long time. The browser also hogs while scrolling, switching tabs or resizing the window, not only when opening the SVG Expected Results: Display the SVG without a performance hit. Tested with Ubuntu with the following extensions: DOM Inspector 2.0.0 Greasemonkey 0.8.20080405.0 Ubuntu Firefox Modification 0.5 Web Developer 1.1.5 Theme: Default 3.0.3, included with the Ubuntu build of firefox. Using XFCE 4 with compiz and emerald activated for the desktop manager.
Component: General → SVG
Product: Firefox → Core
QA Contact: general → general
Version: unspecified → 1.9.0 Branch
On my Windows XP laptop you don't need to comment out anything; it hangs like crazy with high memory usage and low CPU, this since about 20-25 Jan 2007. On Vista this is no problem, only when you comment out "//crash();" and then it regressed also on another time, in Oct 2007.
Blocks: 384208
OS: Linux → All
Hardware: PC → All
Reporter can you use the attachment facility in bugzilla for testcases please? The fact that Crash is slow has nothing to do with SVG. It uses appendChild and so encounters bug 233463. Use insertBefore instead and insert backwards so that you are always inserting a first child of the <g> rather than the last child. I see no issue on Vista. I'll try on XP later.
Perhaps nothing to do with SVG is a bit strong but there are two issues, only one of which is SVG and the other is bug 233463. In crash, the rectangles are about 4 units big and the pattern is 100 units. So each pattern takes 4000 x 4000 bytes or 15mb and you have 100 patterns. That's a lot of memory. Since the objects are small you should not need to create such a large pattern. Alternatively use objectBoundingBox. I think we tried to do something with filters to detect this sort of problem markup, maybe we can do something similar with patterns too.
Attached image Crash SVg file (deleted) —
Robert, this has absolutely NOTHING to do with appendChild, otherwise it woudn't hog during resize/changing tabs/etc., and it woudn't hog at all on the single-rectangle version. I only put the ECMAscript version for practicity sake. If you don't believe, check out the same image with plain SVG instead of ECMAscript. (rectangle on the back removed to allow you to see the other 100)
The XP hang is possibly due to Bug 367557 but it could be a problem only on this particular 2003 system, because like I said I can't reproduce this on Vista.
~100% cpu until rendering is finished, approx 1 minute. UI slow, but not frozen. so changing to sev=major Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2b1pre) Gecko/20090928 Namoroka/3.6b1pre
Severity: critical → major
Keywords: perf
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.4) Gecko/20100413 Firefox/3.6.4 I still see this on Firefox 3.6.4, although it has improved since 3.6.3.
Attached image Series of simple patterns (deleted) —
I'm seeing this on a current trunk build and on Firefox 4.0b8 with a fairly fast Win 7 machine. The attached test case takes about 2s to render for me, even when reloading or changing tab or switching back and forwards from another app (i.e. it's painting as opposed to parsing that seems to be going slowly). There's nothing particularly special about the test case, remove part of it (any part) and it's still slow, although obviously less so.
(In reply to comment #8) > Created attachment 499995 [details] > Series of simple patterns > > I'm seeing this on a current trunk build and on Firefox 4.0b8 with a fairly > fast Win 7 machine. > > The attached test case takes about 2s to render for me, even when reloading or > changing tab or switching back and forwards from another app (i.e. it's > painting as opposed to parsing that seems to be going slowly). > > There's nothing particularly special about the test case, remove part of it > (any part) and it's still slow, although obviously less so. As pointed out by Robert Longson in bug 544809 comment 19, the problem with the attached test case (attachment 499995 [details]) is the use of width/height="100" with the default patternUnits="objectBoundingBox". This ends up creating a pattern surface 100 times wider and longer than the target surface. So in this case clearly the content is in error. However, it is interesting to note that: a) the attachment from comment 4, attachment 348467 [details], has the same problem. This is perhaps a part of the SVG specification that is somewhat confusing and a scenario that is likely to crop up reasonably often in the wild. b) WebKit and Opera nevertheless render the test cases (especially attachment 499995 [details]) quite quickly. Hence it may be worth considering doing some clipping so we don't appear to hang when such content is encountered.
In addition to clipping (e.g. clipping the pattern surface to the size of the target content) comment 3 also mentions the possibility of trying to detect problem markup.
Severity: major → normal
Status: UNCONFIRMED → NEW
Ever confirmed: true
Summary: SVG patterns are slow → SVG patterns with large/incorrect dimensions are very slow
Blocks: 591894
Whiteboard: [external-report]
Summary: SVG patterns with large/incorrect dimensions are very slow → Stop allowing SVGs to (accidentally) create insanely large pattern surfaces that cause performance issues
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: