Loads items in lazy way to achieve high performance and better UX in large lists

Overview

Lazy Load List

Lazy Load List is a lightweight web package that loads items in lazy way to achieve high performance and better UX in large lists.

Rendering large lists makes the first load slow especially if items contain images, so this package split the list to small lists then it renders them one by one when scrolling to the end of the list..

you can notice the deference here:

loading performance deference

Features

  • Fast Loading 🚀
  • Lightweight package
  • Better user experience
  • Supports most loved JS frameworks
  • Supports SSR & SSG

Demo

you can find the source code of examples in examples folder

Lazy Load List 1.2 is here 🎉

what's new?

  • support React js
  • auto loading items when container can contain more
  • better performance
  • explain using custom loading element

Supported Frameworks

| svelte logo | Svete js     | ✅
| vue logo | Vue js (2,3) | ✅
| react logo | React js     | ✅

Installation

install the package using npm or yarn:

install using npm

$ npm i lazy-load-list

or using yarn

$ yarn add lazy-load-list

Usage

⚠ you must wrap the list by div and specify the height and width in the wrapper div.

  • svelte logo svelte js:

{ item }

">
import LazyList from 'lazy-load-list/svelte'


  

{ item }

  • vue logo vue js:
// script import LazyList from 'lazy-load-list/vue' .. components: { LazyList } // don't forget to define it in the components">

  
// script import LazyList from 'lazy-load-list/vue' .. components: { LazyList } // don't forget to define it in the components
  • react logo react js:
">
import  LazyList  from  'lazy-load-list/react'

const renderItem = ({item, index}) => (
	

{ item }

)

Props

prop supported framework description required type default value
data all the item array yes array []
itemsPerRender all items to be rendered per load yes number 3
containerClasses all list container classes for CSS no string ''
defaultLoading all to show the default loading or not no bool true
defaultLoadingColor all color of the default loading no string '#18191A'
renderItem React js element to be render for each item yes React component () => null
loadingComponent React js custom loading component no React component () => null

Using custom loading element

you can specify the loading element color using (defaultLoadingColor) prop.. but if you don't like the default loading element, you can use custom one:

  • in svelte logo svelte js & vue logo vue js (just use slot name "loading like this):
">
loading
  • react logo react js (use loadingComponent props to pass the element):
	..
		loadingComponent={loadingElementHere}
	/>
You might also like...

tsParticles - Easily create highly customizable particles animations and use them as animated backgrounds for your website. Ready to use components available for React, Vue.js (2.x and 3.x), Angular, Svelte, jQuery, Preact, Inferno.

tsParticles - Easily create highly customizable particles animations and use them as animated backgrounds for your website. Ready to use components available for React, Vue.js (2.x and 3.x), Angular, Svelte, jQuery, Preact, Inferno.

tsParticles - TypeScript Particles A lightweight TypeScript library for creating particles. Dependency free (*) and browser ready! Particles.js conver

Jan 4, 2023

Backs up your favourite and recently used gifs/emotes and restores them in case discord clears them after logouts or for other reasons

Persist Favourites This plugin solves the problem of Discord randomly deciding to clear your gifs or emotes by backing both up regularely and restorin

Oct 13, 2022

Based on vitawind, kowind brings ESLint plugin and some other plugins to it that help you to format your code quickly and efficiently.

đŸĻ KOWIND v3 đŸĻ Vite helper based on vitawind 🧰 Easy To Install ⚡ī¸ Automatically open Tailwind JIT Mode ⚙ One-Command Setting 🚀 Automatically config

Nov 26, 2022

This repo contains a fully configured nuxt 3 instance supporting TypeScript and several considered as useful libraries, fully configured and ready to use in real world projects!

Nuxt 3 Starter This repo contains a fully configured nuxt 3 instance supporting TypeScript and several considered as useful libraries, fully configure

Dec 27, 2022

Morse code is a method used in telecommunication to encode text characters as standardized sequences of two different signal durations, called dots and dashes, or dits and dahs.

@elonehoo/point-line Install # npm npm i @elonehoo/point-line # yarn yarn add @elonehoo/point-line #pnpm pnpm i @elonehoo/point-line Usage import {dec

Aug 3, 2022

NativeScript empowers you to access native api's from JavaScript directly. Angular, Vue, Svelte, React and you name it compatible.

NativeScript empowers you to access native api's from JavaScript directly. Angular, Vue, Svelte, React and you name it compatible.

NativeScript empowers you to access native APIs from JavaScript directly. The framework currently provides iOS and Android runtimes for rich mobile de

Jan 4, 2023

JavaScript data grid with a spreadsheet look & feel. Works for React, Angular, and Vue. Supported by the Handsontable team ⚡

JavaScript data grid with a spreadsheet look & feel. Works for React, Angular, and Vue. Supported by the Handsontable team ⚡

Handsontable is a JavaScript component that combines data grid features with spreadsheet-like UX. It provides data binding, data validation, filtering

Dec 31, 2022

🌈 An enterprise-class UI components based on Ant Design and Vue. 🐜

🌈  An enterprise-class UI components based on Ant Design and Vue. 🐜

Ant Design Vue An enterprise-class UI components based on Ant Design and Vue. English | įŽ€äŊ“中文 Features An enterprise-class UI design system for desktop

Jan 9, 2023

BootstrapVue provides one of the most comprehensive implementations of Bootstrap v4 for Vue.js. With extensive and automated WAI-ARIA accessibility markup.

BootstrapVue provides one of the most comprehensive implementations of Bootstrap v4 for Vue.js. With extensive and automated WAI-ARIA accessibility markup.

With more than 85 components, over 45 available plugins, several directives, and 1000+ icons, BootstrapVue provides one of the most comprehensive impl

Jan 4, 2023
Comments
  • Missing lib/Loading.css

    Missing lib/Loading.css

    Description

    After npm install, the following error appears:

    ERROR  Failed to compile with 1 error  
    
    This relative module was not found:
    * ../lib/loading.css in ./node_modules/cache-loader/dist/cjs.js??ref--13-0!./node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref--1-0!./node_modules/vue-loader-v16/dist??ref--1-1!./node_modules/lazy-load-list/vue/LazyList.vue?vue&type=script&lang=js
    

    As the error suggests, the loading.css file is missing from the lib directory. Judging from older versions of this, the code used to be in the Loading modules but was moved to an independent file which was never added to git.

    Suggested fix

    Create a new file called lib/loading.css with the following:

    .dots {
        width: 3.5em;
        display: flex;
        flex-flow: row nowrap;
        align-items: center;
        justify-content: space-between;
    }
    
    .dots div {
        width: 0.8em;
        height: 0.8em;
        border-radius: 50%;
        animation: fade 0.8s ease-in-out alternate infinite;
    }
    
    .dots div:nth-of-type(1) {
        animation-delay: -0.4s;
    }
    
    .dots div:nth-of-type(2) {
        animation-delay: -0.2s;
    }
    
    @keyframes fade {
        from {
            opacity: 1;
        }
        to {
            opacity: 0;
        }
    }
    
    opened by p0rridg3 2
  • [Error] You may need an appropriate loader to handle this file type

    [Error] You may need an appropriate loader to handle this file type

    Hello, Mr. Omar Thanks for your hard work, But I have a little problem.

    I tried to use 'lazy-load-list' in electron app (with nextron), And I got this error Screenshot_20220404_023527

    After some search, I think this to be related to webpack. So, Is there anything which can I do to solve this problem?

    Code :

    import LazyList from "lazy-load-list/react";
    import { useState, useEffect, useRef } from "react";
    
    import {
    	Alert,
    	AlertIcon,
    	AlertTitle,
    	AlertDescription,
    	Button,
    	IconButton,
    	Box,
    	Tooltip,
    	Flex,
    	Spinner,
    	HStack,
    	Stack,
    	Input,
    	InputRightElement,
    	InputGroup,
    	Heading,
    	Select,
    } from "@chakra-ui/react";
    
    import {
    	HiTrash,
    	HiRefresh,
    	HiOutlineInformationCircle,
    	HiSearch,
    	HiX,
    } from "react-icons/hi";
    import LogsProvider, { useLogs } from "@Context/logs";
    
    const NUMBER_OF_MESSAGES = 100;
    
    function Logs() {
    	const { logs, GetLogs, ClearLogs, isLoading } = useLogs();
    
    	const [StatusFilter, setStatusFilter] = useState("all");
    	const [LogsAfterFiltering, setLogsAfterFiltering] = useState(
    		logs?.lines ?? [],
    	);
    
    	const [search, setSearch] = useState({ bool: false, value: "" });
    	useEffect(() => GetLogs(), []); // * Get Logs when user open the modal
    
    	useEffect(() => {
    		setLogsAfterFiltering(
    			logs?.lines?.filter((line) => {
    				if (StatusFilter === "all") return true;
    				return line.status === StatusFilter && line;
    			}),
    		);
    	}, [StatusFilter, logs]);
    
    	useEffect(() => {
    		setLogsAfterFiltering(
    			logs?.lines.filter(
    				(line) =>
    					line.content.toLowerCase().includes(search.value.toLowerCase()) &&
    					(line.status === StatusFilter || StatusFilter === "all"),
    			),
    		);
    	}, [search.value, logs]);
    
    	// useEffect(() => console.log("search update to", search), [search]); // ! For Debugging
    	// useEffect(() => console.log("logs update to", logs), [logs]); // ! For Debugging
    	// useEffect(() => console.log("LogsAfterFiltering update to", LogsAfterFiltering), [LogsAfterFiltering]); // ! For Debugging
    
    	return (
    		<>
    			<Flex w='full' justify='space-between' my={3}>
    				<HStack>
    					<Tooltip
    						hasArrow
    						placement='right'
    						label={`Logs stored in ${logs.path}`}>
    						<IconButton
    							variant='ghost'
    							cursor='default'
    							icon={<HiOutlineInformationCircle size='1.3em' />}
    						/>
    					</Tooltip>
    				</HStack>
    
    				<HStack justify='end' spacing={3}>
    					<Select
    						maxW='150px'
    						value={StatusFilter}
    						variant='filled'
    						onChange={(e) => setStatusFilter(e.target.value)}>
    						<option value='all'>All {logs?.lines?.length}</option>
    						<option value='info'>
    							Info{" "}
    							{logs?.lines?.filter((line) => line.status === "info").length}
    						</option>
    						<option value='warning'>
    							Warning{" "}
    							{logs?.lines?.filter((line) => line.status === "warning").length}
    						</option>
    						<option value='error'>
    							Error{" "}
    							{logs?.lines?.filter((line) => line.status === "error").length}
    						</option>
    					</Select>
    					{search.bool ? (
    						<InputGroup w='200px'>
    							<Input
    								placeholder='Search'
    								variant='filled'
    								value={search.value}
    								onChange={(e) =>
    									setSearch({ ...search, value: e.target.value })
    								}
    							/>
    							<InputRightElement>
    								{search.value ? (
    									<IconButton
    										variant='none'
    										icon={<HiX size='1.4em' />}
    										onClick={() => setSearch({ ...search, value: "" })}
    									/>
    								) : (
    									<IconButton
    										variant='none'
    										icon={<HiSearch size='1.4em' />}
    										onClick={() => setSearch({ ...search, bool: !search.bool })}
    									/>
    								)}
    							</InputRightElement>
    						</InputGroup>
    					) : (
    						<Tooltip label='Search in logs'>
    							<IconButton
    								variant='ghost'
    								icon={<HiSearch size='1.4em' />}
    								onClick={() => setSearch({ ...search, bool: !search.bool })}
    							/>
    						</Tooltip>
    					)}
    
    					<Button leftIcon={<HiRefresh />} onClick={() => GetLogs()}>
    						Refresh
    					</Button>
    					<Button
    						leftIcon={<HiTrash />}
    						colorScheme='red'
    						onClick={() => ClearLogs()}>
    						Clear All
    					</Button>
    				</HStack>
    			</Flex>
    			<Stack spacing={1}>
    				{isLoading ? (
    					<Spinner
    						size='xl'
    						color='green'
    						alignSelf='center'
    						justifySelf='center'
    					/>
    				) : !(LogsAfterFiltering.length > 0) ? (
    					<Heading size='md' alignSelf='center'>
    						No logs found
    					</Heading>
    				) : (
    					<LogRows
    						data={LogsAfterFiltering.slice(
    							0,
    							Math.min(LogsAfterFiltering.length, NUMBER_OF_MESSAGES),
    						)}
    					/>
    				)}
    			</Stack>
    		</>
    	);
    }
    
    function LogAlert({ item, index }) {
    	const { status, date, content } = item;
    	const availableTypes = ["warning", "error", "info"];
    
    	return (
    		<Alert
    			key={index}
    			status={availableTypes.includes(status) ? status : "warning"}>
    			<AlertIcon />
    			<Box flex={1}>
    				<AlertTitle mr={2}>{date}</AlertTitle>{" "}
    				<AlertDescription>{content}</AlertDescription>
    			</Box>
    		</Alert>
    	);
    }
    
    const LogRows = ({ data }) => {
    	const listRef = useRef(null);
    	const ref = useRef(null);
    
    
    
    	return (
    		<Box ref={ref}>
    			<LazyList
    				data={data}
    				itemsPerRender={15}
    				defaultLoadingColor='#222'
    				renderItem={LogAlert}
    			/>
    			
    		</Box>
    	);
    };
    
    function LogsComponent() {
    	return (
    		<LogsProvider>
    			<Logs />
    		</LogsProvider>
    	);
    }
    
    export default LogsComponent;
    
    
    opened by Hulxv 3
Owner
OMER ANWAR
OMER ANWAR
Bionic ReadingTool - Convert Text into Better Way to Read Faster

?? Bionic ReadingTool A revolutionary way for guiding the eyes through text using artificial fixation spots to make reading easier. As a result, the r

Lucian Daniel Crisan 335 Dec 24, 2022
A high quality UI Toolkit built on Vue.js 2.0

iView A high quality UI Toolkit built on Vue.js. Docs 3.x | 2.x | 1.x Features Dozens of useful and beautiful components. Friendly API. It's made for

iView 24k Jan 5, 2023
⊞ The modern way to work with tables. Blazing fast facet-filtering, sorting, and searching.

Table Elements The easiest way to integrate Meilisearch into your frontend as a data source for your tables. These components will allow you to kick-s

Open Web 10 Nov 21, 2022
⚡ī¸ The easiest way to build forms with Vue.

Documentation Website What is Vue Formulate? Vue Formulate is the easiest way to build forms with Vue. Please read the comprehensive documentation for

Braid 2.2k Dec 30, 2022
Carpatin is a React JS Admin Dashboard Template that focuses on the management flows of a back-office application. We leverage the Material-UI power of stylizing the components in a way that feels more professional.

Carpatin Dashboard Free Carpatin is a React Js Admin Dashboard Template that focuses on the management flows of a back-office application. We leverage

Devias 64 Dec 12, 2022
@auth0/auth0-spa-js wrapper in the "Vue way", with full TS support

vue-auth0 This is a wrapper around @auth0/auth0-spa-js meant to ease the usage into Vue projects. This is heavily inspired by the snippet into Auth0 o

Dreamonkey S.r.l. 5 Oct 18, 2022
VGENT – Vue Agent, that helps you to develop in a more effective way

VGENT is a CLI tool that generates boilerplate files for components, pages in your Nuxt.js or Vue.js project.A file generator for Nuxt.js

Arman Kuanysh 20 Dec 29, 2022
Mobile app development framework and SDK using HTML5 and JavaScript. Create beautiful and performant cross-platform mobile apps. Based on Web Components, and provides bindings for Angular 1, 2, React and Vue.js.

Onsen UI - Cross-Platform Hybrid App and PWA Framework Onsen UI is an open source framework that makes it easy to create native-feeling Progressive We

null 8.7k Jan 4, 2023
:necktie: :briefcase: Build fast :rocket: and easy multiple beautiful resumes and create your best CV ever! Made with Vue and LESS.

best-resume-ever ?? ?? Build fast ?? and easy multiple beautiful resumes and create your best CV ever! Made with Vue and LESS. Cool Creative Green Pur

Sara Steiert 15.8k Jan 9, 2023