annevk/webvtt — pull request #7 by stevendesu (2014-12-31 22:00:26+00:00)
Title: Slight speed and size improvements

I wish to incorporate your class into a project that I am building which has **a lot** of JavaScript running and will be parsing WebVTT files every 10 seconds, so improving size and performance were very important. I went ahead and spent about 2 hours making all the easy improvements I could, and littering the code with comments to explain my changes.

There are two large areas where improvements can still be made that would require more significant refactoring:

1. The `nextToken()` function is looping over every single character in the string and, for each character, running through a comparator waterfall. If the current stage is, say, "start tag annotation" then **once per letter** it first checks to see if the current state is equal to "data", then "tag", then "start tag class", then finally (after 3 failed comparisons) it checks for "start tag annotation" before ever comparing the character itself to any possible values. A better design may be something like:

```js
while( pos < line.length ) {
if( state == "data" ) {
while( true ) {
if( ... ) {
state = "tag"
break
}
}
}
if( state == "tag" ) {
...
}
}
```

The idea here being that you only check the state (break out of the infinite loop into the outer loop) if the state changes. If the state doesn't change, you remain inside the inner loop.

2. Running profilers suggests a lot of time is spent in the `WebVTTCueTextParser.parse()` function (excluding time spent in `nextToken()`). Now I did make a change that allowed this function to calculate its own timestamps without spinning up an instance of `WebVTTCueTimingsAndSettingsParser`, so this could have negatively impacted performance of this function while positively affecting overall performance. However I feel the tree structure might not be very efficiently implemented. I haven't looked into it much.

One other change that I considered, but did not bother benchmarking, was changing the following:

```js
skip(SPACE)
// 6-8
if(line[pos] != "-") {
err("No valid timestamp separator found.")
return
}
pos++
if(line[pos] != "-") {
err("No valid timestamp separator found.")
return
}
pos++
if(line[pos] != ">") {
err("No valid timestamp separator found.")
return
}
pos++
if(NOSPACE.test(line[pos])) {
err("'-->' not separated from timestamp by whitespace.")
}
skip(SPACE)
```

into four lines:

```js
if( /[\u0020\t\f]+-->[\u0020\t\f]+/.test( line.substr(pos) ) )
err("No valid timestamp separator found.")
pos = line.indexOf( '>', pos )
skip(SPACE)
```

I don't know if the `substr()` operation would be slow enough to make performance worse than your method, but it's definitely less code.