Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue should not cause execution of content within <noscript> tags #9669

Open
OwenMelbz opened this issue Mar 10, 2019 · 10 comments
Open

Vue should not cause execution of content within <noscript> tags #9669

OwenMelbz opened this issue Mar 10, 2019 · 10 comments

Comments

@OwenMelbz
Copy link

OwenMelbz commented Mar 10, 2019

Version

2.6.8

Reproduction link

https://jsfiddle.net/ncwuvekm/1/

Steps to reproduce

Check the "network" tab.

You can see that Vue causes a request to the content within the <noscript>

What is expected?

Vue should not cause execution of <noscript>content

What is actually happening?

Vue causes requests to elements within <noscript>


It's typical when websites are using Vue to supplement UI and a common pattern is to wrap the site with an id="app"

However, this introduces a problem when people are using <noscript> in various areas of the site that are not within Vue components as Vue will execute it regardless.

A use case example would be using a lazy loading library with a <noscript> fallback.

<img src="thumbnail.jpg" data-src="hi-resolution.jpg" />
<noscript><img src="hi-resolution.jpg" /></noscript>

Vue will cause the hi-resolution.jpg image to download even though it's within the <noscript>

For anybody experiencing this issue, a hack is to add v-if="false" to your <noscript> to prevent the element from rendering e.g.<noscript v-if="false">

@posva
Copy link
Member

posva commented Mar 10, 2019

It's not that Vue processes the content, the browser seems to fire the requests with noscript tags added dynamically (which I wonder if should even be allowed)

const noscript = document.createElement('noscript')
const img = document.createElement('img')
img.setAttribute('src', "https://images.unsplash.com/photo-1552084007-76f5feb8d22a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=60")

noscript.appendChild(img)

window.app.appendChild(noscript)

I think we could avoid rendering noscript elements in general, using a v-if="false" is a valid workaround, you can combine it with v-pre too so Vue skips rendering any of their children and probably boosting the performance a bit too

@OwenMelbz
Copy link
Author

Sorry processing was probably the wrong word :) I could just see Vue was causing them to run.

I’ll try out the v-pre you’ve mentioned as well to see what that affects, thanks for the tip :)

I’m a little confused with your code snippet, what is that trying to demonstrate? - the noscript itself is just in a PHP template for something else, however because the page wrapper is what the “new Vue ( el = #app )” Vue starts to work it’s magic which causes this side effect

@posva
Copy link
Member

posva commented Mar 10, 2019

The code is showing the problem without Vue

@OwenMelbz
Copy link
Author

Ah okay - do you think this is something Vue could handle? As if it works with v-if and v-pre then would suggest it can handle it without side effects?

@tony19
Copy link

tony19 commented Mar 10, 2019

It seems anti-intuitive (or an invalid use case) for <noscript> to be added through scripting -- the very thing that <noscript> indicates is disabled. 😜

@OwenMelbz
Copy link
Author

@tony19 - that’s “sort” of my point. The noscript itself isn’t added through JS it just happens to be in the server side page source

@posva
Copy link
Member

posva commented Mar 10, 2019

What he's saying is that you are adding it through Vue by feeding it to Vue, which adds dynamically content. I get the usecase though, it's added in case there is no JS (Vue doesn't run) but if Vue runs you want it to be ignored the same way it is ignored upon first rendering

@lanaambre
Copy link

lanaambre commented Mar 12, 2019

Just add the inline-template attribute to your <noscript> tag

<noscript inline-template>
 <img src="//something.jpg">
</noscript>

@OwenMelbz OwenMelbz changed the title Vue should not process content within <noscript> tags Vue should not cause execution of content within <noscript> tags Mar 12, 2019
@OwenMelbz
Copy link
Author

OwenMelbz commented Mar 12, 2019

@Antoine-Demailly We've already established that there's several "hacks" to work around this issue, but that's not the point.

The solution should either be

  • Vue internally makes sure it doesn't cause any side effects or execution for noscript content
  • There's sufficient documentation, caveats or compatibility notices within the Vue documentation that highlight this side effect and explain an agreed "best practice" to follow to make sure it doesn't happen.

@posva - The v-pre trick did not work, I was hoping it would as it seems better than v-if or inline-template as it's more descriptive. You can see the example https://jsfiddle.net/nvfuyj8k/ - it still requests the content within the noscript

@posva
Copy link
Member

posva commented Mar 12, 2019

yeah, i said combine it to v-if to prevent vue from running inside, it's a performance improvement. Rendering wasn't the right word, interpreting maybe? Anyway, you can check it out in vue docs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants