{"id":15235693,"url":"https://github.com/developit/preact-scroll-viewport","last_synced_at":"2026-03-07T21:02:09.473Z","repository":{"id":57329617,"uuid":"74083627","full_name":"developit/preact-scroll-viewport","owner":"developit","description":"Preact Component that renders homogeneous children only when visible","archived":false,"fork":false,"pushed_at":"2018-07-27T20:31:42.000Z","size":10,"stargazers_count":123,"open_issues_count":5,"forks_count":11,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-10-11T18:33:02.183Z","etag":null,"topics":["preact","viewport","virtual","virtual-scroll"],"latest_commit_sha":null,"homepage":"https://jsfiddle.net/developit/t6qqnwn9/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/developit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-11-18T01:35:57.000Z","updated_at":"2025-09-09T18:52:54.000Z","dependencies_parsed_at":"2022-09-06T20:30:48.943Z","dependency_job_id":null,"html_url":"https://github.com/developit/preact-scroll-viewport","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/developit/preact-scroll-viewport","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developit%2Fpreact-scroll-viewport","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developit%2Fpreact-scroll-viewport/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developit%2Fpreact-scroll-viewport/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developit%2Fpreact-scroll-viewport/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/developit","download_url":"https://codeload.github.com/developit/preact-scroll-viewport/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developit%2Fpreact-scroll-viewport/sbom","scorecard":{"id":337241,"data":{"date":"2025-08-11","repo":{"name":"github.com/developit/preact-scroll-viewport","commit":"45dd07f628b7aed5dd8375585d286de95dfecc7b"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.2,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":1,"reason":"Found 1/9 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 2 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T04:59:29.623Z","repository_id":57329617,"created_at":"2025-08-18T04:59:29.623Z","updated_at":"2025-08-18T04:59:29.623Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30231490,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-07T19:01:10.287Z","status":"ssl_error","status_checked_at":"2026-03-07T18:59:58.103Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["preact","viewport","virtual","virtual-scroll"],"created_at":"2024-09-29T08:05:20.274Z","updated_at":"2026-03-07T21:02:09.238Z","avatar_url":"https://github.com/developit.png","language":"JavaScript","readme":"# `\u003cScrollViewport /\u003e` \u003csub\u003e_for [Preact]_\u003c/sub\u003e\n\n[![NPM](https://img.shields.io/npm/v/preact-scroll-viewport.svg)](https://www.npmjs.com/package/preact-scroll-viewport)\n[![Travis](https://travis-ci.org/developit/preact-scroll-viewport.svg?branch=master)](https://travis-ci.org/developit/preact-scroll-viewport)\n\nA compositional component that renders its children based on the current viewport.\n\nUseful for those super important business applications where one must show _all_ million rows.\n\n#### [JSFiddle Demo](https://jsfiddle.net/developit/t6qqnwn9/)\n\n\u003ca href=\"https://jsfiddle.net/developit/t6qqnwn9/\"\u003e\n\t\u003cimg alt=\"preview\" src=\"https://i.gyazo.com/38f75b5db9615b0a08304d6cca209e47.gif\" width=\"420\"\u003e\n\u003c/a\u003e\n\n---\n\n\n## Usage Example\n\nSimply wrap a large collection of children in this component, and they will be rendered based on the viewport.\nYou can define a default row height (`defaultRowHeight`) to use prior to dimensions being available, or a static row height (`rowHeight`) to avoid style recalculation entirely. If `rowHeight` is not provided, the height of the first row will be calculated and extrapolated.\n\n```js\n// create 100,000 children:\nlet children = [];\nfor (let i=1; i\u003c100000; i++) {\n\tchildren.push(\u003cdiv class=\"row\"\u003e{i}\u003c/div\u003e);\n}\n\n// ...but only render what is in-viewport:\nrender(\n\t\u003cScrollViewport rowHeight={22}\u003e\n\t\t{children}\n\t\u003c/ScrollViewport\u003e\n);\n```\n\n\n---\n\n\n## Props\n\n| Prop                  | Type       | Description         |\n|-----------------------|------------|---------------------|\n| **`rowHeight`**        | _Number_   | Static height of a row (prevents style recalc)\n| **`defaultRowHeight`** | _Number_   | Initial height of a row prior to dimensions being available\n| **`overscan`**         | _Number_   | Number of extra rows to render above and below visible list. Defaults to 10. \\*\n| **`sync`**             | _Boolean_  | If `true`, forces synchronous rendering \\*\\*\n\n_**\\* Why overscan?** Rendering normalized blocks of rows reduces the number of DOM interactions by grouping all row renders into a single atomic update._\n\n_**\\*\\* About synchronous rendering:** It's best to try without `sync` enabled first. If the normal async rendering behavior is fine, leave sync turned off. If you see flickering, enabling sync will ensure every update gets out to the screen without dropping renders, but does so at the expense of actual framerate._\n\n\n| _Without_ Overscan | _With_ Overscan |\n|--------------------|-----------------|\n| \u003cimg src=\"https://i.gyazo.com/e192bf1ca835fbe6ad803f7b6270e424.gif\" height=\"150\"\u003e | \u003cimg src=\"https://i.gyazo.com/478440d1f06fe543e69fff8b88ce7963.gif\" height=\"150\"\u003e |\n\n\n---\n\n## Simple Example\n\n[**View this example on JSFiddle**](https://jsfiddle.net/developit/t6qqnwn9/)\n\n```js\nimport ScrollViewport from 'preact-scroll-viewport';\n\nclass Demo extends Component {\n    // 30px tall rows\n    rowHeight = 30;\n\n    render() {\n\t\t// Generate 100,000 rows of data\n\t\tlet rows = [];\n\t\tfor (let x=1e5; x--; ) rows[x] = `Item #${x+1}`;\n\n        return (\n            \u003cScrollViewport class=\"list\" rowHeight={this.rowHeight}\u003e\n\t\t\t\t{ rows.map( row =\u003e (\n\t\t\t\t\t\u003cdiv class=\"row\"\u003e{row}\u003c/div\u003e\n\t\t\t\t)) }\n\t\t\t\u003c/ScrollViewport\u003e\n        );\n    }\n}\n\nrender(Demo, document.body);\n```\n\n\n---\n\n\n### License\n\n[MIT]\n\n\n[Preact]: https://github.com/developit/preact\n[MIT]: http://choosealicense.com/licenses/mit/\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevelopit%2Fpreact-scroll-viewport","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevelopit%2Fpreact-scroll-viewport","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevelopit%2Fpreact-scroll-viewport/lists"}