Cuando trato de consulta de elementos secundarios dentro de connectedCallback, puedo obtener una lista de nodos vacío

<script>
  class SomeClass extends HTMLElement {
    constructor() {
      super();
    }

    connectedCallback() {
      // returns empty nodelist
      console.log(this.querySelectorAll('.thing'));
    }

  }

  customElements.define('my-component', SomeClass);
</script>

<my-component>
  <div class="thing"></div>
  <div class="thing"></div>
  <div class="thing"></div>
</my-component>

Cuando trato de consulta de elementos secundarios dentro de connectedCallback, puedo obtener una lista de nodos vacío.

Si me muevo script etiqueta después de <my-component> - se empieza a trabajar:

<my-component>
  <div class="thing"></div>
  <div class="thing"></div>
  <div class="thing"></div>
</my-component>

<script>
  class SomeClass extends HTMLElement {
    constructor() {
      super();
    }

    connectedCallback() {
      // returns empty nodelist
      console.log(this.querySelectorAll('.thing'));
    }

  }

  customElements.define('my-component', SomeClass);
</script>

Hay una devolución de llamada que se activa cuando todos los elementos secundarios están disponibles? (no importa donde <script> fue añadido). ¿Realmente tengo que usar algo como documento.listo o mutación observador? ¿Cuál es la manera más eficiente?