Symfony环境下Webpack加载JS文件过慢问题排查与解决
Symfony Encore 资源加载缓慢问题排查与解决
问题背景
我在Ubuntu 20.04系统上部署了Symfony 6.1.5 + PHP 8.1,搭配Nginx 1.18.0和MySQL 5.7。通过composer require symfony/webpack-encore-bundle引入Encore,执行yarn install完成依赖安装。将CSS、JS文件放在assets目录,在app.js中导入这些资源后功能正常,但资源加载耗时极长——Chrome网络面板显示JS文件加载耗时分别达到23秒和19秒。
我的webpack.config.js配置
const Encore = require('@symfony/webpack-encore'); // Manually configure the runtime environment if not already configured yet by the // "encore" command. // It's useful when you use tools that rely on webpack.config.js file. if (!Encore.isRuntimeEnvironmentConfigured()) { Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev'); } Encore // directory where compiled assets will be stored .setOutputPath('public/build/') // public path used by the web server to access the output path .setPublicPath('/build') // only needed for CDN's or subdirectory deploy //.setManifestKeyPrefix('build/') /* * ENTRY CONFIG * * Each entry will result in one JavaScript file (e.g. app.js) * and one CSS file (e.g. app.css) if your JavaScript imports CSS. */ .addEntry('app', './assets/app.js') // enables the Symfony UX Stimulus bridge (used in assets/bootstrap.js) .enableStimulusBridge('./assets/controllers.json') // When enabled, Webpack "splits" your files into smaller pieces for greater optimization. .splitEntryChunks() // will require an extra script tag for runtime.js // but, you probably want this, unless you're building a single-page app .enableSingleRuntimeChunk() /* * FEATURE CONFIG * * Enable & configure other features below. For a full * list of features, see: * https://symfony.com/doc/current/frontend.html#adding-more-features */ .cleanupOutputBeforeBuild() .enableBuildNotifications() .enableSourceMaps(!Encore.isProduction()) // enables hashed filenames (e.g. app.abc123.css) .enableVersioning(Encore.isProduction()) // configure Babel // .configureBabel((config) => { // config.plugins.push('@babel/a-babel-plugin'); // }) // enables and configure @babel/preset-env polyfills .configureBabelPresetEnv((config) => { config.useBuiltIns = 'usage'; config.corejs = '3.23'; }) // enables Sass/SCSS support //.enableSassLoader() // uncomment if you use TypeScript //.enableTypeScriptLoader() // uncomment if you use React //.enableReactPreset() // uncomment to get integrity="..." attributes on your script & link tags // requires WebpackEncoreBundle 1.4 or higher //.enableIntegrityHashes(Encore.isProduction()) // uncomment if you're having problems with a jQuery plugin .autoProvideVariables({ $: 'jquery', jQuery: 'jquery', 'window.jQuery': 'jquery' }) ; module.exports = Encore.getWebpackConfig();
我的app.js内容
// any CSS you import will output into a single css file (app.css in this case) import './css/bootstrap.min.css'; import './css/templatemo-style.css'; import './fontawesome/css/all.min.css'; import './js/plugins'; // start the Stimulus application import './bootstrap';
可能原因
- 开发环境资源未优化:默认
dev环境下生成的资源包含完整源码映射,文件体积大且未压缩。 - Chunk拆分增加请求开销:
splitEntryChunks()和enableSingleRuntimeChunk()在开发环境下会生成多个小文件,增加HTTP请求数,拖慢加载速度。 - Nginx未配置静态资源缓存:静态文件无缓存策略,每次请求都需重新下载。
- Polyfill冗余引入:Babel的
useBuiltIns: 'usage'可能自动引入大量不必要的polyfill,导致文件体积膨胀。
解决步骤
1. 生产环境构建优化资源
生产模式会自动压缩代码、移除源码映射、优化文件哈希,大幅降低加载耗时:
yarn run encore production
构建完成后,Symfony会自动引用带哈希的优化资源,浏览器会长期缓存这些文件。
2. 调整开发环境配置
如果是开发阶段需要快速加载,修改webpack.config.js关闭不必要的特性:
Encore // 关闭开发环境源码映射(牺牲调试速度换加载性能) .enableSourceMaps(false) // 禁用chunk拆分,减少请求数 .splitEntryChunks(false) // 禁用单独的runtime chunk .disableSingleRuntimeChunk()
执行yarn run encore dev重新构建开发版资源。
3. 配置Nginx静态资源缓存
在站点Nginx配置中添加缓存规则,避免重复请求静态资源:
location /build/ { expires 1y; add_header Cache-Control "public, immutable"; access_log off; }
重启Nginx生效:
sudo systemctl restart nginx
4. 精简依赖与按需加载
- 检查
assets/js/plugins,移除未使用的库,按需引入所需功能。 - 调整Babel配置,改为手动引入polyfill,避免冗余:
.configureBabelPresetEnv((config) => { config.useBuiltIns = 'entry'; config.corejs = '3.23'; })
在app.js顶部手动导入必要的polyfill:
import 'core-js/stable'; import 'regenerator-runtime/runtime';
5. 开发环境启用热更新服务器
使用Encore内置的热更新服务器,实现资源实时更新且加载更快:
yarn run encore dev-server --hot
访问http://localhost:8080即可体验快速加载的开发环境。
内容的提问来源于stack exchange,提问作者Roman Zagday
相关产品推荐
相关产品推荐

