- 浏览: 13413 次
- 性别:
- 来自: 北京
-
文章分类
最新评论
最近在对一个web系统做性能优化.
而对用到的静态资源文件的压缩整合则是前端性能优化中很重要的一环.
好处不仅在于能够减小请求的文件体积,而且能够减少浏览器的http请求数.
因为是基于java的web系统,并且使用的是nginx+tomcat做为服务器.
最后考虑用wro4j和maven plugin在编译期间压缩静态资源.
优化前:
基本上所有的jsp都引用了这一大坨静态文件:
引用的文件很多,并且文件体积没有压缩,导致页面请求的时间非常长.
另外还有一个问题,就是为了能够充分利用浏览器的缓存,静态资源的文件名称最好能够做到版本化控制.
这样前端web服务器就可以放心大胆的开启缓存功能而不用担心缓存过期问题,因为如果一旦静态资源文件有修改的话,
会重新生成一个文件名称.
下面我根据自己项目的经验,来介绍下如何较好的解决这两个问题.
分两步进行.
第一步:引入wro4j,在编译时期将上述分散的多个文件整合成少数几个文件,并且将文件最小化.
第二步:在生成的静态资源文件的文件名称上加入时间信息
这是两步优化之后的引用情况:
只引用了1个css文件,2个js文件.http请求从10几个减少到3个,并且整体文件体积缩小了近一半.
下面介绍优化流程.
第一步:合并并且最小化文件.
1.添加wro4j的maven依赖
2.添加wro4j maven plugin
如果开发环境是eclipse的话,可以下载m2e-wro4j这个插件.
下载地址:http://download.jboss.org/jbosstools/updates/m2e-wro4j/
这个插件的主要功能是能够帮助我们在开发环境下修改对应的静态文件,或者pom.xml文件的时候能够自动生成打包好的js和css文件.
对开发来说就会方便很多.只要修改源文件就能看见修改后的结果.
3.在WEB-INF目录下添加wro.xml文件,这个文件的作用就是告诉wro4j需要以怎样的策略打包jss和css文件.
官方文档:http://code.google.com/p/wro4j/wiki/WroFileFormat
其实这个配置文件很好理解,如果不愿看官方文档的朋友我在这简单介绍下.
上面这样配置的目的就是告诉wro4j要将
<css>/css/basic.css</css>
<css>/css/skin.css</css>
<css>/css/jquery-ui-1.8.23.custom.css</css>
<css>/css/validationEngine.jquery.css</css>
这四个文件整合到一起,生成一个叫basic.css的文件到指定目录(wro4j-maven-plugin里配置的),将
<js>/js/jquery-1.7.2.min.js</js>
<js>/js/jquery-ui-1.8.23.custom.min.js</js>
<js>/js/jquery.validationEngine.js</js>
<js>/js/jquery.fixedtableheader.min.js</js>
<js>/js/roll.js</js>
<js>/js/jquery.pagination.js</js>
<js>/js/jquery.rooFixed.js</js>
<js>/js/jquery.ui.datepicker-zh-CN.js</js>
<js>/js/json2.js</js>
这几个文件整合到一起,生成一个叫basic.js的文件到指定目录.
最后将
<js>/js/jquery.validationEngine-zh_CN.js</js>
<js>/js/common.js</js>
这两个文件整合到一起,,生成一个叫custom.js的文件到指定目录.
第一步搞定,这时候如果你的开发环境是eclipse并且安装了插件的话,应该就能在你工程的%your webapp%/wor/目录下看见生成好的
basic.css,basic.js和custom.js这三个文件了.
然后你再将你的静态资源引用路径改成
就ok了.每次修改被引用到的css或js文件的时候,这些文件都将重新生成.
如果开发环境是eclipse但是没有安装m2e-wro4j插件的话,pom.xml可能需要额外配置.
请参考:https://community.jboss.org/en/tools/blog/2012/01/17/css-and-js-minification-using-eclipse-maven-and-wro4j
第二步:给生成的文件名称中加入时间信息并通过el自定义函数引用脚本文件.
1. 创建DailyNamingStrategy类
2.创建CustomWroManagerFactory类
上面这两个类的作用是使用wro4j提供的文件命名策略,这样生成的文件名就会带上时间信息了.
例如:basic-2013020217.js
但是现在又会发现一个问题:如果静态资源文件名称不固定的话,那怎么样引用呢?
这时候就需要通过动态生成<script>与<link>来解决了.
因为项目使用的是jsp页面,所以通过el自定义函数来实现标签生成.
3.创建PlatformFunction类
对应的tld文件就不给出了,根据方法签名编写就行了.
其中的cssFile和jsFile方法分别实现引用css和js文件.
在页面使用的时候类似这样:
${platform:cssFile("/wro/basic") }
${platform:jsFile("/wro/custom") }
这个类的主要功能就是使用jdk7的WatchService监控wro目录的新增文件事件,
一旦有新的文件加到目录里,判断这个文件是不是最新的,如果是的话则使用这个文件名称引用.
这样一旦有新加的资源文件放到wro目录里,则能够自动被引用,不需要做任何代码上的修改,并且基本不影响性能.
到此为止功能已经实现.
但是我考虑到还有两个问题有待完善:
1.因为生成的文件名称精确到小时,如果这个小时之内有多次代码修改,生成的文件名都完全一样.
这样就算线上的代码有修改,对于已经有该文本缓存的浏览器来说,不会重新请求文件,也就看不到文件变化.
不过一般来说线上代码不会如此频繁改动,对于大多数应用来说影响不大.
2.在开发环境开发一段时间之后,wro目录下会生成一大堆的文件(因为m2e-wro4j插件在生成新的文件的时候不会删除旧文件,如果文件名相同会覆盖掉以前的文件),
这时候就需要手动删除时间靠前的旧文件,虽然系统会忽略旧文件,但是我相信大多数程序员和我一样是有些许洁癖的吧.
解决办法还是不少,比如可以写脚本定期清理掉旧文件.
时间有限,有些地方考虑的不是很完善,欢迎拍砖.
参考资料:
http://meri-stuff.blogspot.sk/2012/08/wro4j-page-load-optimization-and-lessjs.html#Configuration
https://community.jboss.org/en/tools/blog/2012/01/17/css-and-js-minification-using-eclipse-maven-and-wro4j
http://code.google.com/p/wro4j/wiki/MavenPlugin
http://code.google.com/p/wro4j/wiki/WroFileFormat
http://java.dzone.com/articles/using-java-7s-watchservice
而对用到的静态资源文件的压缩整合则是前端性能优化中很重要的一环.
好处不仅在于能够减小请求的文件体积,而且能够减少浏览器的http请求数.
因为是基于java的web系统,并且使用的是nginx+tomcat做为服务器.
最后考虑用wro4j和maven plugin在编译期间压缩静态资源.
优化前:
基本上所有的jsp都引用了这一大坨静态文件:
<link rel="stylesheet" type="text/css" href="${ctxPath}/css/skin.css"/> <link rel="stylesheet" type="text/css" href="${ctxPath}/css/jquery-ui-1.8.23.custom.css"/> <link rel="stylesheet" type="text/css" href="${ctxPath}/css/validationEngine.jquery.css"/> <script type="text/javascript">var GV = {ctxPath: '${ctxPath}',imgPath: '${ctxPath}/css'};</script> <script type="text/javascript" src="${ctxPath}/js/jquery-1.7.2.min.js"></script> <script type="text/javascript" src="${ctxPath}/js/jquery-ui-1.8.23.custom.min.js"></script> <script type="text/javascript" src="${ctxPath}/js/jquery.validationEngine.js"></script> <script type="text/javascript" src="${ctxPath}/js/jquery.validationEngine-zh_CN.js"></script> <script type="text/javascript" src="${ctxPath}/js/jquery.fixedtableheader.min.js"></script> <script type="text/javascript" src="${ctxPath}/js/roll.js"></script> <script type="text/javascript" src="${ctxPath}/js/jquery.pagination.js"></script> <script type="text/javascript" src="${ctxPath}/js/jquery.rooFixed.js"></script> <script type="text/javascript" src="${ctxPath}/js/jquery.ui.datepicker-zh-CN.js"></script> <script type="text/javascript" src="${ctxPath}/js/json2.js"></script> <script type="text/javascript" src="${ctxPath}/js/common.js"></script>
引用的文件很多,并且文件体积没有压缩,导致页面请求的时间非常长.
另外还有一个问题,就是为了能够充分利用浏览器的缓存,静态资源的文件名称最好能够做到版本化控制.
这样前端web服务器就可以放心大胆的开启缓存功能而不用担心缓存过期问题,因为如果一旦静态资源文件有修改的话,
会重新生成一个文件名称.
下面我根据自己项目的经验,来介绍下如何较好的解决这两个问题.
分两步进行.
第一步:引入wro4j,在编译时期将上述分散的多个文件整合成少数几个文件,并且将文件最小化.
第二步:在生成的静态资源文件的文件名称上加入时间信息
这是两步优化之后的引用情况:
${platform:cssFile("/wro/basic") } <script type="text/javascript">var GV = {ctxPath: '${ctxPath}',imgPath: '${ctxPath}/css'};</script> ${platform:jsFile("/wro/basic") } ${platform:jsFile("/wro/custom") }
只引用了1个css文件,2个js文件.http请求从10几个减少到3个,并且整体文件体积缩小了近一半.
下面介绍优化流程.
第一步:合并并且最小化文件.
1.添加wro4j的maven依赖
<wro4j.version>1.6.2</wro4j.version> ... <dependency> <groupId>ro.isdc.wro4j</groupId> <artifactId>wro4j-core</artifactId> <version>${wro4j.version}</version> <exclusions> <exclusion> <!-- 因为项目中的其他jar包已经引入了不同版本的slf4j,所以这里避免jar重叠所以不引入 --> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> </exclusions> </dependency>
2.添加wro4j maven plugin
<plugin> <groupId>ro.isdc.wro4j</groupId> <artifactId>wro4j-maven-plugin</artifactId> <version>${wro4j.version}</version> <executions> <execution> <phase>compile</phase> <goals> <goal>run</goal> </goals> </execution> </executions> <configuration> <targetGroups>basic,custom</targetGroups> <!-- 这个配置是告诉wro4j在打包静态资源的时候是否需要最小化文件,开发的时候可以设成false,方便调试 --> <minimize>true</minimize> <destinationFolder>${basedir}/src/main/webapp/wro/</destinationFolder> <contextFolder>${basedir}/src/main/webapp/</contextFolder> <!-- 这个配置是第二步优化需要用到的,暂时忽略 --> <wroManagerFactory>com.rootrip.platform.common.web.wro.CustomWroManagerFactory</wroManagerFactory> </configuration> </plugin>
如果开发环境是eclipse的话,可以下载m2e-wro4j这个插件.
下载地址:http://download.jboss.org/jbosstools/updates/m2e-wro4j/
这个插件的主要功能是能够帮助我们在开发环境下修改对应的静态文件,或者pom.xml文件的时候能够自动生成打包好的js和css文件.
对开发来说就会方便很多.只要修改源文件就能看见修改后的结果.
3.在WEB-INF目录下添加wro.xml文件,这个文件的作用就是告诉wro4j需要以怎样的策略打包jss和css文件.
<?xml version="1.0" encoding="UTF-8"?> <groups xmlns="http://www.isdc.ro/wro" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isdc.ro/wro wro.xsd"> <group name="basic"> <css>/css/basic.css</css> <css>/css/skin.css</css> <css>/css/jquery-ui-1.8.23.custom.css</css> <css>/css/validationEngine.jquery.css</css> <js>/js/jquery-1.7.2.min.js</js> <js>/js/jquery-ui-1.8.23.custom.min.js</js> <js>/js/jquery.validationEngine.js</js> <js>/js/jquery.fixedtableheader.min.js</js> <js>/js/roll.js</js> <js>/js/jquery.pagination.js</js> <js>/js/jquery.rooFixed.js</js> <js>/js/jquery.ui.datepicker-zh-CN.js</js> <js>/js/json2.js</js> </group> <group name="custom"> <js>/js/jquery.validationEngine-zh_CN.js</js> <js>/js/common.js</js> </group> </groups>
官方文档:http://code.google.com/p/wro4j/wiki/WroFileFormat
其实这个配置文件很好理解,如果不愿看官方文档的朋友我在这简单介绍下.
上面这样配置的目的就是告诉wro4j要将
<css>/css/basic.css</css>
<css>/css/skin.css</css>
<css>/css/jquery-ui-1.8.23.custom.css</css>
<css>/css/validationEngine.jquery.css</css>
这四个文件整合到一起,生成一个叫basic.css的文件到指定目录(wro4j-maven-plugin里配置的),将
<js>/js/jquery-1.7.2.min.js</js>
<js>/js/jquery-ui-1.8.23.custom.min.js</js>
<js>/js/jquery.validationEngine.js</js>
<js>/js/jquery.fixedtableheader.min.js</js>
<js>/js/roll.js</js>
<js>/js/jquery.pagination.js</js>
<js>/js/jquery.rooFixed.js</js>
<js>/js/jquery.ui.datepicker-zh-CN.js</js>
<js>/js/json2.js</js>
这几个文件整合到一起,生成一个叫basic.js的文件到指定目录.
最后将
<js>/js/jquery.validationEngine-zh_CN.js</js>
<js>/js/common.js</js>
这两个文件整合到一起,,生成一个叫custom.js的文件到指定目录.
第一步搞定,这时候如果你的开发环境是eclipse并且安装了插件的话,应该就能在你工程的%your webapp%/wor/目录下看见生成好的
basic.css,basic.js和custom.js这三个文件了.
然后你再将你的静态资源引用路径改成
<link rel="stylesheet" type="text/css" href="${ctxPath}/wro/basic.css"/> <script type="text/javascript" src="${ctxPath}/wro/basic.js"></script> <script type="text/javascript" src="${ctxPath}/wro/custom.js"></script>
就ok了.每次修改被引用到的css或js文件的时候,这些文件都将重新生成.
如果开发环境是eclipse但是没有安装m2e-wro4j插件的话,pom.xml可能需要额外配置.
请参考:https://community.jboss.org/en/tools/blog/2012/01/17/css-and-js-minification-using-eclipse-maven-and-wro4j
第二步:给生成的文件名称中加入时间信息并通过el自定义函数引用脚本文件.
1. 创建DailyNamingStrategy类
public class DailyNamingStrategy extends TimestampNamingStrategy { protected final Logger log = LoggerFactory.getLogger(DailyNamingStrategy.class); @Override protected long getTimestamp() { String dateStr = DateUtil.formatDate(new Date(), "yyyyMMddHH"); return Long.valueOf(dateStr); } }
2.创建CustomWroManagerFactory类
//这个类就是在wro4j-maven-plugin里配置的wroManagerFactory参数 public class CustomWroManagerFactory extends DefaultStandaloneContextAwareManagerFactory { public CustomWroManagerFactory() { setNamingStrategy(new DailyNamingStrategy()); } }
上面这两个类的作用是使用wro4j提供的文件命名策略,这样生成的文件名就会带上时间信息了.
例如:basic-2013020217.js
但是现在又会发现一个问题:如果静态资源文件名称不固定的话,那怎么样引用呢?
这时候就需要通过动态生成<script>与<link>来解决了.
因为项目使用的是jsp页面,所以通过el自定义函数来实现标签生成.
3.创建PlatformFunction类
public class PlatformFunction { private static Logger log = LoggerFactory.getLogger(PlatformFunction.class); private static ConcurrentMap<String, String> staticFileCache = new ConcurrentHashMap<>(); private static AtomicBoolean initialized = new AtomicBoolean(false); private static final String WRO_Path = "/wro/"; private static final String JS_SCRIPT = "<script type=\"text/javascript\" src=\"%s\"></script>"; private static final String CSS_SCRIPT = "<link rel=\"stylesheet\" type=\"text/css\" href=\"%s\">"; private static String contextPath = null; /** * 该方法根据给出的路径,生成js脚本加载标签 * 例如传入参数/wro/custom,该方法会寻找webapp路径下/wro目录中以custom开头,以js后缀结尾的文件名称名称. * 然后拼成<script type="text/javascript" src="${ctxPath}/wro/custom-20130201.js"></script>返回 * 如果查找到多个文件,返回根据文件名排序最大的文件 * @param str * @return */ public static String jsFile(String filePath) { String jsFile = staticFileCache.get(buildCacheKey(filePath, "js")); if(jsFile == null) { log.error("加载js文件失败,缓存中找不到对应的文件[{}]", filePath); } return String.format(JS_SCRIPT, jsFile); } /** * 该方法根据给出的路径,生成css脚本加载标签 * 例如传入参数/wro/custom,该方法会寻找webapp路径下/wro目录中以custom开头,以css后缀结尾的文件名称名称. * 然后拼成<link rel="stylesheet" type="text/css" href="${ctxPath}/wro/basic-20130201.css">返回 * 如果查找到多个文件,返回根据文件名排序最大的文件 * @param str * @return */ public static String cssFile(String filePath) { String cssFile = staticFileCache.get(buildCacheKey(filePath, "css")); if(cssFile == null) { log.error("加载css文件失败,缓存中找不到对应的文件[{}]", filePath); } return String.format(CSS_SCRIPT, cssFile); } public static void init() throws IOException { if(initialized.compareAndSet(false, true)) { ServletContext sc = Platform.getInstance().getServletContext(); if(sc == null) { throw new PlatformException("查找静态资源的时候的时候发现servlet context 为null"); } contextPath = Platform.getInstance().getContextPath(); File wroDirectory = new ServletContextResource(sc, WRO_Path).getFile(); if(!wroDirectory.exists() || !wroDirectory.isDirectory()) { throw new PlatformException("查找静态资源的时候发现对应目录不存在[" + wroDirectory.getAbsolutePath() + "]"); } //将wro目录下已有文件加入缓存 for(File file : wroDirectory.listFiles()) { handleNewFile(file); } //监控wro目录,如果有文件生成,则判断是否是较新的文件,是的话则把文件名加入缓存 new Thread(new WroFileWatcher(wroDirectory.getAbsolutePath())).start(); } } private static void handleNewFile(File file) { String fileName = file.getName(); Pattern p = Pattern.compile("^(\\w+)\\-\\d+\\.(js|css)$"); Matcher m = p.matcher(fileName); if(!m.find() || m.groupCount() < 2) return; String fakeName = m.group(1); String fileType = m.group(2); //暂时限定只能匹配/wro/目录下的文件 String key = buildCacheKey(WRO_Path + fakeName, fileType); if(staticFileCache.putIfAbsent(key, fileName) != null) { synchronized(staticFileCache) { String cachedFileName = staticFileCache.get(key); if(fileName.compareTo(cachedFileName) > 0) { staticFileCache.put(key, contextPath + WRO_Path + fileName); } } } } private static String buildCacheKey(String fakeName, String fileType) { return fakeName + "-" + fileType; } static class WroFileWatcher implements Runnable { private static Logger log = LoggerFactory.getLogger(WroFileWatcher.class); private String wroAbsolutePathStr; public WroFileWatcher(String wroPathStr) { this.wroAbsolutePathStr = wroPathStr; } @Override public void run() { Path path = Paths.get(wroAbsolutePathStr); File wroDirectory = path.toFile(); if(!wroDirectory.exists() || !wroDirectory.isDirectory()) { String message = "监控wro目录的时候发现对应目录不存在[" + wroAbsolutePathStr + "]"; log.error(message); throw new PlatformException(message); } log.warn("开始监控wro目录[{}]", wroAbsolutePathStr); try { WatchService watcher = FileSystems.getDefault().newWatchService(); path.register(watcher, StandardWatchEventKinds.ENTRY_CREATE); while (true) { WatchKey key = null; try { key = watcher.take(); } catch (InterruptedException e) { log.error("", e); continue; } for (WatchEvent<?> event : key.pollEvents()) { if (event.kind() == StandardWatchEventKinds.OVERFLOW) { continue; } WatchEvent<Path> e = (WatchEvent<Path>) event; Path filePath = e.context(); handleNewFile(filePath.toFile()); } if (!key.reset()) { break; } } } catch (IOException e) { log.error("监控wro目录发生错误", e); } log.warn("停止监控wro目录[{}]", wroAbsolutePathStr); } } }
对应的tld文件就不给出了,根据方法签名编写就行了.
其中的cssFile和jsFile方法分别实现引用css和js文件.
在页面使用的时候类似这样:
${platform:cssFile("/wro/basic") }
${platform:jsFile("/wro/custom") }
这个类的主要功能就是使用jdk7的WatchService监控wro目录的新增文件事件,
一旦有新的文件加到目录里,判断这个文件是不是最新的,如果是的话则使用这个文件名称引用.
这样一旦有新加的资源文件放到wro目录里,则能够自动被引用,不需要做任何代码上的修改,并且基本不影响性能.
到此为止功能已经实现.
但是我考虑到还有两个问题有待完善:
1.因为生成的文件名称精确到小时,如果这个小时之内有多次代码修改,生成的文件名都完全一样.
这样就算线上的代码有修改,对于已经有该文本缓存的浏览器来说,不会重新请求文件,也就看不到文件变化.
不过一般来说线上代码不会如此频繁改动,对于大多数应用来说影响不大.
2.在开发环境开发一段时间之后,wro目录下会生成一大堆的文件(因为m2e-wro4j插件在生成新的文件的时候不会删除旧文件,如果文件名相同会覆盖掉以前的文件),
这时候就需要手动删除时间靠前的旧文件,虽然系统会忽略旧文件,但是我相信大多数程序员和我一样是有些许洁癖的吧.
解决办法还是不少,比如可以写脚本定期清理掉旧文件.
时间有限,有些地方考虑的不是很完善,欢迎拍砖.
参考资料:
http://meri-stuff.blogspot.sk/2012/08/wro4j-page-load-optimization-and-lessjs.html#Configuration
https://community.jboss.org/en/tools/blog/2012/01/17/css-and-js-minification-using-eclipse-maven-and-wro4j
http://code.google.com/p/wro4j/wiki/MavenPlugin
http://code.google.com/p/wro4j/wiki/WroFileFormat
http://java.dzone.com/articles/using-java-7s-watchservice
相关推荐
WRO4J 是一个用于优化 Web 资源(如 CSS、JavaScript 文件)的工具,它可以合并、压缩和缓存这些资源,以提高网页加载速度和减少网络请求。 【标签】"开源项目" 表明这两个软件都是遵循开源许可证的,允许用户自由...
介绍这是一个单模块 maven 项目,演示了如何集成以下技术: Spring Boot(基于Spring MVC的项目的单jar部署) Sass Maven 插件(Sass 转 CSS) Wro4J(用于构建时 javascript 组合/缩小) Handlebars.java(服务器端...
Wro4j是一个Web资源优化工具,它可以合并、压缩和最小化JavaScript和CSS文件,以提高网页加载速度。在"icampus-console"项目中,wro4j被用来优化AngularJS的资源,减少HTTP请求的数量,从而提升用户体验。通过...
2. **用户界面**:前端可能使用HTML、CSS和JavaScript,配合React、Angular或Vue.js等现代前端框架,为用户提供交互式的体验。 3. **API设计**:后端可能提供RESTful API供前端调用,处理业务逻辑和数据操作。 4. **...
基于Maxwell设计的经典280W 4025RPM高效率科尔摩根12极39槽TBM无框力矩电机:生产与学习双重应用案例,基于Maxwell设计的经典280W高转速科尔摩根TBM无框力矩电机:7615系列案例解析与应用实践,基于maxwwell设计的经典280W,4025RPM 内转子 科尔摩根 12极39槽 TBM无框力矩电机,7615系列。 该案例可用于生产,或者学习用,(157) ,maxwell设计; 280W; 4025RPM内转子; 科尔摩根; 12极39槽TBM无框力矩电机; 7615系列; 生产/学习用。,基于Maxwell设计,高功率280W 12极39槽TBM无框力矩电机:生产与学习双用途案例
基于碳交易的微网优化模型的Matlab设计与实现策略分析,基于碳交易的微网优化模型的Matlab设计与实现探讨,考虑碳交易的微网优化模型matlab ,考虑碳交易; 微网优化模型; MATLAB;,基于Matlab的碳交易微网优化模型研究
二级2025模拟试题(答案版)
OpenCV是一个功能强大的计算机视觉库,它提供了多种工具和算法来处理图像和视频数据。在C++中,OpenCV可以用于实现基础的人脸识别功能,包括从摄像头、图片和视频中识别人脸,以及通过PCA(主成分分析)提取图像轮廓。以下是对本资源大体的介绍: 1. 从摄像头中识别人脸:通过使用OpenCV的Haar特征分类器,我们可以实时从摄像头捕获的视频流中检测人脸。这个过程涉及到将视频帧转换为灰度图像,然后使用预训练的Haar级联分类器来识别人脸区域。 2. 从视频中识别出所有人脸和人眼:在视频流中,除了检测人脸,我们还可以进一步识别人眼。这通常涉及到使用额外的Haar级联分类器来定位人眼区域,从而实现对人脸特征的更细致分析。 3. 从图片中检测出人脸:对于静态图片,OpenCV同样能够检测人脸。通过加载图片,转换为灰度图,然后应用Haar级联分类器,我们可以在图片中标记出人脸的位置。 4. PCA提取图像轮廓:PCA是一种统计方法,用于分析和解释数据中的模式。在图像处理中,PCA可以用来提取图像的主要轮廓特征,这对于人脸识别技术中的面部特征提取尤
麻雀搜索算法(SSA)自适应t分布改进版:卓越性能与优化代码注释,适合深度学习。,自适应t分布改进麻雀搜索算法(TSSA)——卓越的学习样本,优化效果出众,麻雀搜索算法(SSA)改进——采用自适应t分布改进麻雀位置(TSSA),优化后明显要优于基础SSA(代码基本每一步都有注释,代码质量极高,非常适合学习) ,TSSA(自适应t分布麻雀位置算法);注释详尽;高质量代码;适合学习;算法改进结果优异;TSSA相比基础SSA。,自适应T分布优化麻雀搜索算法:代码详解与学习首选(TSSA改进版)
锂电池主动均衡Simulink仿真研究:多种均衡策略与电路架构的深度探讨,锂电池主动均衡与多种均衡策略的Simulink仿真研究:buckboost拓扑及多层次电路分析,锂电池主动均衡simulink仿真 四节电池 基于buckboost(升降压)拓扑 (还有传统电感均衡+开关电容均衡+双向反激均衡+双层准谐振均衡+环形均衡器+cuk+耦合电感)被动均衡电阻式均衡 、分层架构式均衡以及分层式电路均衡,多层次电路,充放电。 ,核心关键词: 锂电池; 主动均衡; Simulink仿真; 四节电池; BuckBoost拓扑; 传统电感均衡; 开关电容均衡; 双向反激均衡; 双层准谐振均衡; 环形均衡器; CUK均衡; 耦合电感均衡; 被动均衡; 电阻式均衡; 分层架构式均衡; 多层次电路; 充放电。,锂电池均衡策略研究:Simulink仿真下的多拓扑主动与被动均衡技术
S7-1500和分布式外围系统ET200MP模块数据
内置式永磁同步电机无位置传感器模型:基于滑膜观测器和MTPA技术的深度探究,内置式永磁同步电机基于滑膜观测器和MTPA的无位置传感器模型研究,基于滑膜观测器和MTPA的内置式永磁同步电机无位置传感器模型 ,基于滑膜观测器;MTPA;内置式永磁同步电机;无位置传感器模型,基于滑膜观测与MTPA算法的永磁同步电机无位置传感器模型
centos7操作系统下安装docker,及docker常用命令、在docker中运行nginx示例,包括 1.设置yum的仓库 2.安装 Docker Engine-Community 3.docker使用 4.查看docker进程是否启动成功 5.docker常用命令及nginx示例 6.常见问题
给曙光服务器安装windows2012r2时候找不到磁盘,问厂家工程师要的raid卡驱动,内含主流大多数品牌raid卡驱动
数学建模相关主题资源2
西门子四轴卧式加工中心后处理系统:828D至840D支持,四轴联动制造解决方案,图档处理与试看程序一应俱全。,西门子四轴卧加后处理系统:支持828D至840D系统,四轴联动高精度制造解决方案,西门子四轴卧加后处理,支持828D~840D系统,支持四轴联动,可制制,看清楚联系,可提供图档处理试看程序 ,核心关键词:西门子四轴卧加后处理; 828D~840D系统支持; 四轴联动; 制程; 联系; 图档处理试看程序。,西门子四轴卧加后处理程序,支持多种系统与四轴联动
MATLAB下基于列约束生成法CCG的两阶段鲁棒优化问题求解入门指南:算法验证与经典文献参考,MATLAB下基于列约束生成法CCG的两阶段鲁棒优化问题求解入门指南:算法验证与文献参考,MATLAB代码:基于列约束生成法CCG的两阶段问题求解 关键词:两阶段鲁棒 列约束生成法 CCG算法 参考文档:《Solving two-stage robust optimization problems using a column-and-constraint generation method》 仿真平台:MATLAB YALMIP+CPLEX 主要内容:代码构建了两阶段鲁棒优化模型,并用文档中的相对简单的算例,进行CCG算法的验证,此篇文献是CCG算法或者列约束生成算法的入门级文献,其经典程度不言而喻,几乎每个搞CCG的两阶段鲁棒的人都绕不过此篇文献 ,两阶段鲁棒;列约束生成法;CCG算法;MATLAB;YALMIP+CPLEX;入门级文献。,MATLAB代码实现:基于两阶段鲁棒与列约束生成法CCG的算法验证研究
“生热研究的全面解读:探究参数已配置的Comsol模型中的18650圆柱锂电池表现”,探究已配置参数的COMSOL模型下的锂电池生热现象:18650圆柱锂电池模拟分析,出一个18650圆柱锂电池comsol模型 参数已配置,生热研究 ,出模型; 18650圆柱锂电池; comsol模型; 参数配置; 生热研究,构建18650电池的COMSOL热研究模型
移动端多端运行的知识付费管理系统源码,TP6+Layui+MySQL后端支持,功能丰富,涵盖直播、点播、管理全功能及礼物互动,基于UniApp跨平台开发的移动端知识付费管理系统源码:多端互通、全功能齐备、后端采用TP6与PHP及Layui前端,搭载MySQL数据库与直播、点播、管理、礼物等功能的强大整合。,知识付费管理系统源码,移动端uniApp开发,app h5 小程序一套代码多端运行,后端php(tp6)+layui+MySQL,功能齐全,直播,点播,管理,礼物等等功能应有尽有 ,知识付费;管理系统源码;移动端uniApp开发;多端运行;后端php(tp6);layui;MySQL;直播点播;管理功能;礼物功能,知识付费管理平台:全功能多端运行系统源码(PHP+Layui+MySQL)
基于Python+Django+MySQL的个性化图书推荐系统:协同过滤推荐,智能部署,用户定制功能,基于Python+Django+MySQL的个性化图书推荐系统:协同过滤推荐,智能部署,用户定制功能,Python+Django+Mysql个性化图书推荐系统 图书在线推荐系统 基于用户、项目、内容的协同过滤推荐算法。 帮远程安装部署 一、项目简介 1、开发工具和实现技术 Python3.8,Django4,mysql8,navicat数据库管理工具,html页面,javascript脚本,jquery脚本,bootstrap前端框架,layer弹窗组件、webuploader文件上传组件等。 2、项目功能 前台用户包含:注册、登录、注销、浏览图书、搜索图书、信息修改、密码修改、兴趣喜好标签、图书评分、图书收藏、图书评论、热点推荐、个性化推荐图书等功能; 后台管理员包含:用户管理、图书管理、图书类型管理、评分管理、收藏管理、评论管理、兴趣喜好标签管理、权限管理等。 个性化推荐功能: 无论是否登录,在前台首页展示热点推荐(根据图书被收藏数量降序推荐)。 登录用户,在前台首页展示个性化推荐