Surfin’ Safari

Another Acid 3 Fix: Ranges and Document Mutation

Posted by Darin Adler on Saturday, March 15th, 2008 at 9:27 am

You probably know that the Acid 3 score for nightly builds of WebKit was 90/100 last week. Today it’s up to 91/100 because I fixed our handling of DOM ranges under document mutation.

In older versions of WebKit, if you removed the node at one end of a DOM range from the document, the range would end up with one endpoint in the document and another endpoint outside the document. Ranges aren’t supposed to work that way. Instead, when you modify the document the range is supposed to get “fixed up” so that both endpoints are still in the document.

That’s fixed now and so Acid 3 test 13 now passes. See bug 11997 if you want to know more of the details.

The Acid 3 Test

Posted by Dave Hyatt on Thursday, March 6th, 2008 at 12:29 pm

The Acid 3 Test has been officially released. The test has been in development for some time, with much of that development happening in the open.

The Acid 3 test is far more complex than the Acid 2 test. It covers a wider range of standards and consists of many more individual tests. Browsers have to render a sequence of boxes that display dynamically in a stairstep pattern. For every cluster of tests passed successfully, the boxes will fill in with a color, which signifies that all of the tests covered by that block have passed.

If you run Acid 3 on the shipping versions of current browsers (Firefox 2, Safari 3, Opera 9, IE7), you’ll see that they all score quite low. For example Safari 3 scores a 39/100. This percentage score is a bit misleading however. The situation with all four browser engines really isn’t that bad.

You can think of the Acid 3 test as consisting of 100 individual test suites. In order for a browser engine to claim one of these precious 100 points, it has to pass a whole battery of tests around a specific standard. In other words it’s like the browser is being asked to take 100 separate exams and score an A+ on each test in order to get any credit at all.

The reality is that all of the browsers are doing much better than their scores would have you believe, since the engines are often passing a majority of the subtests and experiencing minor failures that cost them the point for that section.

Shipping Safari scores a 39/100 with some significant rendering errors. We’ve been working hard since the test surfaced and are pleased to report that we’ve entered the “A” range on the test with a score of 90/100.

So what did we fix to gain so many points?

Bug 17064 has all the details, but here are the highlights.

Support for CSS3 Selectors
We added support for all of the remaining CSS3 selectors. These include selectors like nth-child, nth-of-type, last-child, last-of-type, etc. These selectors were already implemented in KHTML, and the KHTML developers had even kindly provided patches for us in the relevant WebKit bugs. Therefore it was a simple matter of taking those patches, updating them to the WebKit codebase, and then merging them in. A big thanks to the KHTML developers for their hard work in this area.

Parsing Bugs
WebKit had a number of minor parsing bugs that Acid 3 targeted. The boxes did not render properly because of an obscure parsing bug that the test exploited (thanks, Hixie). In addition a number of other parsing bugs kept us from completely passing individual tests. We have updated our parser to be much closer to the HTML5-specified parsing rules.

WebKit has also never parsed DOCTYPEs before. I re-wrote WebKit’s DOCTYPE parsing to match the HTML5 specification, and so now if you put a DOCTYPE into your page it will be present in the DOM. In addition many bugs centered around proper mode resolution (quirks vs. strict) have now been fixed. You can document.write a DOCTYPE for example in a new document and have the correct mode be selected.

SVG
Acid3 has many SVG tests. We’ve been hard at work making these tests pass. In particular SVG font support and other aspects of the SVG DOM have been tested. Many of the remaining 10 points are SVG failures. We’ll be working on SVG animation in order to pass the last few SVG tests.

DOM
Acid3 tests a lot of DOM level 2 features, like traversal and ranges. It particularly focuses on the “liveness” of objects, e.g., making sure everything updates properly when you dynamically change a document by adding/removing nodes. Most of our failures in this area had to do with not behaving properly in the presence of these dynamic changes (even though we tended to pass the more static tests).

Now that we’re closing in on 100%, we’ll be blogging about each fix as it happens, so that you can follow our progress from the blog.

The Star Seven Hack

Posted by Dave Hyatt on Monday, February 11th, 2008 at 2:09 pm

For those of you using the star seven CSS hack to target current or older versions of WebKit, this parsing bug has been closed in the latest WebKit nightlies. Acid3 specifically tests for this, so any browser that wants to be compliant with Acid3 will have to fix this CSS parsing bug.

For more information about this hack, see:

http://diveintomark.org/projects/csshacks/star7.html

querySelector and querySelectorAll

Posted by David Smith on Thursday, February 7th, 2008 at 2:41 pm

A familiar and unpleasant sight in web applications is fragile code traversing the DOM to get to certain elements or collections of elements. Chains of getElementById("something").parent.parent are all too common, hurting both readability and flexibility. As a result, many javascript libraries have implemented functions to use the powerful CSS selector system to look up DOM nodes.

Continuing the trend of standardizing and speeding up commonly used functionality from these libraries, WebKit now has support for the new W3C Selectors API, which consists of the querySelector and querySelectorAll methods. Hopefully libraries will begin to adopt this new functionality to provide performance improvements while remaining compatible with older browsers.

Some examples of how it could be used:

  /*
   * Get all the elements with class "hot" (duplicating getElementsByClassName)
   * A common use for this is as a toggle;
   * for example, a search feature might tag results with a class
   */
  document.querySelectorAll(".hot");

  /*
   * Get the currently hovered element
   */
  document.querySelector(":hover");

  /*
   * Get every other element in the <li> with id "large"
   * This is mostly useful for doing "zebra stripe" alternating rows.
   * Once CSS3 becomes more widespread, doing this directly via CSS will be more practical
   */
  document.querySelectorAll("#large:nth-child(even)");

What would a new API like this be without benchmarks? The mootools project has conveniently created a wonderful test and benchmark suite for just this sort of functionality. A version of it that has been modified to test querySelectorAll as well as three common javascript libraries is available at http://webkit.org/perf/slickspeed/. Please note that many of the tests will only work in a build of WebKit from February 7th or later.

Versioning, Compatibility and Standards

Posted by Maciej Stachowiak on Tuesday, January 22nd, 2008 at 11:51 pm

The new IE8 version targeting switch, announced on IEBlog and A List Apart, has been the talk of the web. Some web standards experts, like Eric Meyer and Jeffrey Zeldman see the switch in a positive light. Others, including Dean Edwards, Robert O’Callahan and Anne van Kesteren think the proposal is a bad idea.

We don’t talk much about what other browsers are doing on this blog. While we’re happy to collaborate on web standards and testing, and sometimes share a little friendly rivalry, we try to keep our focus on making the best Web browser engine we can, not on the competition. So we’re not going to give in-depth commentary on the IE team’s decision. Straddling compatibility and Web standards is a tough job requiring tough choices.

However, some have asked if other browser engines, including WebKit, would adopt a similar version switch. For example, the original announcement asks, “I, for one, hope other browser vendors join Microsoft in implementing this functionality.” I can’t make any definitive statement for all time, but such an approach does not seem like a good idea to us currently. Why, you may ask? There are a few reasons.

Mode Switches in WebKit

WebKit, like most browser engines, has a quirks mode that is triggered by certain old HTML doctypes, or lack of a doctype declaration in text/html. Documents with newer or unknown doctypes, or sent as XML, are processed in standards mode. Like Mozilla and Opera, we apply only a limited set of nonstandard behaviors in quirks mode, and otherwise fix bugs across both modes, if they do not have a specific significant impact on Web compatibility. This is in contrast to the IE approach of completely freezing old behavior in quirks mode.

We actually have a few modes besides that. A handful of doctypes trigger what is called “almost standards mode”, which is standards mode with one minor deviation, mainly affecting how images lay out in table cells; this is copied from Mozilla. In addition, we have a few rendering and DOM differences between documents served with an XML MIME type and those served with an HTML MIME type, but we are trying to reduce these over time. And finally, we have a Dashboard compatibility mode that has a few extra quirks beyond quirks mode, to handle Dashboard widgets that were coded to depend on old WebKit bugs.

Maintainability

As you can see, this is quite a few modes already. Having lots of modes raises a number of challenges for maintaining the engine.

First, the more different modes there are, the harder it is to fully test the engine. We have an aggressive approach to automated testing, and our layout tests often find critical problems before they are shipped or even checked in. Having more modes means many things need to be tested in multiple modes. So that’s more tests, more time for developers to run the test suite, and more chances of missing code coverage, especially when different modes interact.

Second, implementing mode switches hurts hackability of the code. Hackability is one of our core project goals. It’s part of the reason new contributors can dive in quickly, and enables us to rapidly develop new features, while improving performance, stability, and security.

There’s two plausible ways to add more modes. One is to make all engine changes conditional on a version flag. Another is to have a whole second copy of the layout code. Either would be a huge additional barrier to entry for developers, and would make it harder to maintain the code.

So, bottom line, we’d like to see fewer modes, not more.

Mobile-Readiness

In addition to maintainability, an important feature of the WebKit engine is the ease with which it is deployed on limited-capability devices such as mobile phones. Some of the more prominent examples include Nokia’s S60 Browser, Apple’s iPhone and iPod touch, and Google’s Android platform. These and other products all include a full-powered version of WebKit, no compromises.

However, having more mode switches cuts against this. The extra code (possibly whole extra copies of the engine, at the very least a whole lot of extra if statements) would be a significant burden on mobile devices. It’s not very well aligned with our mission of staying lean and mean.

Commitment to Standards and Interoperability

Yet another reason we feel more mode switches are not a good idea for WebKit is our commitment to Web standards, and to interoperability with other browsers. We strongly believe that Web standards are the path forward for interoperability, and we work closely with Web standards groups and other browser vendors to align behavior.

Part of this commitment is delivering standards-compliant behavior out of the box. We don’t ask you to set a special preference, or to add extra markup to your web page, or anything else beyond the long established standards mode switch. That means WebKit can truly pass standards-based tests like Acid2 and someday the forthcoming Acid3, and we’ll work more like other standards-based browsers over time. In general, web developers are happy to get automatic ever-advancing standards support from our engine, and indeed our support for advanced CSS3 properties has unleashed a wave of creativity in iPhone web apps.

Reducing Engine Fragmentation

Another key reason to avoid more modes is to reduce the number of different compatibility profiles that web content authors have to deal with. With many different vendors shipping WebKit-based products, we rely a lot on the fact that uptake of WebKit-based browsers is really fast. Already many web developers are focusing primarily on Safari 3 and not Safari 2, because in only a few months the majority of users have upgraded.

But locking in compatibility would mean you have to think about the compatibility profiles of old browsers a lot longer. And no one wants to think about the state of the engine in Safari 2 - I sure don’t! We made thousands of fixes and improvements and those fixes deserve to stick.

We Don’t Really Need It

Finally, while we sympathize with the tough road that the IE team has to travel to achieve a high degree of standards compliance, we haven’t really experienced the same problem. The IE team has mentioned severe negative feedback on the IE7 release, due to sites expecting standards behavior from most browsers, but IE6 bugs from IE.

But WebKit already has a high degree of standards compliance. And we are not in the enviable but tough position of being the most widely used browser. The fixes we do for standards compliance rarely cause widespread destruction, and when they do, it’s often a sign that the standards themselves may need revision. We do not get complaints from web content authors about their sites breaking, on the contrary we get a lot of praise for each version of the engine handling web sites better.

Conclusion

So, in conclusion, we don’t see a great need to implement version targeting in Safari. We think maintaining multiple versions of the engine would have many downsides for us and little upside. The IE team is, of course, under different constraints and free to make their own choices.

WebKit gets Native getElementsByClassName

Posted by David Smith on Friday, December 21st, 2007 at 11:43 pm

getElementsByClassName is one of the more common functions requested by JavaScript programmers (and added by JavaScript libraries); it works along the same lines as getElementsByTagName and getElementById in looking up elements of a web page by their properties. In fact, it’s so common that in the new in-progress HTML5 specification it’s been added to the official DOM API. Last week WebKit joined upcoming versions of Firefox and Opera in supporting this new feature.

The advantages of a native implementation are clear:

  • No additional JavaScript library files required
  • Clearly specified and consistent behavior
  • Blindingly fast

How fast? Let’s have a look at WebKit’s shiny new implementation. For testing purposes I wrote a simple benchmark allowing comparison between three different methods for getting elements by their class names. The first is the new native getElementsByClassName, and the last two are both from prototype.js; one uses XPath, and the other is a straight JavaScript/DOM implementation.

Graph of getElementsByClassName benchmark results

The results speak for themselves. Web applications that do a lot of class lookups should see noticeable speed improvements when run with any of the native implementations, and existing JavaScript libraries can fill in for older or less advanced browsers. John Resig has run a different benchmark of the same functionality in Firefox 3 and observed a similar native vs. JavaScript/DOM speedup ratio.

Testing Methodology:
Tests were run three times, then averaged. The page was reloaded between each run. The browser used was Safari 3 with WebKit r28911. The hardware was a 2GHz Apple MacBook with 3GB of RAM running Mac OS X 10.5.1. The XPath and JS/DOM functions are from Prototype 1.5.1.

Announcing SunSpider 0.9

Posted by Maciej Stachowiak on Tuesday, December 18th, 2007 at 2:06 pm

A New JavaScript Benchmark From the WebKit Team

Here in WebKit-land, we strive for great performance and we love to make things faster. When doing performance work, it’s critical to be able to measure how fast you are at any given time and track changes. And it’s important to make sure your metric reflects realistic use cases. None of the existing JavaScript benchmarks were exactly suited to our needs (more on that below), so we decided to make our own.

We’re widely announcing this benchmark today because we’d like to share with other browser-hosted and standalone JavaScript engines. And we’d like to have input from JavaScript experts on the usefulness and validity of the tests. In that spirit of cooperation, we’re not going to post competitive numbers or even comparisons to older Safari/WebKit versions for now (although I can tell you that the shipping version of Safari 3 is not the fastest JS engine we tested).

Try It Out!

But people like playing with these benchmarks. So I’m sure a lot of you would like to try your luck and test your browser. If you’d like to post your results in the comments, please mention what browser, what version, and what hardware and OS you’re running on. Make sure to quit extraneous apps and avoid jiggling your mouse for the minute or two that it runs. Have fun!

The Gory Details

There are a lot of JavaScript benchmarks out there already: Celtic Kane’s JavaScript speed test, the JavaScript processing test from iBench, Jason Orendorff’s JavaScript speed tests, John Resig’s tests, and others. But none of these were quite what we needed to measure improve real-world JavaScript performance.

So we made our own. Why bother? Well, we think our benchmark has a combination of useful properties that we didn’t see in any existing test:

  • It’s based on real code that does interesting things; both things that the web apps of today are doing, and more advanced code of the sorts we can expect as web apps become more advanced. Very few of the tests could be classed as microbenchmarks.
  • It’s balanced between different aspects of the JavaScript language — not dominated by just a small handful of different things. In fact, we collected test cases from all over the web, including from other benchmarks. But at the same time, we avoided DOM tests and stuck to the core JavaScript language itself.
  • It’s super easy to run in the browser or from the command line, so you can test both pure engine performance, and the results you actually get in the browser.
  • We included statistical analysis so you can see how stable the results you’re getting really are.

Incidentally, we’ve been doing a lot of work on JavaScript performance lately. If you’re interested in helping out, stop by the webkit-dev@webkit.org mailing list, or the #webkit IRC channel on chat.freenode.net and say hi. Our engine is highly hackable so it’s easier than you think to get started.

New WebKit Reviewer

Posted by Brady Eidson on Wednesday, December 12th, 2007 at 10:00 am

I’m happy to announce that Holger Freyther is now a WebKit reviewer. Since arriving on the WebKit scene in early ‘07 he has proven himself to be a consistently solid contributer. After valuable work cleaning up the GTK+/Qt build systems and the GTK+ public API he continues to help fill in other missing pieces of the GTK+ and Qt ports. All the while he’s shown great judgement and collaboration with the WebKit community as a whole. It’s no wonder the nomination for him to become a reviewer - the first through our new committer and reviewer policy - was quickly confirmed.

Please join me in congratulating Holger!

Web Inspector Update

Posted by Adam Roben on Thursday, December 6th, 2007 at 12:55 pm

Inspect Element context menuAs Maciej said, web developer tools are a big new feature of WebKit 3. Since we first introduced the new Web Inspector back in June, Tim Hatcher (xenon in #webkit) has been spearheading the effort to make the Web Inspector an even better tool for web developers, and I wanted to give an update on the progress we’ve made so far. If you’ve never used the Inspector before, you should follow the instructions to enable the Web Inspector on the WebKit wiki.

New Features

Inline CSS Editing
Web Inspector Inline CSS EditingThis is the biggest new feature of the Inspector. You can now edit CSS styles simply by double-clicking them in the Inspector’s Styles sidebar. This is really handy for tweaking the look of your site live in the browser.
Support for Downloadable Fonts
When you visit a site that uses downloadable fonts via @font-face rules, the Inspector will show you all the fonts downloaded by WebKit in the Resources sidebar. Each font has a small icon preview in the sidebar and a more complete preview when you select it.
Web Inspector Downloadable Fonts Support
Database Browser
WebKit now supports the HTML5 SQL storage API, and the Inspector has full support for this new feature. You can execute SQL queries right in the Inspector and see the results live, or browse through all the databases and tables a website uses.
Web Inspector's Database Browser
Support for New CSS Properties
The Inspector shows the new CSS transform and animation properties in its Styles sidebar. You can even trigger animations on the fly by using the Inspector’s inline CSS editing!
Multi-Platform Support
The Inspector was designed from the beginning to be easily implementable on many platforms, and has worked on both Mac OS X and Microsoft Windows from the very beginning. Recently, Holger Freyther has stepped up and implemented the Web Inspector on Qt.
Usability Improvements
In addition to all these big features, we’ve spent some time fixing some of the little things that make the Inspector that much easier to use. The list of usability improvements includes resizable sidebars, resizable search area, size-to-fit DOM breadcrumbs, and better selection and copying behavior. One of my favorite features in this area is that when you Copy while a node is selected in the DOM view, the serialized source for that node and its children are put on the clipboard. This makes it incredibly easy to take a portion of a live website (complete with any modifications that have been made to the DOM) and modify it in a text editor.

You can try out all these new features today by running a nightly WebKit build.

Future Work

There’s still a lot of work to be done on the Inspector, and we’d love to have your help. Most of the Web Inspector is written in HTML, JavaScript, and CSS, so it’s easy to get started making changes and improvements. There are some really interesting tasks in the list of Web Inspector bugs and enhancements, and the WebKit contributors in the #webkit chat room are pretty much always available to provide help and advice.

Welcome to Planet WebKit

Posted by Adam Roben on Monday, December 3rd, 2007 at 11:18 pm

Surfin’ Safari has always been a great place to get information about WebKit, from descriptions of the many new features being added to technical discussions of engine internals to announcements of WebKit being used in entirely new places. But the web is a big place, and we want to make it easier to find the many great articles WebKit contributors are writing every day on their own blogs. So we’ve recently set up Planet WebKit, your one-stop-shop for information about WebKit development and its growing uses in the world, straight from the developers’ mouths. Special thanks to Matt Lilek and Tim Hatcher for coming up with a great look for Planet WebKit. Bookmark the page or subscribe to the feed and start reading!