When attempting to download the Image() function, numerous errors are encountered without clear explanation

I have incorporated Quasar into my project using the following code:

<template>
  <div class="q-pa-md">
    <div class="q-gutter-sm row items-start">
      <q-img
        v-for="pic in picObject"
        :key="pic.id"
        :src="pic"
        @error="reportError"
        style="height: 140px; width: 140px"
      >
        <template v-slot:default>
          <div class="absolute-bottom transparant-banner">This picture loaded ok.</div>
        </template>
        <template v-slot:error>
          <div class="absolute-full flex flex-center bg-dark" style="color: red">Cannot load image</div>
        </template>
      </q-img>
    </div>
  </div>
</template>
<script>

export default {
  components: {},
  data() {
    return {
      picObject: { "2": "https://images.takeshape.io/86ce9525-f5f2-4e97-81ba-54e8ce933da7/dev/144069dc-7390-4022-aa0f-abba022d3a2f/spec.jpg?auto=compress%2Cformat", "3": "https://natureconservancy-h.assetsadobe.com/is/image/content/dam/tnc/nature/en/photos/prescribed_burn_oregon.jpg?crop=0,120,5760,3600&wid=1640&hei=1025&scl=3.5121951219512195", "4": "https://orig11.deviantart.net/1062/f/2015/315/9/6/abstract__7_by_thejsyve1-d9gciwk.jpg", "5":...
    };
  },
  methods: {
    reportError(event) {
      console.log(`${event.name}: ${event.message}`);
    }
  }
};
</script>
<style>
.transparant-banner {
  color: white;
}
</style>

When viewing on Chrome, I encounter errors on multiple images. However, everything functions as expected on Firefox. The Quasar q-img component relies on the javascript image() which triggers the onerror event.

Some of my questions are as follows:

  1. Why do these errors occur randomly even though the image appears to be successfully downloaded after the error happens?
  2. How can I resolve this issue?

The behavior can be observed in this jsfiddle, with relevant code in components/Example.vue.

EDIT: The error message reported is:

EncodingError - The source image cannot be decoded.

According to source, the error is caused by .decode(). But what exactly is the reason behind it? This article explains .decode() and its exclusive application to Chrome. In Quasar framework, the decoding process is handled here.

Answer №1

Image.decode is a browser async API designed to prevent the main thread from being blocked during decoding and painting.

When images are initialized with src, the browser begins downloading them. The decode function returns a Promise that indicates when it can safely be added to the DOM.

However, processing a sequence of large images (such as 4mb each) can sometimes lead to corruption. The reasoning behind this issue remains unclear, but both size and quantity seem to play a role.

I experimented with an array of images using a simple code snippet:

imagesArray.forEach(function(img) {
  var i = new Image();
  i.src = img;
  i.decode().then(function() {
    console.log("decoded");
  }).catch(function() {
    console.log("error");
  });
});

The error tends to occur when processing more than 5-6 images. It might be worth trying static images (with image Content-type) instead.

In any case, Quazar utilizes this.__updateSrc(); to pass the src value to the backgroundImage. This results in backgrounds being loaded even in error scenarios, causing the browser to download the images twice. In cases where decoding fails, the first download goes unused.

To address this issue, you can comment out the line containing this.hasError = true within the __onError method. When set to true, this property triggers Vue to throw an error on the template slot.

It's worth mentioning that version v1.0.0-rc.1 of Quasar has already addressed this issue, ensuring downloads proceed without encountering errors. You can find more details about this fix here.

Answer №2

Upon observing the DevTools Network, one can discern that the images downloaded by Vue are staged in batches of no more than 6 at a time. The common-sense limit for simultaneous open connections via HTTP is 2. Interestingly, Quasar's loaded images do not adhere to this rule as all 12 are downloaded in parallel. In Firefox, these connections are forcibly constrained to 2 at a time. It is believed that the large number of parallel quasar connections may get reset by the remote server mid-flight, indicated by the fact that the same image is downloaded with varying byte sizes. This theory is supported by the fact that the header still returns a 200 status.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Discover the secrets of positioning objects around a spherical globe in Three.js

I am currently working on a project where I have a json file containing country borders. My goal is to use this data to build a map in three.js, similar to the example provided by this link. I want each cylinder on the map to be positioned according to i ...

Ways to showcase content on a web browser while the page is loading

I spend a considerable amount of time in my HTML code trying to optimize the loading of script blocks. However, during the loading process, the browser screen remains blank (white screen). Is there a way for me to ensure that when the browser is launched ...

JavaScript - unique user-defined data types - what skills do I need and what knowledge should I acquire?

Exploring the vast flexibility of JavaScript, I've been intrigued by the idea of creating a custom data type that mimics the behavior of native JS types. My goal is to develop a range data type capable of representing math ranges such as (2.5;9] or (- ...

How to dynamically apply component-specific CSS in NextJS based on conditions

I'm working on my nextjs project and encountered an issue with adding conditional styling to a component. To address this, I created a component-level stylesheet called MyComponent.module.css, which includes the following styles: .primary { color: ...

Encountering the error of receiving "$ undefined," despite making a reference to the library

I have included the JQuery library in the following way: <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js" type="text/javascript"></script> Despite trying to download the library and include it locally in my project, I ...

Interact with a button on a Vue.js application to scan the DOM, identify all elements with a particular class name, and add a new class to their current class list

Currently, I am utilizing Axios to retrieve an HTML file. After getting the file, I extract everything after the <body> tag and then append it to {{htmlData}} within a div in my template. This is how it appears: <template> <somebutton ...

What is the procedure for verifying the type of an element using chai?

Is there a way to determine if an element is either an "a" tag or a "div" tag? I've tried the following code, but it's not working as expected: it('has no link if required', () => { const wrapper = shallow(<AssetOverlay a ...

Using postMessage with an iframe is causing issues within a React application

I encountered two errors when executing the code below in my React application: try { iframe.src = applicationRoutes.href; iframe.style.width = '0px'; iframe.style.height = '0px'; iframe.style.border = '0px& ...

Unable to retrieve $scope.property using direct access, however it is visible when printed to the console using console.log($

I have successfully populated $scope with data using a get call: httpGetAsync("myUrlWasHere", getBlogPosts, $scope); The console outputs the data when I print console.log($scope): https://i.sstatic.net/SkDl9.png However, when I try to access it using c ...

Elements of Data Pagination in Vuetify Data Tables

My data-table is filled with thousands of data inputs, so I am using the default Vuetify pagination to display only 5, 10, or 25 items at a time on the table. However, I am in need of a way to determine which data is currently visible on the table. For ex ...

How can I make the first option in a dropdown menu automatically selected in a select input form?

Having an issue where the first selection in my dropdown list is showing as null even though it should be selected. Here is the code: <div class="form-group mb-6"> <label class="form-label">{{ $trans('labels.departme ...

A guide on accessing the value of ng-model in an AngularJS controller

I am facing an issue with a simple view that contains an input text field where the user enters their name. The controller should retrieve this value and assign it to the employeeDescription variable. However, the ng-model value from the input field is not ...

Encountering a "Web Storm identifier expected" error while attempting to pass Vue function parameters using braces

This is the code I've been working on. I encountered an error while coding. Can you help me figure out how to address this issue? Should I consider disabling the inspection feature in WebStorm, or should I make changes to the code style? I have alre ...

Creating a Custom Form Control in Angular 2 and Implementing Disable Feature

I have developed a unique custom control using ControlValueAccessor that combines an input[type=text] with a datepicker. While the template-driven forms accept it without any issues, the situation changes when implementing the model-driven approach (react ...

Bizarre glitch in the box-shadow transition

Recently, I encountered an unusual issue involving transitioning a box-shadow... Upon hovering over the divs, a box-shadow (black, 5px spread) is applied with a transition. Once the cursor leaves the divs, the box-shadow spread returns to 0px. The strang ...

Automatically updating Vue.js list after making a request

My form allows me to add a new contact to the database: <el-form :model="contact" > <el-form-item> <el-input v-model="contact.firstname"/> </el-form-item> <el-form-item> ...

Encountering 404 Error in Production with NextJS Dynamic Routes

I'm currently working on a next.js project that includes a dynamic routes page. Rather than fetching projects, I simply import data from a local JSON file. While this setup works well during development, I encounter a 404 error for non-existent pages ...

Switch the background image in Three.js with a function call

Issue at Hand: I am currently working on creating a static scene with a fixed image background and some geometries in front of it. Given that the scene is static, I have determined that I do not need an envMap. To achieve this, I followed the guidance pr ...

What is the best way to utilize a forEach method or other array methods on arrays within objects in Javascript?

I'm currently exploring the use of modern array methods on arrays, but I'm curious if there's a way to apply these methods to objects that contain arrays? If not, would it be more efficient to store the entire object as an array instead? va ...

Difficulty implementing clickable dropdown buttons in a React navbar

After some tweaking, I was able to create buttons that trigger dropdown menus which disappear when clicked off. However, a problem arises when any button is clicked - all of the dropdowns appear at once. It appears that setting the state for one button a ...