@@ -688,27 +688,44 @@ export class NullRenderer extends IncrementalDomRendererImpl {
688688 * proposedKey -> 1c1b, currentPointerKey -> 1d1c1b1a
689689 */
690690export function isMatchingKey (
691- proposedKey : unknown ,
692- currentPointerKey : unknown ,
691+ proposedKey : incrementaldom . Key ,
692+ currentPointerKey : incrementaldom . Key ,
693693) : boolean {
694694 // Using "==" instead of "===" is intentional. SSR serializes attributes
695695 // differently than the type that keys are. For example "0" == 0.
696696 // tslint:disable-next-line:triple-equals
697697 if ( proposedKey == currentPointerKey ) {
698698 return true ;
699699 }
700- // This is always true in Soy-IDOM, but Incremental DOM believes that it may
700+
701+ // This is always false in Soy-IDOM, but Incremental DOM believes that it may
701702 // be null or number.
702703 if (
703- typeof proposedKey === 'string' &&
704- typeof currentPointerKey = == 'string'
704+ typeof proposedKey !== 'string' ||
705+ typeof currentPointerKey ! == 'string'
705706 ) {
706- return (
707- proposedKey . startsWith ( currentPointerKey ) ||
708- currentPointerKey . startsWith ( proposedKey )
709- ) ;
707+ return false ;
708+ }
709+
710+ const proposedKeyLength = proposedKey . length ;
711+ const currentPointerKeyLength = currentPointerKey . length ;
712+ // If these have the same length, then they must be different or we would
713+ // have returned true already. This is a cheap check and xids used for keys
714+ // are usually(?) the same length.
715+ if ( proposedKeyLength === currentPointerKeyLength ) {
716+ return false ;
710717 }
711- return false ;
718+
719+ // See if one string starts with the other. In order for this to be true, the
720+ // shorter string must be a prefix of the longer string.
721+ // Slice is fast (string views) and this is faster than using startsWith even
722+ // with just one comparison in each direction. Perhaps the string views get
723+ // reused with a computed hashcode?
724+ if ( proposedKeyLength > currentPointerKeyLength ) {
725+ return proposedKey . slice ( 0 , currentPointerKeyLength ) === currentPointerKey ;
726+ }
727+
728+ return currentPointerKey . slice ( 0 , proposedKeyLength ) === proposedKey ;
712729}
713730
714731function debugReplacerHashingMessages ( k : unknown , v : unknown ) : unknown {
0 commit comments