Blog Archives

Blog entries related to Mozilla Firefox

Making sense of Firefox startup time

One of the things that we at Mozilla would like to do better at is the amount of time it takes between when you launch Firefox, and when it starts up and is usable.  We’ve been tackling this problem for quite a while, and have already made tremendous improvements.  But we think we can still do better.

Last week, Vlad landed the function timer API, which can be used for producing a log of how much time it takes to execute any given code block.  This is a very useful framework for measuring how much time different things consume at Firefox startup.  On Monday, I, Vlad, Shawn, Johnathan, and Shaver started to look into instrumenting Firefox to produce a useful log of what goes on at Firefox startup, to be able to analyze it to identify the areas that we’re being slow at, in order to focus our attention to improve those pieces of code.

I set up a clone of mozilla-central here to so that we can focus on adding probes to the code without being slowed down by trying to lands things on mozilla-central for now.  Then, we started to add probes like crazy.  The probing work is really finished now, and I think that we’ll spend some time tomorrow to try to analyze the logs, in order to be able to make some sense out of them, and identify the areas where we can attack in order to get the most gain in reducing the startup time.

If you want to create your own startup logs, here are the steps to do that.  Please note that these instructions are for Windows.  Other platforms can be measured similarly, but we’re trying to focus our attention to Windows for now.

  1. Clone the repository.
  2. Your measurement would be most useful if you create a build similar to our release versions of Firefox.  In order to do that, you can grab a copy of the mozconfig file which we use for our release builds.  Make sure that you add ac_add_options –enable-functiontimer so that your build actually includes the probes, and remove the –enable-update-channel and –enable-update-packaging options, to make sure that you don’t mess with the release update channels.
  3. Build firefox, and create an installer:
    make -f build
    make -C objdir package
    make -C objdir installer
  4. Go to objdir/dist/install/sea, you will find a file named something like firefox-3.7a5pre.en-US.win32.installer.exe there.  This is a normal installer.  Use that to install this version of Firefox somewhere on your system.  Please note that you don’t want to replace this with your default Firefox install, since it’s built from a random revision off of mozilla-central, and it’s subject to all the usual warnings when running experimental builds.
  5. Set the MOZ_FT environment variable to the full path of a file which will be used as a log file, for example: C:\Users\ehsan\startup.log.
  6. Execute the installed version of Firefox.  As soon as you see the window on screen, type an address like inside the location bar, press enter, wait for the page to load, and then close Firefox.
  7. Open the log file you specified in step 5.  Try to find the address that you entered in step 6 in that file.  Anything before the first occurence of the address is what happened before Firefox started up and became usable on your system.

Here is a bit of information about the format of the log.  On each line, you will see a pattern like this:

[   123.45] >5)       |nsContentDLF::CreateBlankDocument (line 349)
[   244.43] * (  2)   |        0.50 ms (     0.65 ms total)NS_InitXPCOM3_P (line 480) [Next: timer startup]
[   330.21] < ( 10)           |      3.48 ms (     3.48 ms total)mozJSComponentLoader::Import (line 1444)
(file: resource://gre/modules/XPCOMUtils.js)

Here is what each of these items mean:

  • Time stamp in ms.  This is the time passed since Firefox was started when this message was being added to the log.
  • >, *, or <.  These include three types of logs: function entry, function marker, and function exit, respectively.  The first and last ones are obvious.  The function marker is used for a few very large functions in order to enable us split up the function’s execution time in chunks, so that we can know how much time a function took to execute.
  • Call nesting depth.  It is a number indicating the depth of the call.  It can be used to show whether a function has been called (directly or indirectly) by another one.
  • Function name and line number.  It shows the function in which the log was recorded, and which line in the respective source code it has been defined on.
  • Elapsed time and total time.  These two numbers show how much time has been elapsed inside the function, and how much total time the function has been executed so far.  Note that these numbers are not applicable to function entries.  Also, note that they will be equal on function exit, because the log is generated as the last step inside the function.
  • Marker identifiers.  These are only used for function markers, and usually show what is going to happen next inside the function.
  • Extra information.  Some of the log lines have some extra information associated with them.  For example, the third line in the sample above shows that the module being loaded was XPCOMUtils.js.

Johnath has also adapted a script to generate graphs from the logs, but at this point, we’re thinking that the graphs are misleading, and therefore I’m not going to talk more about this, but check the bug for more information (including how to create such graphs, and some graph samples.)

The next steps probably include finding out where there are gaps in our logs, and try to add probes to cover those areas.  We also need to generate logs for a range of different profiles, including blank and heavy ones.  We need to generate a variety of logs to ensure that we’re not missing any obvious use case of Firefox.  We are also trying to figure out which types of visualizations for this data would be helpful, to be able to better filter/present the generated logs.  Hopefully, we’ll soon have a number of actionable tasks which we can pursue to reduce Firefox startup time to a significant degree.

If you have any ideas how to improve things, or have any logs which we need to see, either comment here or in the bug.

Posted in Blog Tagged with: , , ,

User name autocomplete in Bugzilla

Atul Varma has built an user name autocomplete tool for Bugzilla.  This reminded me that it’s been a long time since I wanted to add this functionality to the Bugzilla Tweaks jetpack.  Last week I added this feature, but I didn’t get the time to blog about it!

Here is how it looks on a a sample bug:

User name autocomplete for the Assignee field

It is also smart enough to handle multiple users for fields which accept it.

User name autocomplete for multiple users

It works on almost everywhere in Bugzilla where you can enter a user name.  Here is the full list for the curious:

  • CC field on bug pages (both when viewing and filing a new bug)
  • Assignee field on bug pages (both when viewing and filing a new bug)
  • Requestee field on attachments (when you request a flag, like review, from someone)
  • User name entry fields on the advanced search page
  • Add user watch field on the preferences page

This is providing the same functionality of Atul’s tool, with two added benefits: it provides the functionality right where you need it, and doesn’t require you to enter your user name and password.

No more memorizing people’s email addresses!  No more asking around for their email addresses!  No more bugzilla error pages telling you that the user name you entered doesn’t exist, or couldn’t be matched exactly!  I hope you like the idea.

The jetpack lives here.  If you have already installed it, you can either rely on Jetpack Prototype’s auto-update feature, or refresh it manually.

Posted in Blog Tagged with: , ,

Jetpack Prototype with trunk support

If you use Firefox nightly builds, and you had the Jetpack Prototype installed, you might have noticed that about two weeks ago, your jetpacks had started to get disabled a short while after you had opened your browser.  This issue was really frustrating, since some of us run jetpacks which are very important in our daily work.

I filed bug 554169 about this issue.  Paul O’Shannessy fixed this, and earlier this week, the Jetpack team released a new version of the Jetpack Prototype which fixes this issue.  You can install it from AMO, and your jetpacks will resume working reliably on nightly builds.

Thanks a lot to Paul, Myk and Atul for making this happen!

Posted in Blog Tagged with: , ,

Help build a tool for checking Private Browsing compatility in extensions

As I wrote before, there are plans in motion to require Private Browsing mode compatibility in Firefox extensions.  In order to make the lives of our reviewers easier, we need a tool to help them review extensions for Private Browsing compatibility.

I’ve laid out the specifics of such a tool in a wiki page.  The plan is detailed, with a lot of links to documentation which would help you do the specific tasks needed for building this tool.  If you’ve ever wanted to get started building an extension, or were waiting for an exciting extension idea which would help Mozilla folks do their job better, this is a very good opportunity.

I’ll be available to help you through the details of building this tool.  Don’t hesitate, jump in!

Posted in Blog Tagged with: , ,

Private Browsing support in Firefox extensions

Firefox 3.5 included the Private Browsing feature for the first time.  As I’ve already written about it, Private Browsing is a mode in which Firefox does not record any data which can reveal the sites and pages that users have visited.  So, whenever you want to browse without leaving a trace on your computer, you put Firefox into the Private Browsing mode, and rely on Firefox to keep its promise and not record any revealing information about your browsing activities.  Now, with extensions introduced into the picture, things are a little bit more complex.

In general, there is no way for Firefox to be able to automatically detect whether extensions are honoring the Private Browsing mode or not.  The same is true in almost every other functionality provided by the browser.  That is why we’ve been using human inspection in reviewing the extensions submitted to AMO, to make sure that extensions do not impair the functionality provided by the browser.

After a lengthy discussion with the AMO editors, we have decided to modify the AMO add-on submission policy to reflect that extensions should honor the Private Browsing mode in order to be listed publicly on AMO.  While most extensions will not need any modifications for supporting Private Browsing (because they don’t record any data revealing users’ browsing activities), there are some which require some changes, and we appreciate the fact that the change cannot happen overnight.  Therefore, we’ve tentatively decided to give a two-month grace period to add-on authors before we actively start to reject extensions incompatible with the Private Browsing mode.

This means that during this grace period, if a reviewer comes across an extension which complies with the submission policy in every respect except for Private Browsing support, one of the following will happen depending on the status of the add-on:

  • For add-ons nominated to become public for the first time, the add-on will be rejected.
  • For updates to existing public add-ons, the update will be approved with the additional note to the author stating the incompatibility of the add-on with Private Browsing, and that it must be fixed in the next version of the add-on.

Please note that while the decision is not yet final, it’s been discussed extensively and is likely to be put into effect soon.

Now, let’s take a moment to talk about what it means for an extension to support the Private Browsing mode.  Basically, extensions need to ensure that no sensitive data is recorded inside the Private Browsing mode.  You would of course get a different answer depending on who you ask about what sensitive data are, but we’re tried to keep a well-defined scope for this term in Firefox.  Basically, we consider data which fits into one of these five categories as sensitive, and refrain from saving such data to disk inside the Private Browsing mode.

  1. The data which includes things like the URL of pages that the user has visited.  Example of such data inside the Firefox includes browsing history, and download history.  Note that in this case, we usually remember the things that the user explicitly asks us to save (like bookmarks), but try to eliminate the visited-ness traces if possible (e.g., we save bookmarks as unvisited bookmarks, which can also be created by adding a bookmark from the Library window and entering a URL manually.)
  2. The domains of websites which the user has visited.  Example of such data inside Firefox includes the content preferences service, which stores preferences (such as the zoom level) for an Internet domain.  We usually refuse to remember such settings inside the Private Browsing mode.
  3. The content of the web pages that the user has visited.  Example of such data inside Firefox includes the network cache.  We usually try not to write the content to disk inside the Private Browsing mode, and in the case of cache, we still keep the in-memory cache around for the duration of the Private Browsing mode.
  4. Other data related to web pages that the user has visited.  Examples of such data inside Firefox includes the cookies, which we only store in memory inside the Private Browsing mode.
  5. Other data which is used to customize the Firefox UI based on what happens inside the Private Browsing mode.  Examples of such data inside Firefox includes the path of the last download directory, which is used to initialize the file picker to that directory for future downloads.  We usually refuse to store this data inside the Private Browsing mode, although we retain the data in memory for the duration of the Private Browsing mode in order to provide a seamless UI functionality to users.

The AMO reviewers will be reviewing each submitted add-on based on the criterion of whether it persists any data belonging to the above categories on disk.  Although after reading the list, supporting Private Browsing mode in an extension might seem overwhelming, it actually isn’t that hard!  Basically, if an extension is using one of the APIs provided by Firefox or Gecko, it’s already safe, because we’ve been careful to make sure that our APIs handle the Private Browsing mode in a graceful manner.  There are several resources for add-on authors who need to know more details about how to support Private Browsing mode in their extensions.  Make sure to keep these resources in mind, and use them:

Happy hacking!

Posted in Blog Tagged with: , ,

Bugzilla made even more awesome

Bugzilla is an essential tool to the working process of Mozilla, and many of us spend a good portion of their day in Bugzilla.  The Bugzilla Tweaks jetpack is an attempt of me and Johnathan to make this process more efficient and productive.  If you have never heard about it, it would be a good idea to first read Johnath’s original post and then my previous one.

Since I published the original enhanced version of the Bugzilla Tweaks jetpack, I have received a lot of positive feedback.  Max Kanat-Alexander event suggested that he likes the UI so much that he’s going to consider using it when the feature is ported to Bugzilla itself.  Several other people have also suggested things that they would like to have in their every day usage of Bugzilla.  I’ve been implementing all of these features and adding even more new features and fixes to the Jetpack.  I thought that the volume of changes has been large enough to deserve another post, so here we go!

Attachment flags with links pointing to the time when the flag was set

Did you ever wonder at which point a flag on an attachment was set, and what the context was?  Wonder no more!  Bugzilla Tweaks now linkifies the attachment flags to point to the exact location where the flag was set.  No matter whether it’s a review, superreview, ui-review, approval, or any other type of flag, merely clicking on the flag name takes you to the exact location where it was set and you can see the exact context right away.

Attachment numbers linkified with names in their tooltip

Now, the attachment numbers generated by Bugzilla Tweaks in history events are links which point to the attachment edit page.  The name of the attachment appears as the tooltip for that link.

Bug dependencies linked to the respective bugs

Bug dependency changes are now linked to their respective bugs.  The title and status of the bug also appears as a tooltip for those links.

URLs appearing as links

Comment numbers appearing as links

We are used to the fact that things like URLs, bug numbers and comment numbers are linked in Bugzilla.  To keep this convention so that Bugzilla Tweaks is as good a citizen in Bugzilla as possible, I’ve made it convert all of those to links as well.

Duplicate markers appearing as history events

We all have seen comments with this content too many times in different bugs:

*** Bug 123456 has been marked as a duplicate of this bug. ***

This is an automatic comment which Bugzilla puts in a bug when another bug is marked as a duplicate of it.  Nearly most of this comment is just noise, and it’s really part of a bug history, not a real comment.  So, Bugzilla Tweaks converts them to history events, so that you don’t confuse them with actual comments.  There is one interesting point here.  Since Bugzilla shows these as comments, they have a comment number and can be linked to by adding #cNN after the bug’s URL, where NN is the number of the comment.  In order to keep those URLs working, I made them point to the history events instead of the comment which no longer exists.

To get the latest version of the Jetpack, you can either install it from this page if you don’t already have it, go to about:jetpack and refresh the installed version of the Jetpack, or simply wait until the Jetpack engine updates it automatically from the server in the background.

Feel free to suggest any other interesting things which you would want in this Jetpack.  So far, every feature that others have requested from me has been implemented, so there is a good chance that yours would be as well!

Posted in Blog Tagged with: , ,

Bugzilla Tweaks enhanced

A while ago, Johnath unleashed the Bugzilla Tweaks jetpack, which implemented Beltzner‘s original idea.  This jetpack adds the information regarding the history of a bug in a right-hand column on bug pages.  I liked it a lot, but I thought that it could be even better, and now I am releasing a tweaked version of that jetpack.

Let’s see what this Jetpack does in action.  The below screenshot shows a change made to a bug while adding a comment.

Changes with a comment

Here, you can see that the status of the bug was changed from NEW to ASSIGNED, and the bug was assigned to dmandelin.

If the change was made without any comment on the bug, an entry is added between the two comments, with an indentation, which hopefully makes it easy for the eye to detect this entry subconciously.

Changes without a comment

Here, you can see that dvander has reviewed a patch, and has marked it r+.  If you want to know exactly when this change has been made, you can just move the mouse pointer over the name of the person who has made the change, and a tooltip shows the time that change was made.

The changes on each bug are shown interleaved with comments as above, with the exception of CC changes.  CC changes are usually not interesting, and they tend to add more clutter than useful information to the history of the bug.  If you want to view the CC history though, you are not out of luck, you can just right-click on the page and choose Show CC History, and all the CC changes will appear.  You can toggle them off by righ-clicking on the page and choosing Hide CC History.

Showing the CC history

CC history displayed

You can see that several CC changes which had occurred between two comments have appeared.  Please note that the CC history visibility setting is not persisted, and each time a bug page is loaded, it will default to hiding the CC history.

Also, in the above screenshot you can see that if the person making the change has commented on the bug as well, their actual name is displayed, otherwise, only the email address will be displayed.

Another feature which is probably useful for drivers and those who triage bugs (among others) is that if a flag has changed during the lifetime of the bug, its name will be converted into a link, and clicking on it will take you to the latest change on the flag.  This both works for real Bugzilla flags and the "pseudo-flags" that we have been using for branch management lately.

Easy access links to the latest change on a flag

To grab it while it’s hot, make sure that you have the Jetpack engine installed.  If you have, when you visit this blog post, you should get a prompt that this page contains a Jetpack.  Just click the Install button and you’re all set.

The source code for this jetpack lives in Johnath’s user repository.  Suggestions, bug reports, and patches appreciated!

Posted in Blog Tagged with: , ,

فایرفاکس ۳٫۵ بتا ۴ فارسی منتشر شد

نسخهٔ فارسی فایرفاکس ۳٫۵ بتا ۴ به همراه ۷۰ نسخهٔ محلی دیگر فایرفاکس ۳٫۵ هفتهٔ گذشته منتشر گردید.  این نسخه که دومین انتشار فایرفاکس فارسی پس از نسخهٔ ۳٫۱ بتا ۳ می‌باشد، هم‌اکنون قابل بارگیری و نصب می‌باشد.  نمایی از این نسخه از فایرفاکس را می‌توانید در زیر مشاهده نمایید.

فایرفاکس ۳٫۵ بتا ۴ فارسی

تیم فارسی‌سازی فایرفاکس در حال تلاش برای انتشار رسمی نسخهٔ فارسی فایرفاکس به همراه نسخهٔ نهایی فایرفاکس ۳٫۵ می‌باشد.  در این مرحله بیش از هر چیز مایل به شنیدن نظرات شما هستیم، پس لطفاً این نسخه از فایرفاکس را بارگیری و نصب نموده و نظر خود را (مخصوصاً در صورتی که به مشکلی برخوردید) در زیر همین نوشته به اطلاع ما برسانید.  به امید انتشار نهایی نسخهٔ رسمی فایرفاکس فارسی!

پیوند به نسخهٔ انگلیسی این نوشته

Posted in Blog Tagged with: ,

Persian Firefox 3.5 Beta 4 released

I finally got to blog about this: the Persian localization of Firefox 3.5 Beta 4 was released last week among the 70 localizations in that release.  This is the second release of the Persian localization team, and the release is currently in Beta.  We are hoping to prepare everything for the first official release of Persian Firefox with the release of Firefox 3.5.

Persian Firefox 3.5 Beta 4

You can download this version from the all-beta page.  As always, all feedback is appreciated.  Please let us know what you think about this release, especially if you encounter any problems while using it.

Link to the Persian version of this post

Posted in Blog Tagged with: , , ,

Show right-click menus on form elements

Ever since bug 404536 has landed, a number of users have been angry.  What that bug did was removing the context menu for HTML form elements.  This change annoyed mainly two classes of users: those who were accustomed to those context menus, and those who used extensions which add menu items to the context menus for form elements (along with other elements, possibly), most notably, Firebug.

Exactly one year later, I am releasing the Form Control Context Menu extension, with the sole purpose of reverting back to the old behavior of showing the context menus for HTML form elements.  So, if you’ve been affected by this in the past, jump up and install this extension.  It can be installed on anything from Firefox 3.0 Beta 4 to the latest trunk builds.

Remember that the extension is currently in sandbox, so you need to log in before installing it.  Make sure to leave your comments if you find the extension useful, because moving it out of the sandbox needs your comment love. 

If you are an extension developer, and your extension adds something to those context menus, and is hence affected by that fix, you can either ask your users to install the Form Control Context Menu extension, or use the below code inside your own extension.  This code needs to run exactly once for each browser window, so you can add it to the load event handler of the XUL window.

let setTargetOriginal = nsContextMenu.prototype.setTarget;
nsContextMenu.prototype.setTarget = function(aNode, aRangeParent, aRangeOffset) {
  setTargetOriginal.apply(this, arguments);
  if (this.isTargetAFormControl(aNode))
    this.shouldDisplay = true;

For the curious, this is exactly the same code used inside the extension.  You can browse the extension’s source code on AMO, but there’s nothing too interesting there.

Posted in Blog Tagged with: , ,