PHP渲染百万级数据,你踩过这些坑吗?

恭喜,恭喜,iMouse爱鼠XP版全面发布测试,苹果手机自动化测试必须 电脑控制苹果手机,免越狱,免签名,自动化测试 阅读详情

最近接到了一个新需求,要在PHP里渲染一个超大的数据集,数据量大概在百万级别。作为一个老PHP,我一开始以为这不就是个简单的foreach循环,结果现实给我上了一课。今天就来聊聊PHP大数据渲染的那些坑,以及我是怎么填这些坑的。

先说说最初的想法:直接从数据库里拉出来所有数据,然后扔给PHP处理,循环输出到页面上。代码大概长这样:

$data = $db->query("SELECT FROM huge_table");

foreach ($data as $row) {

echo "<div>{ $row['name'] }</div>";

}

看起来很简单?结果服务器直接崩了。为啥?内存爆炸了。PHP脚本默认的内存限制是128M,但百万条记录一上来就是几百兆,直接爆了。

所以,填坑第一步:控制内存。我决定分批处理数据,比如每次只处理1000条。于是代码改成了这样:

$offset = 0;

$limit = 1000;

do {

$data = $db->query("SELECT

FROM huge_table LIMIT { $limit } OFFSET { $offset }");

foreach ($data as $row) {

echo "<div>{ $row['name'] }</div>";

}

$offset += $limit;

} while (!empty($data));

这下内存是稳住了,但新问题又来了:渲染时间太长。百万条记录,每批1000条,要渲染1000次,每次都要跟数据库交互,速度实在是太慢了。于是,填坑第二步:减少数据库查询次数。

我决定用游标(cursor)来处理数据,一次性从数据库拉取数据,然后逐条处理。代码是这样的:

$stmt = $db->query("SELECT FROM huge_table");

while ($row = $stmt->fetch()) {

}

这样减少了数据库查询次数,速度确实快了不少。但问题又来了:PHP脚本执行时间太长,超时了。PHP默认的最大执行时间是30秒,而我这个脚本跑了1分钟还没完。于是,填坑第三步:调整脚本执行时间。

我在脚本开头加了一句:

set_time_limit(0);

这样脚本就不会超时了。但新的问题又出现了:页面加载时间太长,用户会以为网页挂了。于是,填坑第四步:异步渲染。

我决定用AJAX来分批渲染数据,先把页面框架加载出来,然后通过AJAX请求分批获取数据并渲染。前端代码大概长这样:

function loadMore(offset, limit) {

fetch(/api/getData?offset=${ offset }&limit=${ limit })

.then(response => response.json())

.then(data => {

data.forEach(row => {

document.getElementById('container').innerHTML += &lt;div&gt;${ row.name }&lt;/div&gt;;

});

if (data.length > 0) {

loadMore(offset + limit, limit);

});

}

loadMore(0, 1000);

后端API代码大概是这样的:

$offset = $_GET['offset'];

$limit = $_GET['limit'];

$data = $db->query("SELECT

FROM huge_table LIMIT { $limit } OFFSET { $offset }");

echo json_encode($data);

这下用户体验好多了,页面先加载出来,数据慢慢渲染。但问题又来了:如果用户快速滚动页面,AJAX请求会堆积,导致服务器压力过大。于是,填坑第五步:限制并发请求。

我决定在前端加一个队列,每次只允许一个AJAX请求,等上一个请求完成了再发起下一个。代码大概是这样的:

let isRequesting = false;

if (isRequesting) return;

isRequesting = true;

isRequesting = false;

}

这下服务器压力小多了,但新问题又来了:如果用户不滚动页面,数据就不会加载,导致页面一开始是空的。于是,填坑第六步:预加载数据。

我决定在页面加载时先加载几批数据,这样用户一进来就能看到内容。loadMore(0, 5000); // 先加载5000条

这样用户体验更好了,但问题又来了:如果用户只看前几页,后面的数据就白白加载了,浪费资源。于是,填坑第七步:仅渲染可视区域。

我决定用虚拟滚动技术,只渲染用户当前可见的部分,其他部分等用户滚动到那里时再渲染。前端代码大概是这样的:

const container = document.getElementById('container');

const visibleItems = 20;

const itemHeight = 50;

let scrollTop = 0;

function render() {

const start = Math.floor(scrollTop / itemHeight);

const end = start + visibleItems;

fetch(/api/getData?offset=${ start }&limit=${ visibleItems })

container.innerHTML = '';

data.forEach((row, index) => {

const top = (start + index) itemHeight;

container.innerHTML += &lt;div style="position: absolute; top: ${ top }px;"&gt;${ row.name }&lt;/div&gt;;

}

container.addEventListener('scroll', () => {

scrollTop = container.scrollTop;

render();

});

render();

这下资源利用率大大提高了,但问题又来了:快速滚动时,渲染跟不上,导致页面卡顿。于是,填坑第八步:优化渲染性能。

我决定用节流(throttle)来控制渲染频率,比如每100ms最多渲染一次。let lastRenderTime = 0;

const throttleTime = 100;

const now = Date.now();

if (now - lastRenderTime > throttleTime) {

lastRenderTime = now;

scrollTop = container.scrollTop;

render();

}

});

这下页面流畅多了,但新问题又来了:如果用户快速滚动到页面底部,需要渲染的数据量过大,导致渲染时间过长。于是,填坑第九步:分块渲染。

我决定把数据分成多个块,每个块单独渲染,减少单次渲染的数据量。const chunkSize = 1000;

let currentChunk = 0;

function renderChunk() {

const start = currentChunk

chunkSize;

const end = start + chunkSize;

fetch(/api/getData?offset=${ start }&limit=${ chunkSize })

currentChunk++;

requestAnimationFrame(renderChunk);

}

if (container.scrollTop + container.clientHeight >= container.scrollHeight) {

renderChunk();

}

});

这样即使是百万级别的数据,也能流畅地渲染出来。不过,问题又来了:如果用户频繁滚动,可能会导致重复渲染。于是,填坑第十步:缓存已渲染的数据。

我决定用个数组来记录哪些数据已经渲染过了,避免重复渲染。const rendered = [];

if (rendered.includes(currentChunk)) return;

rendered.push(currentChunk);

}

这下性能终于达到了预期,用户可以流畅地浏览百万级别的数据了。

总结一下,PHP大数据渲染的坑确实不少,但通过分批处理、异步渲染、虚拟滚动、分块渲染等技术手段,最终还是填上了这些坑。希望这篇分享能帮到同样遇到这类问题的朋友。

基于matlab目标雷达横截面建模(附源码) 雷达系统依靠目标反射或散射来检测和识别目标。目标反射越强,雷达接收器返回的回波就越大,从而获得更高的信噪比(SNR)和更高的检测可能性。在雷达系统中,从目标反射的能量由雷达横截面(RCS)决定,定义为sigma代表RCS,R是雷达与目标之间的距离,Es是从目标反射的信号的场强,以及Ei是入射到目标上的信号的场强。通常,目标向各个方向散射能量,RCS是入射角,散射角和信号频率的函数。RCS 取决于目标的形状和构建目标的材料。用于RCS的常用单位包括平方米或dBsm。 阅读详情

相关推荐

车辆动力学从入门到进阶之路(传统篇)

新手如何入门车辆动力学开发领域,本文为您引路!

CrazyRabbit的博客 1万+

php页面渲染

本篇文章主要讲解不使用任何模板引擎来渲染页面数据的原生php方式. 1.输出数据 可以使用 以下两种方法: <div><?= $title ?></div> <div><?php echo $title ?></div> 案例: 2....

brokenkay的博客 5162

ROS2前置基础教程 | 小鱼教你用CMake依赖查找流程

上面我们用g++、make、cmake三种方式来编译ros2的C++节点。用cmake虽然成功了,但是CMakeLists.txt的内容依然非常的臃肿,我们需要将其进一步的简化。将上面的CmakLists.txt改成下面的样子 接着继续生成和编译 是不是非常的神奇,为什么可以浓缩成那么短的几句指令呢?find_package查找路径对应的环境变量如下。 打开终端,输入指令: 结果 观察PATH变量,你会发现赫然在其中,中的路径如果以或结尾,则自动回退到上一级目录,接着检查这些目录下的 cmake找到这些目录

生活不止眼前的苟且 7162

推荐开源项目:PHP-View - 简单高效的PHP视图渲染器

推荐开源项目:PHP-View - 简单高效的PHP视图渲染器 在寻求高效且易于使用的PHP模板引擎时,我们发现了一款名为PHP-View的优秀开源项目。这个轻量级的库允许开发者将PHP脚本转化为PSR-7响应对象,特别适合与Slim Framework 4搭配使用。 1. 项目介绍 PHP-View是一个简洁的视图渲染器,旨在帮助开发者构建动态网页应用。它支持在模板中嵌套子模板,并可以使用布局文...

gitblog_00095的博客 658

手把手教你用ADS和CGH40010F模型搭建Doherty功放仿真原型(附工程文件)

本文详细介绍了如何使用ADS软件和CGH40010F GaN器件模型搭建Doherty功放仿真原型,涵盖工程准备、关键电路模块实现、效率优化技巧及常见问题排查。通过实战指南和效率优化技巧,帮助工程师快速掌握Doherty功放设计,提升5G基站和广播发射系统的功率放大器性能。

weixin_26897585的博客 345

Kubeflow系统性学习教程:从入门到高级实践

Kubeflow学习教程摘要(150字): Kubeflow是基于Kubernetes的云原生MLOps平台,提供端到端机器学习解决方案。核心功能包括Jupyter Notebooks开发环境、Pipelines工作流编排、分布式训练支持和模型服务部署。教程采用三阶段学习路径:初学者搭建Kind集群体验Notebooks;中级开发自定义Pipeline组件;高级实现企业级应用。通过容器化和K8s CRD深度集成,解决环境一致性、实验跟踪和资源调度等MLOps痛点,相比MLflow/Airflow更适合大规模

自可乐的博客 887

浅谈PHP导出百万excel问题解决思路与解决方案

前两年做外包时候的事了,记录一下吧,也正好梳理一下思路,温故而知新。 php导出excel,数据量小的时候使用phpexcel可轻松解决问题,仅仅限于5w行以下数据,但实际上我在使用phpexcel导出4w行数据的时候就出问题了: 一开始是报内存溢出,然后随手给了1g内存,当然是程序里ini_set动态设置没动配置文件。 然后又报运行时间超过30秒,我又设置了在程序执行完在结束 又过了一段...

编程哲学家的专栏 1131

树莓派 5 AI 套件(Hailo)示例

该用户自定义类作为输入传递给回调函数,该函数在管道输出上运行。它用于主程序与回调函数之间的通信。它对 hailo_rpi_common::app_callback_class 进行了扩展,并可根据应用程序的具体情况定制附加变量和方法。

机器人控制与仿真应用 4115

什么是php渲染,php数据渲染输出

关键是要把页面上的静态不变的部分和需要动态加载的部分分离开来,以下是我的异步动态加载数据的方法,不知道有没有解决楼主的问题$(document).ready(function() {/*从服务器端取回数据*/$.ajax({url: URL_getData, // 服务器端从数据库取数据的php文件的url地址,如http://111.222.33.44/getData.phptype: "POS...

weixin_28894691的博客 629

1.4 KFD 设备文件的获取与驱动握手协议

本文分析了OpenClose模块中libhsakmt与KFD内核驱动建立通信的过程。首先通过hsaKmtOpenKFD()函数打开/dev/kfd设备文件,建立用户态与内核态的通信通道。随后通过AMDKFD_IOC_GET_VERSION ioctl命令完成版本握手,确认双方的接口兼容性。KFD驱动采用Major.Minor二级版本号体系,当前主要版本为1,从1.1演进到1.19不断添加新功能。整个过程构成了用户态与内核态之间的"建连协议",是所有后续GPU操作的基础前提。

图形/计算GPU的驱动与虚拟化技术分享园地 607

Python爬虫实战:爬取ETF基金持仓变化

在python复制编辑本文详细介绍了如何使用Python的Scrapy框架爬取ETF基金的持仓变化信息,包括项目的搭建、数据的提取与存储、以及数据的可视化分析。通过本项目,读者可以掌握基本的网页爬虫技术,并应用于实际的财经数据采集与分析中。

2201_76125261的博客 629

如何用php直接渲染页面,总结浏览器渲染页面的方法

转载自web fundamental构建对象模型浏览器渲染页面前需要先构建 DOM 和 CSSOM 树。因此,我们需要确保尽快将 HTML 和 CSS 都提供给浏览器。字节 → 字符 → 标记 → 节点 → 对象模型。HTML 标记转换成文档对象模型 (DOM);CSS 标记转换成 CSS 对象模型 (CSSOM)。DOM 和 CSSOM 是独立的数据结构。Chrome DevTools Time...

weixin_33212263的博客 1249

【实验】ENSP 实战:酒店有线 + 无线三层组网全配置(VLAN 规划 + AC/AP+SSID 绑定)

三层架构:出口路由器 → 核心交换机 → 汇聚交换机 → 接入交换机 / AP / 终端。

jundao1997的专栏 431

PHP 8.7新特性深度解析(基于百万级请求压测数据)

深入解析PHP 8.7新特性并结合百万级请求性能测试,揭示高并发场景下的优化策略与执行效率提升。涵盖JIT改进、内存管理升级及真实压测数据对比,助你掌握下一代PHP性能调优方法,值得收藏。

LiteCompile的博客 898

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【PHP大文件下载接口优化秘籍】:揭秘百万级文件传输性能提升的5大核心技术

掌握PHP大文件下载接口优化核心技巧,解决卡顿与内存溢出问题。适用于视频、大附件等场景,通过分块读取、断点续传、内存控制等5大技术显著提升传输效率。百万级文件稳定下载,性能提升90%以上,值得收藏。

ProceGlow的博客 732

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

【独家】ThinkPHP在百万级数据场景下的SQL优化实战案例

解决百万级数据查询性能瓶颈,本文深入剖析PHP ThinkPHP框架在高并发场景下的SQL优化策略,涵盖索引设计、查询缓存与分页优化等实战技巧。提升系统响应速度,降低数据库负载,ThinkPHP开发者值得收藏的优化指南,点击了解具体实现方案。

CompiShoal的博客 307

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

php超大树形分页,PHP+MySql千万级数据limit分页优化方案

PHP+MySql千万级数据limit分页优化方案1年前阅读 2750评论 0喜欢 0### 原因徒弟突然有个需求,就是他发现limit分页,页数越大之后,mysql的消耗越大,查询时间越长,当突破百万级数据之后,一个简单的翻页都需要5-6秒,极其不方便。### 测试数据库结构```CREATE TABLE IF NOT EXISTS `video_info` (`id` int(10) unsi...

weixin_28736335的博客 626

php分页limit排序,PHP+MySql千万级数据limit分页优化方案

PHP+MySql千万级数据limit分页优化方案1年前阅读 2790评论 0喜欢 0### 原因徒弟突然有个需求,就是他发现limit分页,页数越大之后,mysql的消耗越大,查询时间越长,当突破百万级数据之后,一个简单的翻页都需要5-6秒,极其不方便。### 测试数据库结构```CREATE TABLE IF NOT EXISTS `video_info` (`id` int(10) unsi...

weixin_42560530的博客 507

从零到百万并发:用Go+PHP手搓一个直播系统,我踩了哪些坑?

本文详细介绍了使用Go+PHP构建高并发直播系统的实战经验,涵盖技术选型、架构演进、性能优化及容灾设计。通过PHP的快速开发与Go的高并发处理能力结合,成功应对百万级并发挑战,并分享了流媒体服务器选型、消息队列优化等关键问题的解决方案。

weixin_28712661的博客 318

AI短剧创作系统源码(PHP+MySQL+Uniapp)实现方案

MySQL数据库设计需包含多租户标识字段(tenant_id),所有数据表增加该字段实现租户隔离。PHP后端采用ThinkPHP或Laravel框架,通过中间件实现租户鉴权。采用B/S架构模式,前端基于Uniapp跨平台框架,后端使用PHP+MySQL组合。系统支持SAAS多租户模式,通过账号隔离实现无限扩展能力。核心模块包括剧本生成器、角色管理、场景编辑器、AI语音合成和视频渲染引擎。该系统可实现日均百万级剧本创作请求处理,视频渲染支持1080P分辨率输出,平均响应时间控制在500ms以内。

2401_86439998的博客 749

Dompdf大数据报表优化:虚拟滚动与分页加载技术

在数据可视化领域,PHP开发者常常面临将海量数据转换为PDF报表的挑战。当处理超过10万行数据时,传统一次性渲染方式往往导致内存溢出(Memory Exhausted)错误或长达数分钟的生成延迟。本文将系统介绍基于Dompdf(HTML to PDF converter for PHP)的大数据报表优化方案,通过虚拟滚动(Virtual Scrolling)与分页加载(Pagination Loa...

gitblog_00185的博客 525

【PHP开发900个实用技巧】530.地理信息处理:PHP空间数据分析与可视化

### PHP空间数据分析与可视化实战指南 空间数据处理和可视化是开发中常见的复杂任务,尤其是在需要处理地理位置信息时。通过合理的设计和优化,可以高效地完成从数据存储到可视化的全流程。以下是PHP空间数据分析与可视化的核心策略和实践方法。 --- #### 1. 地理信息基础:数据类型与常见陷阱 **痛点**:将经纬度存储为字符串格式,导致查询效率低下。 **解决方案**:使用MySQL的空间数据类型(如`POINT`)和空间索引。 ```sql CREATE TABLE shops (

1054

10倍提速!Laravel Fast Paginate让百万级数据分页不再卡顿

> 推荐搭配使用:laravel-debugbar查看SQL执行计划,Clockwork分析请求性能瓶颈 掌握Fast Paginate不仅解决了当前的性能问题,更重要的是理解了数据库查询优化的核心思想。在数据持续增长的今天,这种优化思维将帮助你构建更高性能、更具扩展性的Laravel应用。 如果你在使用过程中获得了显著性能提升,欢迎在评论区分享你的测试数据和优化经验!下一篇我们将深入探讨"L

gitblog_00223的博客 479

PHP foreach剖析高效迭代数组技巧与实战

《怪物猎人:荒野》索尼特别舞台活动公开新情报!

Aa211223的博客 718

避开这些坑!PHP开源OA系统二次开发必知的5个核心技巧

本文分享了PHP开源OA系统二次开发中的5个核心技巧,包括权限体系改造、审批流定制、MySQL性能优化、前后端分离策略及日志监控增强。针对TP5+HAdmin架构,提供实战代码示例,帮助企业避开常见开发陷阱,提升系统性能和可用性。特别适合需要深度定制办公管理系统的开发者参考。

weixin_30595035的博客 404

农业PHP可视化工具链终极对比:Laravel Livewire vs. CodeIgniter + D3.js,谁扛得住万亩大棚并发?

面向智慧农业场景,提供高效稳定的农业PHP可视化工具选型方案。对比Laravel Livewire与CodeIgniter+D3.js在万亩大棚实时数据监控、高并发图表渲染及低延迟交互中的表现,涵盖架构适配性、开发效率与部署成本。真实压测数据支撑决策,值得收藏。

VarFun的博客 353
上一篇: 视频抄袭泛滥?教你几招看透那些偷工减料的作品
下一篇: PHP渲染百万级数据,你踩过这些坑吗?
普通网友
博客等级 码龄2年 91粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值