Using ImageLocation is already a way to cache the work to speed things up, the Picturebox will not load the image until it is necessary to display it. If you for example click the scrollbar to see next "page" you'll first see image 'x' then each image is loaded. Still it is sloppy because enormous amount of memory is wasted, the only way to solve it is to load each image into memory and process a thumbnail image from that (Image.GetThumbnailImage is suitable), which of course is very time consuming and for this you need multithreading. The BackgroundWorker as you mentioned is a very easy component to use for multithreading, basically you add one from toolbox to form and doubleclick it to get the DoWork event, then write the code for the work to do in this thread. To run the worker you call RunWorkerAsync method, it would be suitable to pass the folder path to process as argument to this method. Since the worker methods runs a separate thread you shall not create pictureboxes and modify UI elements here, instead you will stack up the processed thumbnail images in an array, List(Of Image) is suitable, and pass this as Result from worker, the RunWorkerCompleted runs in UI thread and here you can quickly create an array of pictureboxes and add them in one go with FlowlayoutPanel.Controls.AddRange method. Give it a try, it is easy to do what is described here.