We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Async Javascript Assets

Does anyone know how to make the output from $this->assets->outputJs(); an async javascript?

At the moment, I'm doing this just to get it working:

ob_start();
$this->assets->outputJs("jsHeader");
$contents = ob_get_contents();
ob_end_clean();
echo str_replace('<script ', '<script async ', $contents);

What I would prefer is a more beautiful solution.

You could do this by adding attribute array in addJs().

$this->asset->addJs('path/to/file', null, false, array('async' => 'async'));

Second and third parameter should be adjusted to your needs, this are only the defaults.

Thanks for that. How do I do it if I'm combining more than one javascript file?

Simply call this function for each file you want to insert.

You can add as many as you want and outputJs() prints the html for your site.

OK, so I call the function like this:

        $this->assets
            ->collection('jsHeader')
            ->setTargetPath(__DIR__.'/../../../public/assets/v1/production/final.js')
            ->setTargetUri('assets/v1/production/final.js')
            ->addJs('assets/v1/js/jquery-2.1.1.js', true, null, array('async' => 'async'))
            ->addJs('assets/v1/js/jquery.cookie.js', true, null, array('async' => 'async'))
            ->addJs('assets/v1/js/default.js', true, null, array('async' => 'async'))
            ->join(true)
            ->addFilter(new \Phalcon\Assets\Filters\Jsmin());

But it only generates the following code:

<script type="text/javascript" src="/assets/v1/production/final.js"></script>

That's correct, because you join all files you inserted into the collection to the final.js

I don't know if async works in this case, because the single files are never send to browser, only the joined file.

Maybe I should put a change request in. Thanks for your help.



43.9k
edited Dec '14

Hi,

interesting discussion. @Gareth: did you try without the join statement ? Does this work ?

Sorry for the delay, but yes I just tried it without the join statement, and I get a link to final.js without async.



121
Accepted
answer

Hello,

you can use this :

    $this->assets
        ->collection('main')
        ->setTargetPath('main.js')
        ->setTargetUri('main.js')
        ->addJs('myscript1.js')
        ->addJs('myscript2.js')
        ->setAttributes(array('async' => true))
        ->join(true)
    ;

Refer to the doc' : https://docs.phalcon.io/pt/latest/api/Phalcon_Assets_Collection.html

It'll product :

<script type="text/javascript" src="/main.js" async="1"></script>