ContainerTiming: cache parent record pointers
When an element is painted inside a container timing hierarchy,
the current implementation has to traverse all the ancestors that
are meaningful for Container Timing using recursive calls to
GetParentContainerRoot().
With this change, for each container timing root record, we cache
a pointer to its ancestor. This way, once we find a container
timing root, all the ancestors notification is faster.
When there are changes that could affect these pointers, we just
invalidate all the records, and lazily regenerate them on next
paint.
This only resolves the traversal from one root to the next. We
would still want to support later a way to make the traversal from
a painted element to its closes container timing root.
I also added a few unit tests focused on the traversal.